API Documentation
The aip
top module provides a comprehensive set of functions for interacting with files, paths, text, markdown, JSON, web services, Lua value inspection, agent control flow, command execution, semantic versioning, Handlebars templating, code formatting, Git, Rust code processing, and HTML processing within the AIPACK environment.
Getting Started Video Tutorial
The available submodules are:
aip.file
: File system operations (load, save, list, append, JSON/MD/HTML handling).aip.path
: Path manipulation and checking (split, resolve, exists, diff, parent).aip.text
: Text processing utilities (trim, split, split lines, replace, truncate, escape, ensure).aip.md
: Markdown processing (extract blocks, extract metadata).aip.json
: JSON parsing and stringification.aip.web
: HTTP requests (GET, POST), URL parsing and resolution.aip.uuid
: UUID generation and conversion.aip.hash
: Hashing utilities (SHA256, SHA512, Blake3) with various encodings.aip.lua
: Some lua helpers (for now only.dump(data)
).aip.agent
: Running other AIPACK agents.aip.run
: Run-level pin helper (attach pins to the current run).aip.task
: Task-level pin helper (attach pins to the current task).aip.flow
: Controlling agent execution flow.aip.cmd
: Executing system commands.aip.semver
: Semantic versioning operations.aip.rust
: Rust code specific processing.aip.html
: HTML processing utilities.aip.git
: Basic Git operations.aip.hbs
: Handlebars template rendering.aip.code
: Code commenting utilities.aip.time
: Time and date utilities (now, parse/format, epoch conversions).
File Path supported
AIPACK supports several types of file paths:
Type | Example | Notes |
---|---|---|
Relative | some/file.txt |
Relative to the workspace directory |
Absolute | /absolute/path/file.txt |
Absolute path (C:/ on Windows) |
Pack Ref | my_org@my_pack/path/file.txt |
Finds the closest pack (in custom workspace, custom base, or install base) and uses this as a directory |
Home Tilde | ~/path/to/file.txt |
User home directory; ~ is replaced by the home directory (or / if no home directory is found) |
Session TMP | $tmp/some/file.txt |
Located in .aipack/.sessions/_uid_/ within the workspace; unique per session (until command stops) |
Workspace Pack Support | my_org@my_pack$workspace/some/file.txt |
Maps to .aipack/support/pack/my_org/my_pack/some/file.txt in the workspace |
Base Pack Support | my_org@my_pack$base/some/file.txt |
Maps to .aipack-base/support/pack/my_org/my_pack/some/file.txt in the base directory |
Important notes:
- The workspace directory is the parent directory of the
.aipack/
folder. Like.git
or.vscode
, the.aipack/
folder marks a directory as the workspace. - The pack support directory suffixes
$workspace
and$base
must appear immediately after the pack name. - These paths can be used in globs (e.g.,
aip.file.list({"~/path/to/**/*.md", "pro@rust10x/guide/**/*.md"})
).
Common Data Types:
FileInfo
(foraip.file..
) (FileInfo +.content
)FileRecord
(foraip.file..
)FileStats
(foraip.file..
)WebResponse
(foraip.web..
)MdSection
(foraip.md..
)MdBlock
(foraip.md..
)CmdResponse
(foraip.cmd..
)DestOptions
(foraip.file.save_...to_...(src_path, dest))
AI Response
An ai_response
variable will be injected into the scope in the # Output
Lua code block if an instruction was given and an AI request occurred (otherwise, it will be nil
).
{
// The final text response from the AI, if available.
content?: string,
// A formatted string capturing essential details like usage, price, model, and duration of the request, using the fields below.
info: string,
// e.g., `gpt-4.1-mini`
model_name: string,
// e.g., `openai`
adapter_kind: AdapterKind,
// Token usage details.
usage: {
prompt_tokens: number,
completion_tokens: number
},
// The approximate price in USD, if available.
price_usd?: number,
// Duration in seconds (with millisecond precision).
duration_sec: number,
// Reasoning content, if available (e.g., from deepseek or some groq models).
reasoning_content?: string,
}
Global and Injected Variables:
- All stage Lua code blocks and required scripts receive a
CTX
variable containing context information (e.g.,CTX.AGENT_NAME
,CTX.TMP_DIR
, etc.). - All stage Lua code blocks also receive
options
, which includes.model
and.input_concurrency
. # Before All
stage Lua code blocks receiveinputs
(can benil
if no inputs are given).# Data
stage Lua code blocks receiveinput
(can benil
if no input is provided) and the return value from the# Before All
stage (before_all
, which can benil
).# Output
stage Lua code blocks receiveinput
,ai_response
(can benil
),data
(the return value from the# Data
stage), andbefore_all
.# After All
stage Lua code blocks receiveoutputs
(return values from each# Output
stage),inputs
, andbefore_all
.
NOTE
All of the type documentation is noted in "TypeScript style" as it is a common and concise type notation for scripting languages and works well to express Lua types. However, it is important to note that there is no TypeScript support, just standard Lua. For example, Lua properties are delimited with
=
and not:', and arrays and dictionaries are denoted with
{ }`.
aip.file
File manipulation functions for loading, saving, listing, and managing files and their content, including specialized functions for JSON and Markdown.
Functions Summary
aip.file.load(rel_path: string, options?: {base_dir: string}): FileRecord
aip.file.save(rel_path: string, content: string)
aip.file.append(rel_path: string, content: string)
aip.file.delete(path: string): boolean
aip.file.ensure_exists(path: string, content?: string, options?: {content_when_empty?: boolean}): FileInfo
aip.file.exists(path: string): boolean
aip.file.list(include_globs: string | list<string>, options?: {base_dir?: string, absolute?: boolean, with_meta?: boolean}): list<FileInfo>
aip.file.list_load(include_globs: string | list<string>, options?: {base_dir?: string, absolute?: boolean}): list<FileRecord>
aip.file.first(include_globs: string | list<string>, options?: {base_dir?: string, absolute?: boolean}): FileInfo | nil
aip.file.info(path: string): FileInfo | nil
aip.file.load_json(path: string): table | value
aip.file.load_ndjson(path: string): list<table>
aip.file.append_json_line(path: string, data: value): FileInfo
aip.file.append_json_lines(path: string, data: list): FileInfo
aip.file.save_changes(path: string, changes: string): FileInfo
aip.file.load_md_sections(path: string, headings?: string | list<string>): list<MdSection>
aip.file.load_md_split_first(path: string): {before: string, first: MdSection, after: string}
aip.file.save_html_to_md(html_path: string, dest?: string | table): FileInfo
aip.file.save_html_to_slim(html_path: string, dest?: string | table): FileInfo
aip.file.load_html_as_slim(html_path: string): string
aip.file.load_html_as_md(html_path: string, options?: table): string
aip.file.save_docx_to_md(docx_path: string, dest?: string | table): FileInfo
aip.file.load_docx_as_md(docx_path: string): string
aip.file.hash_sha256(path: string): string
aip.file.hash_sha256_b64(path: string): string
aip.file.hash_sha256_b64u(path: string): string
aip.file.hash_sha256_b58u(path: string): string
aip.file.hash_sha512(path: string): string
aip.file.hash_sha512_b64(path: string): string
aip.file.hash_sha512_b64u(path: string): string
aip.file.hash_sha512_b58u(path: string): string
aip.file.hash_blake3(path: string): string
aip.file.hash_blake3_b64(path: string): string
aip.file.hash_blake3_b64u(path: string): string
aip.file.hash_blake3_b58u(path: string): string
Note: All relative paths are relative to the workspace directory (parent of
.aipack/
). Unless abase_dir
option is specified. Pack references (e.g.,ns@pack/
) can be used in paths andbase_dir
.
aip.file.load
Load a FileRecord object with its content.
-- API Signature
aip.file.load(rel_path: string, options?: {base_dir: string}): FileRecord
Loads the file specified by rel_path
and returns a FileRecord object containing the file's metadata and its content.
Arguments
rel_path: string
: The path to the file, relative to thebase_dir
or workspace root.options?: table
: An optional table containing:base_dir: string
(optional): The base directory from whichrel_path
is resolved. Defaults to the workspace root. Pack references (e.g.,ns@pack/
) can be used.
Returns
FileRecord
: A FileRecord table representing the file.
Example
local readme = aip.file.load("doc/README.md")
print(readme.path) -- Output: "doc/README.md" (relative path used)
print(#readme.content) -- Output: <length of content>
local agent_file = aip.file.load("agent.aip", { base_dir = "ns@pack/" })
print(agent_file.path) -- Output: "agent.aip" (relative to the resolved base_dir)
Error
Returns an error (Lua table { error: string }
) if the file cannot be found, read, or metadata retrieved, or if base_dir
is invalid.
aip.file.save
Save string content to a file at the specified path.
-- API Signature
aip.file.save(rel_path: string, content: string)
Writes the content
string to the file specified by rel_path
. Overwrites existing files. Creates directories as needed. Restricts saving outside the workspace or shared base directory for security.
Arguments
rel_path: string
: The path relative to the workspace root.content: string
: The string content to write.
Returns
- FileInfo: Metadata (FileInfo) about the saved file.
Example
aip.file.save("docs/new_feature.md", "# New Feature\n\nDetails.")
Error
Returns an error (Lua table { error: string }
) on write failure, permission issues, path restrictions, or if no workspace context.
aip.file.append
Append string content to a file at the specified path.
-- API Signature
aip.file.append(rel_path: string, content: string)
Appends content
to the end of the file at rel_path
. Creates the file and directories if they don't exist.
Arguments
rel_path: string
: The path relative to the workspace root.content: string
: The string content to append.
Returns
FileInfo
: Metadata (FileInfo) about the file.
Example
aip.file.append("logs/app.log", "INFO: User logged in.\n")
Error
Returns an error (Lua table { error: string }
) on write failure, permission issues, or I/O errors.
aip.file.delete
Deletes a file at the specified path.
-- API Signature
aip.file.delete(path: string): boolean
Attempts to delete the file specified by path
. The path is resolved relative to the workspace root.
Security:
-
Deleting files is only allowed within the current workspace directory.
-
Deleting files under the shared base directory (
~/.aipack-base/
) is not allowed.
Arguments
path: string
The path to the file to delete, relative to the workspace root.
Returns
boolean
true
if a file was deleted,false
if the file did not exist.
Example
local removed = aip.file.delete("logs/app.log")
if removed then
print("Removed logs/app.log")
else
print("No file to remove")
end
Error
Returns an error (Lua table { error: string }
) if:
-
The path attempts to delete outside the allowed workspace directory.
-
The target is in the
.aipack-base
folder (always forbidden). -
The file cannot be deleted due to permissions or other I/O errors.
-
The operation requires a workspace context, but none is found.
aip.file.ensure_exists
Ensure a file exists at the given path, optionally creating it or adding content if empty.
-- API Signature
aip.file.ensure_exists(path: string, content?: string, options?: {content_when_empty?: boolean}): FileInfo
Checks if the file exists. If not, creates it with content
. If it exists and options.content_when_empty
is true and the file is empty (or whitespace only), writes content
. Intended for files, not directories.
Arguments
path: string
: The path relative to the workspace root.content?: string
(optional): Content to write. Defaults to empty string.options?: table
(optional):content_when_empty?: boolean
(optional): If true, thecontent
will be written to the file if the file is empty (or only contains whitespace). Defaults tofalse
.
Returns
FileInfo
: Metadata (FileInfo) about the file.
Example
-- Create config if needed, with default content
local default_config = "-- Default Settings --\nenabled=true"
local meta = aip.file.ensure_exists("config/settings.lua", default_config)
print("Ensured file:", meta.path)
-- Ensure log file exists, don't overwrite
aip.file.ensure_exists("logs/activity.log")
-- Add placeholder only if file is currently empty
aip.file.ensure_exists("src/module.lua", "-- TODO", {content_when_empty = true})
Error
Returns an error (Lua table { error: string }
) on creation/write failure, permission issues, or metadata retrieval failure.
aip.file.exists
Checks if the specified path exists (file or directory).
-- API Signature
aip.file.exists(path: string): boolean
Checks if the file or directory specified by path
exists. The path is resolved relative to the workspace root.
Supports relative paths, absolute paths, and pack references (ns@pack/...
).
Arguments
path: string
: The path string to check for existence. Can be relative, absolute, or a pack reference.
Returns
boolean
: Returnstrue
if a file or directory exists at the specified path,false
otherwise.
Example
if aip.file.exists("README.md") then
print("README.md exists.")
end
if aip.file.exists("ns@pack/main.aip") then
print("Pack main agent exists.")
end
Error
Returns an error (Lua table { error: string }
) if the path string cannot be resolved (e.g., invalid pack reference, invalid path format).
{
error: string // Error message
}
aip.file.list
List file metadata (FileInfo) matching glob patterns.
-- API Signature
aip.file.list(
include_globs: string | list<string>,
options?: {
base_dir?: string,
absolute?: boolean,
with_meta?: boolean
}
): list<FileInfo>
Finds files matching include_globs
within base_dir
(or workspace) and returns a list of FileInfo objects (metadata only, no content).
Arguments
include_globs: string | list<string>
: Glob pattern(s). Pack references supported.options?: table
(optional):base_dir?: string
(optional): Base directory for globs. Defaults to workspace. Pack refs supported.absolute?: boolean
(optional): Iftrue
, thepath
in the returned FileInfo objects will be absolute. Iffalse
(default), thepath
will be relative to thebase_dir
. If a path resolves outside thebase_dir
(e.g., using../
in globs), it will be returned as an absolute path even ifabsolute
is false.with_meta?: boolean
(optional): Iffalse
, the function will skip fetching detailed metadata (ctime
,mtime
,size
) for each file, potentially improving performance if only the path information is needed. Defaults totrue
.ctime
is creation time,mtime
is last modification time (from the file system), both in epoch micro
Returns
list<FileInfo>
: A Lua list of FileInfo tables. Empty if no matches.
Example
-- List all Markdown files in the 'docs' directory (relative paths)
local doc_files = aip.file.list("*.md", { base_dir = "docs" })
for _, file in ipairs(doc_files) do
print(file.path) -- e.g., "guide.md", "api.md"
end
-- List all '.aip' files in a specific pack (absolute paths, no detailed meta)
local agent_files = aip.file.list("**/*.aip", {
base_dir = "ns@pack/",
absolute = true,
with_meta = false
})
for _, file in ipairs(agent_files) do
print(file.path) -- e.g., "/path/to/workspace/.aipack/ns/pack/agent1.aip"
end
-- List text and config files from the workspace root
local config_files = aip.file.list({"*.txt", "*.config"})
for _, file in ipairs(config_files) do
print(file.path, file.size) -- e.g., "notes.txt", 1024
end
Error
Returns an error (Lua table { error: string }
) on invalid arguments, resolution failure, glob matching error, or metadata retrieval error (if with_meta=true
).
aip.file.list_load
List and load files (FileRecord) matching glob patterns.
-- API Signature
aip.file.list_load(
include_globs: string | list<string>,
options?: {
base_dir?: string,
absolute?: boolean
}
): list<FileRecord>
Finds files matching include_globs
patterns within the specified base_dir
(or workspace root),
loads the content of each matching file, and returns a list of FileRecord objects.
Each FileRecord contains both metadata and the file content.
Arguments
include_globs: string | list<string>
- A single glob pattern string or a Lua list (table) of glob pattern strings. Globs can include standard wildcards (*
,?
,**
,[]
). Pack references (e.g.,ns@pack/**/*.md
) are supported.options?: table
(optional) - A table containing options:base_dir?: string
(optional): The directory relative to which theinclude_globs
are applied. Defaults to the workspace root. Pack references (e.g.,ns@pack/
) are supported.absolute?: boolean
(optional): Iftrue
, the paths used internally and potentially thepath
in the returned FileRecord objects will be absolute. Iffalse
(default), paths will generally be relative to thebase_dir
. Note: The exact path stored in FileRecord.path depends on internal resolution logic, especially if paths resolve outsidebase_dir
.
Returns
list<FileRecord>
: A Lua list of FileRecord tables. Empty if no files match the globs.
Example
-- Load all Markdown files in the 'docs' directory
local doc_files = aip.file.list_load("*.md", { base_dir = "docs" })
for _, file in ipairs(doc_files) do
print("--- File:", file.path, "---")
print(file.content)
end
-- Load all '.aip' files in a specific pack
local agent_files = aip.file.list_load("**/*.aip", { base_dir = "ns@pack/" })
for _, file in ipairs(agent_files) do
print("Agent Name:", file.stem)
end
Error
Returns an error (Lua table { error: string }
) on invalid arguments, resolution failure, glob matching error, or file read/metadata error.
aip.file.first
Find the first file matching glob patterns and return its metadata (FileInfo).
-- API Signature
aip.file.first(
include_globs: string | list<string>,
options?: {
base_dir?: string,
absolute?: boolean
}
): FileInfo | nil
Searches for files matching the include_globs
patterns within the specified base_dir
(or workspace root).
It stops searching as soon as the first matching file is found and returns its FileInfo object (metadata only, no content).
If no matching file is found, it returns nil
.
Arguments
include_globs: string | list<string>
- A single glob pattern string or a Lua list (table) of glob pattern strings. Globs can include standard wildcards (*
,?
,**
,[]
). Pack references (e.g.,ns@pack/**/*.md
) are supported.options?: table
(optional) - A table containing options:base_dir?: string
(optional): The directory relative to which theinclude_globs
are applied. Defaults to the workspace root. Pack references (e.g.,ns@pack/
) are supported.absolute?: boolean
(optional): Iftrue
, thepath
in the returned FileInfo object (if found) will be absolute. Iffalse
(default), thepath
will be relative to thebase_dir
. Similar toaip.file.list
, paths outsidebase_dir
become absolute.
Returns
FileInfo | nil
: If a matching file is found, returns a FileInfo table. If no matching file is found, returnsnil
.
Example
-- Find the first '.aip' file in a pack
local agent_meta = aip.file.first("*.aip", { base_dir = "ns@pack/" })
if agent_meta then
print("Found agent:", agent_meta.path)
-- To load its content:
-- local agent_file = aip.file.load(agent_meta.path, { base_dir = "ns@pack/" })
-- print(agent_file.content)
else
print("No agent file found in pack.")
end
-- Find any config file in the root
local config_meta = aip.file.first({"*.toml", "*.yaml", "*.json"}, { base_dir = "." })
if config_meta then
print("Config file:", config_meta.name)
end
Error
Returns an error (Lua table { error: string }
) on invalid arguments, resolution failure, error during search before first match, or metadata retrieval error for the first match.
aip.file.info
Retrieves file metadata (FileInfo
) for the specified path.
-- API Signature
aip.file.info(path: string): FileInfo | nil
If the given path
exists, this function returns a FileInfo
object
containing the file metadata (no content).
If the path cannot be resolved or the file does not exist, it returns nil
.
Arguments
path: string
– The file or directory path. Can be relative, absolute, or use pack references (ns@pack/...
,ns@pack$workspace/...
, etc.).
Returns
FileInfo | nil
: Metadata for the file, ornil
when not found.
Example
local meta = aip.file.info("README.md")
if meta then
print("Size:", meta.size)
end
Error
Returns an error only if the path cannot be resolved (invalid pack
reference, invalid format, …). If the path resolves successfully but the
file does not exist, the function simply returns nil
.
aip.file.stats
Calculates aggregate statistics for a set of files matching glob patterns.
-- API Signature
aip.file.stats(
include_globs: string | list<string> | nil,
options?: {
base_dir?: string,
absolute?: boolean
}
): FileStats | nil
Finds files matching the include_globs
patterns within the specified base_dir
(or workspace root)
and returns aggregate statistics about these files in a FileStats
object.
If include_globs
is nil
or no files match the patterns, returns nil
.
Arguments
include_globs: string | list<string> | nil
- A single glob pattern string, a Lua list (table) of glob pattern strings, ornil
. Ifnil
, the function returnsnil
. Globs can include standard wildcards (*
,?
,**
,[]
). Pack references (e.g.,ns@pack/**/*.md
) are supported.options?: table
(optional) - A table containing options:base_dir?: string
(optional): The directory relative to which theinclude_globs
are applied. Defaults to the workspace root. Pack references (e.g.,ns@pack/
) are supported.absolute?: boolean
(optional): Affects how files are resolved internally, but the statistics remain the same regardless.
Returns
FileStats
: AFileStats
object containing aggregate statistics about the matching files.nil
ifinclude_globs
isnil
If no files if ound a FileStats will all 0 will be returned.
Example
-- Get statistics for all Markdown files in the 'docs' directory
local stats = aip.file.stats("*.md", { base_dir = "docs" })
if stats then
print("Number of files:", stats.number_of_files)
print("Total size:", stats.total_size)
print("First created:", stats.ctime_first)
print("Last modified:", stats.mtime_last)
end
-- Get statistics for all '.aip' files in a specific pack
local agent_stats = aip.file.stats("**/*.aip", { base_dir = "ns@pack/" })
if agent_stats then
print("Total agent files:", agent_stats.number_of_files)
end
-- Nil globs return nil
local nil_stats = aip.file.stats(nil)
print(nil_stats) -- Output: nil
Error
Returns an error if:
include_globs
is not a string, a list of strings, ornil
.base_dir
cannot be resolved (e.g., invalid pack reference).- An error occurs during file system traversal or glob matching.
aip.file.load_json
Load a file, parse its content as JSON, and return the corresponding Lua value.
-- API Signature
aip.file.load_json(path: string): table | value
Loads the file at path
(relative to workspace), parses it as JSON, and converts it to a Lua value.
Arguments
path: string
: Path to the JSON file, relative to workspace root.
Returns
table | value
: Lua value representing the parsed JSON.
Example
-- Assuming 'config.json' contains {"port": 8080, "enabled": true}
local config = aip.file.load_json("config.json")
print(config.port) -- Output: 8080
Error
Returns an error (Lua table { error: string }
) if file not found/read, content is invalid JSON, or conversion fails.
aip.file.load_ndjson
Load a file containing newline-delimited JSON (NDJSON), parse each line, and return a Lua list (table) of the results.
-- API Signature
aip.file.load_ndjson(path: string): list<table>
Loads the file at path
(relative to workspace), parses each non-empty line as JSON, and returns a Lua list of the parsed values. Empty lines are skipped.
Arguments
path: string
: Path to the NDJSON file, relative to workspace root.
Returns
list<table>
: Lua list containing parsed values from each line.
Example
-- Assuming 'logs.ndjson' contains:
-- {"level": "info", "msg": "Started"}
-- {"level": "warn", "msg": "Low space"}
local logs = aip.file.load_ndjson("logs.ndjson")
print(#logs) -- Output: 2
print(logs[1].msg) -- Output: Started
Error
Returns an error (Lua table { error: string }
) if file not found/read, any line has invalid JSON, or conversion fails.
aip.file.append_json_line
Convert a Lua value to a JSON string and append it as a new line to a file.
-- API Signature
aip.file.append_json_line(path: string, data: value)
Converts data
to JSON and appends it, followed by a newline (\n
), to the file at path
(relative to workspace). Creates file/directories if needed.
Arguments
path: string
: Path to the target file, relative to workspace root.data: value
: Lua data (table, string, number, boolean, nil) to append.
Returns
FileInfo
: Metadata (FileInfo) about the file.
Example
aip.file.append_json_line("output.ndjson", {user = "test", score = 100})
-- Appends '{"score":100,"user":"test"}\n' to output.ndjson
Error
Returns an error (Lua table { error: string }
) on conversion/serialization failure, directory creation failure, or file write/permission error.
aip.file.append_json_lines
Convert a Lua list (table) of values to JSON strings and append them as new lines to a file.
-- API Signature
aip.file.append_json_lines(path: string, data: list)
Iterates through the data
list, converts each element to JSON, and appends it followed by a newline (\n
) to the file at path
(relative to workspace). Creates file/directories if needed. Uses buffering.
Arguments
path: string
: Path to the target file, relative to workspace root.data: list
: Lua list (table with sequential integer keys from 1) of values to append.
Returns
Does not return anything upon success.
Example
local users = { {user = "alice"}, {user = "bob"} }
aip.file.append_json_lines("users.ndjson", users)
-- Appends '{"user":"alice"}\n{"user":"bob"}\n'
Error
Returns an error (Lua table { error: string }
) if data
is not a list, conversion/serialization fails for any element, directory creation fails, or file write/permission error.
aip.file.load_md_sections
Load markdown sections from a file, optionally filtering by specific heading names.
-- API Signature
aip.file.load_md_sections(
path: string,
headings?: string | list<string>
): list<MdSection>
Reads the markdown file at path
(relative to workspace) and splits it into sections based on headings (#
). Returns a list of MdSection objects. Optionally filters by exact heading name
(case-sensitive, excluding #
).
Arguments
path: string
: Path to the markdown file, relative to workspace root.headings?: string | list<string>
(optional): Heading name(s) to filter by.
Returns
list<MdSection>
: A Lua list of MdSection tables. Includes content before the first heading if no filter applied. Empty if file empty or no matching sections.
Example
-- Load all sections
local all_sections = aip.file.load_md_sections("doc/readme.md")
-- Load only the "Summary" section
local summary_section = aip.file.load_md_sections("doc/readme.md", "Summary")
-- Load "Summary" and "Conclusion" sections
local sections = aip.file.load_md_sections("doc/readme.md", {"Summary", "Conclusion"})
Error
Returns an error (Lua table { error: string }
) if file not found/read, headings
invalid, or parsing/conversion error.
aip.file.load_md_split_first
Splits a markdown file into three parts based on the first heading encountered.
-- API Signature
aip.file.load_md_split_first(path: string): {before: string, first: MdSection, after: string}
Reads the file at path
(relative to workspace) and divides it into: content before the first heading (before
), the first heading section (first
), and content from the second heading onwards (after
).
Arguments
path: string
: Path to the markdown file, relative to workspace root.
Returns
table
: A table containing the three parts:{ before: string, // Content before first heading. first: MdSection, // The first [MdSection](#mdsection) (default if no headings). after: string // Content from second heading onwards. }
Example
local split = aip.file.load_md_split_first("doc/structure.md")
print("--- BEFORE ---")
print(split.before)
print("--- FIRST Heading Name ---")
print(split.first.heading.name)
print("--- AFTER ---")
print(split.after)
Error
Returns an error (Lua table { error: string }
) if file not found/read, or parsing/conversion error.
aip.file.save_html_to_md
Loads an HTML file, converts its content to Markdown, and saves it.
-- API Signature
aip.file.save_html_to_md(
html_path: string,
dest?: string | table
): FileInfo
Loads the HTML file at html_path
(relative to workspace), converts its content to Markdown, and saves the result. The destination can be specified as a string path or a table of options (DestOptions).
Arguments
-
html_path: string
Path to the source HTML file, relative to the workspace root. -
dest?: string | table (optional)
Destination path or options table:string
Path to save the.md
file (relative or absolute).table
(DestOptions):base_dir?: string
: Base directory for resolving the destination.file_name?: string
: Custom file name for the Markdown output.suffix?: string
: Suffix appended to the source file stem before.md
.
Returns
FileInfo
Metadata (FileInfo) about the created Markdown file.
Example
-- Default (replaces .html with .md):
aip.file.save_html_to_md("docs/page.html")
-- Result: docs/page.md
-- Using a custom string path:
aip.file.save_html_to_md("docs/page.html", "out/custom.md")
-- Using options table:
aip.file.save_html_to_md("docs/page.html", {
base_dir = "output",
suffix = "_v2",
})
-- Assuming source was 'docs/page.html', result might be 'output/page_v2.md'
Error
Returns an error (Lua table { error: string }
) if file I/O, parsing, conversion, or destination resolution fails.
aip.file.save_html_to_slim
Loads an HTML file, "slims" its content (removes scripts, styles, comments, etc.), and saves the slimmed HTML.
-- API Signature
aip.file.save_html_to_slim(
html_path: string,
dest?: string | table
): FileInfo
Loads the HTML file at html_path
(relative to workspace), removes non-content elements, and saves the cleaned HTML. The destination can be specified as a string path or a table of options (DestOptions).
Arguments
-
html_path: string
Path to the source HTML file, relative to the workspace root. -
dest?: string | table (optional)
Destination path or options table (DestOptions) for the output.html
file:nil
: Saves as[original_name]-slim.html
in the same directory.string
: Path to save the slimmed.html
file (relative or absolute).table
(DestOptions):base_dir?: string
: Base directory for resolving the destination. If provided withoutfile_name
orsuffix
, the output will be[original_name].html
in this directory.file_name?: string
: Custom file name for the slimmed HTML output.suffix?: string
: Suffix appended to the source file stem (e.g.,_slimmed
).slim?: boolean
: If true (default), slims HTML before saving; if false, saves the original HTML content without slimming.
Returns
FileInfo
Metadata (FileInfo) about the created slimmed HTML file.
Example
-- Default (saves as original-slim.html):
aip.file.save_html_to_slim("web/page.html")
-- Result: web/page-slim.html
-- Using a custom string path:
aip.file.save_html_to_slim("web/page.html", "output/slim_page.html")
-- Using options table (base_dir, uses original name):
aip.file.save_html_to_slim("web/page.html", { base_dir = "slim_output" })
-- Assuming source was 'web/page.html', result might be 'slim_output/page.html'
-- Using options table (suffix):
aip.file.save_html_to_slim("web/page.html", { suffix = "_light" })
-- Assuming source was 'web/page.html', result might be 'web/page_light.html'
-- Using options table (no slimming):
aip.file.save_html_to_slim("web/page.html", { slim = false })
-- Result: web/page.html (original content saved)
Error
Returns an error (Lua table { error: string }
) if file I/O, slimming, or destination resolution fails.
aip.file.load_html_as_slim
Loads an HTML file, "slims" its content (removes scripts, styles, comments, etc.), and returns the slimmed HTML string.
-- API Signature
aip.file.load_html_as_slim(html_path: string): string
Arguments
html_path: string
Path to the source HTML file, relative to the workspace root.
Returns
string
The slimmed HTML content.
Example
local slim = aip.file.load_html_as_slim("web/page.html")
-- For example, ensure scripts are removed:
print(string.find(slim, "<script") == nil)
Error
Returns an error (Lua table { error: string }
) if the HTML file cannot be found/read or if slimming fails.
aip.file.load_html_as_md
Loads an HTML file, optionally "trims" (slims) its content, converts it to Markdown, and returns the Markdown string.
-- API Signature
aip.file.load_html_as_md(
html_path: string,
options?: { trim?: boolean } -- default true. When true, slim HTML before converting to Markdown.
): string
Arguments
-
html_path: string
Path to the source HTML file, relative to the workspace root. -
options?: table
trim?: boolean
(default: true) Whentrue
, trims/slims the HTML (removes scripts, styles, comments, etc.) before conversion. Note: For compatibility,slim
can also be used instead oftrim
.
Returns
string
The Markdown content converted from the (optionally slimmed) HTML.
Example
-- Default (slims first, then converts)
local md1 = aip.file.load_html_as_md("docs/page.html")
-- No slimming before conversion
local md2 = aip.file.load_html_as_md("docs/page.html", { trim = false })
Error
Returns an error (Lua table { error: string }
) if the HTML file cannot be found/read, if slimming fails (when enabled), or if the conversion to Markdown fails.
aip.file.save_docx_to_md
Loads a DOCX file, converts its content to Markdown, and saves it.
-- API Signature
aip.file.save_docx_to_md(
docx_path: string,
dest?: string | table
): FileInfo
Arguments
-
docx_path: string
Path to the source DOCX file, relative to the workspace root. -
dest?: string | table (optional)
Destination path or options table (DestOptions):string
Path to save the.md
file (relative or absolute).table
(DestOptions):base_dir?: string
: Base directory for resolving the destination.file_name?: string
: Custom file name for the Markdown output.suffix?: string
: Suffix appended to the source file stem before.md
.
Returns
FileInfo
Metadata (FileInfo) about the created Markdown file.
Example
-- Default (replaces .docx with .md):
aip.file.save_docx_to_md("docs/spec.docx")
-- Result: docs/spec.md
-- Using a custom string path:
aip.file.save_docx_to_md("docs/spec.docx", "out/spec.md")
-- Using options table:
aip.file.save_docx_to_md("docs/spec.docx", {
base_dir = "output",
suffix = "_v2",
})
-- Assuming source was 'docs/spec.docx', result might be 'output/spec_v2.md'
Error
Returns an error (Lua table { error: string }
) if file I/O, parsing/conversion, or destination resolution fails.
aip.file.load_docx_as_md
Loads a DOCX file, converts its content to Markdown, and returns a Markdown string.
-- API Signature
aip.file.load_docx_as_md(docx_path: string): string
Arguments
docx_path: string
Path to the source DOCX file, relative to the workspace root.
Returns
string
The Markdown content converted from the DOCX file.
Example
local md = aip.file.load_docx_as_md("docs/spec.docx")
print(string.sub(md, 1, 80)) -- prints the first 80 characters of the converted Markdown
Error
Returns an error (Lua table { error: string }
) if the DOCX file cannot be found/read or if the conversion to Markdown fails.
aip.path
Functions for path manipulation, checking, and resolution within the AIPACK workspace.
Functions Summary
aip.path.split(path: string): (parent: string, filename: string)
aip.path.resolve(path: string): string
aip.path.exists(path: string): boolean
aip.path.is_file(path: string): boolean
aip.path.is_dir(path: string): boolean
aip.path.diff(file_path: string, base_path: string): string
aip.path.parent(path: string): string | nil
aip.path.matches_glob(path: string | nil, globs: string | list<string>): boolean | nil
aip.path.join(base: string, ...parts: string | string[]): string
aip.path.parse(path: string | nil): table | nil
Note: Paths are typically relative to the workspace directory unless otherwise specified or resolved using pack references.
aip.path.parse
Parses a path string and returns a FileInfo table representation of its components.
-- API Signature
aip.path.parse(path: string | nil): table | nil
Parses the given path string into a structured table containing components like dir
, name
, stem
, ext
, etc., without checking file existence or metadata.
Arguments
path: string | nil
: The path string to parse. Ifnil
, the function returnsnil
.
Returns
table | nil
: A FileInfo table representing the parsed path components ifpath
is a string. Returnsnil
if the inputpath
wasnil
. Note thatctime
,mtime
, andsize
fields will benil
as this function only parses the string, it does not access the filesystem.
Example
local parsed = aip.path.parse("some/folder/file.txt")
-- parsed will be similar to { path = "some/folder/file.txt", dir = "some/folder", name = "file.txt", stem = "file", ext = "txt", ctime = nil, ... }
print(parsed.name) -- Output: "file.txt"
local nil_result = aip.path.parse(nil)
-- nil_result will be nil
Error
Returns an error (Lua table { error: string }
) if the path string is provided but is invalid and cannot be parsed into a valid SPath object.
{
error: string // Error message
}
aip.path.split
Split path into parent directory and filename.
-- API Signature
aip.path.split(path: string): (parent: string, filename: string)
Splits the given path into its parent directory and filename components.
Arguments
path: string
: The path to split.
Returns
parent: string
: The parent directory path (empty string if no parent).filename: string
: The filename component (empty string if no filename).
Example
local parent, filename = aip.path.split("folder/file.txt")
print(parent) -- Output: "folder"
print(filename) -- Output: "file.txt"
local parent, filename = aip.path.split("justafile.md")
print(parent) -- Output: ""
print(filename) -- Output: "justafile.md"
Error
Does not typically error.
aip.path.join
Joins a base path with one or more path segments.
-- API Signature
aip.path.join(base: string, ...parts: string | string[]): string
Constructs a new path by appending processed segments from ...parts
to the base
path.
Each argument in ...parts
is first converted to a string:
- String arguments are used as-is.
- List (table) arguments have their string items joined by
/
. These resulting strings are then concatenated together. Finally, this single concatenated string is joined withbase
using system-appropriate path logic (which also normalizes separators like//
to/
).
Arguments
base: string
: The initial base path....parts: string | string[]
(variadic): One or more path segments to process and append. Each part can be a single string or a Lua list (table) of strings.
Returns
string
: A new string representing the combined and normalized path.
Example
-- Example 1: Basic join
print(aip.path.join("dir1/", "file1.txt")) -- Output: "dir1/file1.txt"
print(aip.path.join("dir1", "file1.txt")) -- Output: "dir1/file1.txt"
-- Example 2: Joining with a list (table)
print(aip.path.join("dir1/", {"subdir", "file2.txt"})) -- Output: "dir1/subdir/file2.txt"
-- Example 3: Multiple string arguments
-- Segments are concatenated, then joined to base.
print(aip.path.join("dir1/", "subdir/", "file3.txt")) -- Output: "dir1/subdir/file3.txt"
print(aip.path.join("dir1/", "subdir", "file3.txt")) -- Output: "dir1/subdirfile3.txt"
-- Example 4: Mixed arguments (strings and lists)
-- Lists are pre-joined with '/', then all resulting strings are concatenated, then joined to base.
print(aip.path.join("root/", {"user", "docs"}, "projectA", {"report", "final.pdf"}))
-- Output: "root/user/docsprojectAreport/final.pdf"
-- Example 5: Normalization
print(aip.path.join("", {"my-dir//", "///file.txt"})) -- Output: "my-dir/file.txt"
print(aip.path.join("a", "b", "c")) -- Output: "a/bc"
print(aip.path.join("a/", "b/", "c/")) -- Output: "a/b/c/"
Error
Returns an error (Lua table { error: string }
) if any of the parts
arguments cannot be converted to a string or a list of strings (e.g., passing a boolean or a function).
aip.path.resolve
Resolves and normalizes a path relative to the workspace or pack structure.
-- API Signature
aip.path.resolve(path: string): string
Resolves relative paths (.
, ..
), absolute paths, and pack references (ns@pack/
, ns@pack$base/
, ns@pack$workspace/
) to a normalized, typically absolute, path.
Arguments
path: string
: The path string to resolve.
Returns
string
: The resolved and normalized path.
Example
local resolved_path = aip.path.resolve("./agent-script/../agent.aip")
-- Output: /path/to/workspace/agent.aip (example)
local resolved_pack_path = aip.path.resolve("ns@pack/some/file.txt")
-- Output: /path/to/aipack-base/packs/ns/pack/some/file.txt (example)
Error
Returns an error (Lua table { error: string }
) if the path cannot be resolved (e.g., invalid pack reference, invalid format).
aip.path.exists
Checks if the specified path exists (file or directory).
-- API Signature
aip.path.exists(path: string): boolean
Checks existence after resolving the path relative to the workspace or pack structure.
Arguments
path: string
: The path string to check.
Returns
boolean
:true
if exists,false
otherwise.
Example
if aip.path.exists("README.md") then print("Exists") end
if aip.path.exists("ns@pack/main.aip") then print("Pack agent exists") end
Error
Returns an error (Lua table { error: string }
) if the path cannot be resolved.
aip.path.is_file
Checks if the specified path points to an existing file.
-- API Signature
aip.path.is_file(path: string): boolean
Checks after resolving the path relative to the workspace or pack structure.
Arguments
path: string
: The path string to check.
Returns
boolean
:true
if it's an existing file,false
otherwise.
Example
if aip.path.is_file("config.toml") then print("Is a file") end
Error
Returns an error (Lua table { error: string }
) if the path cannot be resolved.
aip.path.is_dir
Checks if the specified path points to an existing directory.
-- API Signature
aip.path.is_dir(path: string): boolean
Checks after resolving the path relative to the workspace or pack structure.
Arguments
path: string
: The path string to check.
Returns
boolean
:true
if it's an existing directory,false
otherwise.
Example
if aip.path.is_dir("src/") then print("Is a directory") end
Error
Returns an error (Lua table { error: string }
) if the path cannot be resolved.
aip.path.diff
Computes the relative path from base_path
to file_path
.
-- API Signature
aip.path.diff(file_path: string, base_path: string): string
Calculates the relative path string that navigates from base_path
to file_path
.
Arguments
file_path: string
: The target path.base_path: string
: The starting path.
Returns
string
: The relative path. Empty if paths are the same or cannot be computed (e.g., different drives).
Example
print(aip.path.diff("/a/b/c/file.txt", "/a/b/")) -- Output: "c/file.txt"
print(aip.path.diff("/a/b/", "/a/b/c/file.txt")) -- Output: "../.."
print(aip.path.diff("folder/file.txt", "folder")) -- Output: "file.txt"
Error
Returns an error (Lua table { error: string }
) if paths are invalid.
aip.path.parent
Returns the parent directory path of the specified path.
-- API Signature
aip.path.parent(path: string): string | nil
Gets the parent directory component.
Arguments
path: string
: The path string.
Returns
string | nil
: The parent directory path, ornil
if no parent (e.g., for ".", "/", "C:/").
Example
print(aip.path.parent("some/path/file.txt")) -- Output: "some/path"
print(aip.path.parent(".")) -- Output: nil
Error
Does not typically error.
aip.path.matches_glob
Checks if a path matches one or more glob patterns.
-- API Signature
aip.path.matches_glob(path: string | nil, globs: string | list<string>): boolean | nil
Determines whether the provided path
matches any of the glob patterns given
in globs
. The function returns nil
when path
is nil
.
If globs
is an empty string or an empty list, the result is false
.
Arguments
-
path: string | nil
The path to test. Ifnil
, the function returnsnil
. -
globs: string | list<string>
A single glob pattern string or a Lua list of pattern strings.
Standard wildcards (*
,?
,**
,[]
) are supported.
Returns
boolean | nil
true
– when thepath
matches at least one pattern.
false
– when it matches none.
nil
– when the suppliedpath
wasnil
.
Example
-- Single pattern
print(aip.path.matches_glob("src/main.rs", "**/*.rs")) -- true
-- Multiple patterns
print(aip.path.matches_glob("README.md", {"*.md", "*.txt"})) -- true
-- No match
print(aip.path.matches_glob("image.png", {"*.jpg", "*.gif"})) -- false
-- Nil path
print(aip.path.matches_glob(nil, "*.rs")) -- nil
Error
Returns an error (Lua table { error: string }
) if globs
is not a string
or a list of strings.
aip.text
Text manipulation functions for cleaning, splitting, modifying, and extracting text content.
Functions Summary
aip.text.escape_decode(content: string | nil): string | nil
aip.text.escape_decode_if_needed(content: string | nil): string | nil
aip.text.split_first(content: string | nil, sep: string): (string | nil, string | nil)
aip.text.split_last(content: string | nil, sep: string): (string | nil, string | nil)
aip.text.remove_first_line(content: string | nil): string | nil
aip.text.remove_first_lines(content: string | nil, n: number): string | nil
aip.text.remove_last_line(content: string | nil): string | nil
aip.text.remove_last_lines(content: string | nil, n: number): string | nil
aip.text.trim(content: string | nil): string | nil
aip.text.trim_start(content: string | nil): string | nil
aip.text.trim_end(content: string | nil): string | nil
aip.text.remove_last_lines(content: string | nil, n: number): string | nil
aip.text.truncate(content: string | nil, max_len: number, ellipsis?: string): string | nil
aip.text.replace_markers(content: string | nil, new_sections: list): string | nil
aip.text.ensure(content: string | nil, {prefix?: string, suffix?: string}): string | nil
aip.text.ensure_single_ending_newline(content: string | nil): string | nil
aip.text.format_size(bytes: integer | nil, lowest_size_unit?: "B" | "KB" | "MB" | "GB"): string | nil -- lowest_size_unit default "B"
aip.text.extract_line_blocks(content: string | nil, options: {starts_with: string, extrude?: "content", first?: number}): (list<string> | nil, string | nil)
aip.text.split_first_line(content: string | nil, sep: string): (string | nil, string | nil)
aip.text.split_last_line(content: string | nil, sep: string): (string | nil, string | nil)
aip.text.escape_decode
HTML-decodes the entire content string. If content
is nil
, returns nil
.
-- API Signature
aip.text.escape_decode(content: string | nil): string | nil
Useful for decoding responses from LLMs that might HTML-encode output.
Arguments
content: string | nil
: The content to HTML-decode. Ifnil
, the function returnsnil
.
Returns
string | nil
: The decoded string, ornil
if the inputcontent
wasnil
.
Error
Returns an error (Lua table { error: string }
) if decoding fails (and content was not nil
).
aip.text.escape_decode_if_needed
Selectively HTML-decodes content if needed (currently only decodes <
). If content
is nil
, returns nil
.
-- API Signature
aip.text.escape_decode_if_needed(content: string | nil): string | nil
A more conservative version of escape_decode
for cases where only specific entities need decoding.
Arguments
content: string | nil
: The content to process. Ifnil
, the function returnsnil
.
Returns
string | nil
: The potentially decoded string, ornil
if the inputcontent
wasnil
.
Error
Returns an error (Lua table { error: string }
) if decoding fails (and content was not nil
).
aip.text.split_first
Splits a string into two parts based on the first occurrence of a separator. If content
is nil
, returns (nil, nil)
.
-- API Signature
aip.text.split_first(content: string | nil, sep: string): (string | nil, string | nil)
Arguments
content: string | nil
: The string to split. Ifnil
, the function returns(nil, nil)
.sep: string
: The separator string.
Returns
string | nil
: The part before the first separator.nil
ifcontent
wasnil
or separator not found.string | nil
: The part after the first separator.nil
ifcontent
wasnil
or separator not found. Empty string if separator is at the end.
Example
local content = "first part===second part"
local first, second = aip.text.split_first(content, "===")
-- first = "first part"
-- second = "second part"
Error
This function does not typically error.
aip.text.split_last
Splits a string into two parts based on the last occurrence of a separator. If content
is nil
, returns (nil, nil)
.
-- API Signature
aip.text.split_last(content: string | nil, sep: string): (string | nil, string | nil)
Arguments
content: string | nil
: The string to split. Ifnil
, the function returns(nil, nil)
.sep: string
: The separator string.
Returns
string | nil
: The part before the last separator.nil
ifcontent
wasnil
or separator not found.string | nil
: The part after the last separator.nil
ifcontent
wasnil
or separator not found. Empty string if separator is at the end.
Example
local content = "some == text == more"
local first, second = aip.text.split_last(content, "==")
-- first = "some == text "
-- second = " more"
local content = "no separator here"
local first, second = aip.text.split_last(content, "++")
-- first = "no separator here"
-- second = nil
Error
This function does not typically error.
aip.text.remove_first_line
Removes the first line from the content. If content
is nil
, returns nil
.
-- API Signature
aip.text.remove_first_line(content: string | nil): string | nil
Arguments
content: string | nil
: The content to process. Ifnil
, the function returnsnil
.
Returns
string | nil
: The content with the first line removed, ornil
if the inputcontent
wasnil
.
Error
This function does not typically error.
aip.text.remove_first_lines
Removes the first n
lines from the content. If content
is nil
, returns nil
.
-- API Signature
aip.text.remove_first_lines(content: string | nil, n: number): string | nil
Arguments
content: string | nil
: The content to process. Ifnil
, the function returnsnil
.n: number
: The number of lines to remove.
Returns
string | nil
: The content with the firstn
lines removed, ornil
if the inputcontent
wasnil
.
Error
This function does not typically error.
aip.text.remove_last_line
Removes the last line from the content. If content
is nil
, returns nil
.
-- API Signature
aip.text.remove_last_line(content: string | nil): string | nil
Arguments
content: string | nil
: The content to process. Ifnil
, the function returnsnil
.
Returns
string | nil
: The content with the last line removed, ornil
if the inputcontent
wasnil
.
Error
This function does not typically error.
aip.text.remove_last_lines
Removes the last n
lines from the content. If content
is nil
, returns nil
.
-- API Signature
aip.text.remove_last_lines(content: string | nil, n: number): string | nil
Arguments
content: string | nil
: The content to process. Ifnil
, the function returnsnil
.n: number
: The number of lines to remove.
Returns
string | nil
: The content with the lastn
lines removed, ornil
if the inputcontent
wasnil
.
Error
This function does not typically error.
aip.text.trim
Trims leading and trailing whitespace from a string. If content
is nil
, returns nil
.
-- API Signature
aip.text.trim(content: string | nil): string | nil
Arguments
content: string | nil
: The string to trim. Ifnil
, the function returnsnil
.
Returns
string | nil
: The trimmed string, ornil
if the inputcontent
wasnil
.
Error
This function does not typically error.
aip.text.trim_start
Trims leading whitespace from a string. If content
is nil
, returns nil
.
-- API Signature
aip.text.trim_start(content: string | nil): string | nil
Arguments
content: string | nil
: The string to trim. Ifnil
, the function returnsnil
.
Returns
string | nil
: The trimmed string, ornil
if the inputcontent
wasnil
.
Error
This function does not typically error.
aip.text.trim_end
Trims trailing whitespace from a string. If content
is nil
, returns nil
.
-- API Signature
aip.text.trim_end(content: string | nil): string | nil
Arguments
content: string | nil
: The string to trim. Ifnil
, the function returnsnil
.
Returns
string | nil
: The trimmed string, ornil
if the inputcontent
wasnil
.
Error
This function does not typically error.
aip.text.truncate
Truncates content to a maximum length, optionally adding an ellipsis. If content
is nil
, returns nil
.
-- API Signature
aip.text.truncate(content: string | nil, max_len: number, ellipsis?: string): string | nil
If content
length exceeds max_len
, truncates and appends ellipsis
(if provided).
Arguments
content: string | nil
: The content to truncate. Ifnil
, the function returnsnil
.max_len: number
: The maximum length of the result.ellipsis?: string
(optional): String to append if truncated (e.g., "...").
Returns
string | nil
: The truncated string, ornil
if the inputcontent
wasnil
.
Error
This function does not typically error.
aip.text.replace_markers
Replaces <<START>>...<<END>>
markers in content with corresponding sections. If content
is nil
, returns nil
.
-- API Signature
aip.text.replace_markers(content: string | nil, new_sections: list): string | nil
Replaces occurrences of <<START>>...<<END>>
blocks sequentially with items from new_sections
. Items in new_sections
can be strings or tables with a .content
field.
Arguments
content: string | nil
: The content containing<<START>>...<<END>>
markers. Ifnil
, the function returnsnil
.new_sections: list
: A Lua list of strings or tables to replace the markers.
Returns
string | nil
: The string with markers replaced, ornil
if the inputcontent
wasnil
.
Error
This function does not typically error.
aip.text.ensure
Ensures the content starts with prefix
and/or ends with suffix
. If content
is nil
, returns nil
.
-- API Signature
aip.text.ensure(content: string | nil, {prefix?: string, suffix?: string}): string | nil
Adds the prefix/suffix only if the content doesn't already start/end with it.
Arguments
content: string | nil
: The content to process. Ifnil
, the function returnsnil
.options: table
: A table with optionalprefix
andsuffix
string keys.
Returns
string | nil
: The ensured string, ornil
if the inputcontent
wasnil
.
Error
This function does not typically error.
aip.text.ensure_single_ending_newline
Ensures the content ends with exactly one newline character (\n
). If content
is nil
, returns nil
.
-- API Signature
aip.text.ensure_single_ending_newline(content: string | nil): string | nil
Removes trailing whitespace and adds a single newline if needed. Returns \n
if content is empty. Useful for code normalization.
Arguments
content: string | nil
: The content to process. Ifnil
, the function returnsnil
.
Returns
string | nil
: The string ending with a single newline, ornil
if the inputcontent
wasnil
.
Error
This function does not typically error.
aip.text.format_size
Formats a byte count (in bytes) into a human-readable, fixed-width string (9 characters, right-aligned).
If bytes
is nil
, the function returns nil
.
Optional lowest unit size to be used (by default "B" for Bytes)
-- API Signature
aip.text.format_size(bytes: integer | nil, lowest_size_unit?: "B" | "KB" | "MB" | "GB"): string | nil
Examples
aip.text.format_size(777) -- " 777 B "
aip.text.format_size(8_777) -- " 8.78 KB"
aip.text.format_size(5_242_880) -- " 5.24 MB"
aip.text.format_size(nil) -- nil
aip.text.extract_line_blocks
Extracts consecutive lines starting with a specific prefix. If content
is nil
, returns (nil, nil)
.
-- API Signature
aip.text.extract_line_blocks(content: string | nil, options: {starts_with: string, extrude?: "content", first?: number}): (list<string> | nil, string | nil)
Extracts blocks of consecutive lines from content
where each line begins with options.starts_with
.
Arguments
content: string | nil
: The content to extract from. Ifnil
, the function returns(nil, nil)
.options: table
:starts_with: string
(required): The prefix indicating a line block.extrude?: "content"
(optional): If set, returns the remaining content after extraction as the second return value.first?: number
(optional): Limits the number of blocks extracted. Remaining lines (if any) contribute to the extruded content ifextrude
is set.
Returns
list<string> | nil
: A Lua list of strings, each element being a block of consecutive lines starting with the prefix.nil
if inputcontent
wasnil
.string | nil
: The remaining content ifextrude = "content"
, otherwisenil
.nil
if inputcontent
wasnil
.
Example
local text = "> Block 1 Line 1\n> Block 1 Line 2\nSome other text\n> Block 2"
local blocks, remain = aip.text.extract_line_blocks(text, {starts_with = ">", extrude = "content"})
-- blocks = { "> Block 1 Line 1\n> Block 1 Line 2", "> Block 2" }
-- remain = "Some other text\n"
Error
Returns an error (Lua table { error: string }
) if arguments are invalid (and content was not nil
).
aip.text.split_first_line
Splits a string into two parts based on the first line that exactly matches the separator. If content
is nil
, returns (nil, nil)
. If no line matches, returns (original_content, nil)
.
-- API Signature
aip.text.split_first_line(content: string | nil, sep: string): (string | nil, string | nil)
The separator line itself is not included in either part.
Arguments
content: string | nil
: The string to split. Ifnil
, the function returns(nil, nil)
.sep: string
: The exact string the line must match.
Returns
string | nil
: The part before the first matching line.nil
ifcontent
wasnil
. Empty string if the first matching line was the first line.string | nil
: The part after the first matching line.nil
ifcontent
wasnil
or no line matchedsep
. Empty string if the first matching line was the last line.
Example
local text = "line one\n---\nline two\n---\nline three"
local first, second = aip.text.split_first_line(text, "---")
-- first = "line one"
-- second = "line two\n---\nline three"
local first, second = aip.text.split_first_line("START\ncontent", "START")
-- first = ""
-- second = "content"
local first, second = aip.text.split_first_line("no separator", "---")
-- first = "no separator"
-- second = nil
Error
This function does not typically error.
aip.text.split_last_line
Splits a string into two parts based on the last line that exactly matches the separator. If content
is nil
, returns (nil, nil)
. If no line matches, returns (original_content, nil)
.
-- API Signature
aip.text.split_last_line(content: string | nil, sep: string): (string | nil, string | nil)
The separator line itself is not included in either part.
Arguments
content: string | nil
: The string to split. Ifnil
, the function returns(nil, nil)
.sep: string
: The exact string the line must match.
Returns
string | nil
: The part before the last matching line.nil
ifcontent
wasnil
or no line matchedsep
.string | nil
: The part after the last matching line.nil
ifcontent
wasnil
or no line matchedsep
. Empty string if the last matching line was the last line.
Example
local text = "line one\n---\nline two\n---\nline three"
local first, second = aip.text.split_last_line(text, "---")
-- first = "line one\n---\nline two"
-- second = "line three"
local first, second = aip.text.split_last_line("content\nEND", "END")
-- first = "content"
-- second = ""
local first, second = aip.text.split_last_line("no separator", "---")
-- first = "no separator"
-- second = nil
Error
This function does not typically error.
aip.md
Markdown processing functions for extracting structured information like code blocks and metadata.
Functions Summary
aip.md.extract_blocks(md_content: string): list<MdBlock>
aip.md.extract_blocks(md_content: string, lang: string): list<MdBlock>
aip.md.extract_blocks(md_content: string, {lang?: string, extrude: "content"}): (list<MdBlock>, string)
aip.md.extract_meta(md_content: string | nil): (table | nil, string | nil)
aip.md.outer_block_content_or_raw(md_content: string): string
aip.md.extract_blocks
Extracts fenced code blocks (MdBlock) from markdown content.
-- API Signatures
-- Extract all blocks:
aip.md.extract_blocks(md_content: string): list<MdBlock>
-- Extract blocks by language:
aip.md.extract_blocks(md_content: string, lang: string): list<MdBlock>
-- Extract blocks and remaining content:
aip.md.extract_blocks(md_content: string, {lang?: string, extrude: "content"}): (list<MdBlock>, string)
Parses md_content
and extracts fenced code blocks (
).
Arguments
md_content: string
: The markdown content.options?: string | table
(optional):- If string: Filter blocks by this language identifier.
- If table:
lang?: string
: Filter by language.extrude?: "content"
: If set, also return content outside the extracted blocks.
Returns
- If
extrude
is not set:list<MdBlock>
: A Lua list of MdBlock objects. - If
extrude = "content"
:(list<MdBlock>, string)
: A tuple containing the list of MdBlock objects and the remaining content string.
Example
local md = "```rust\nfn main() {}\n```\nSome text.\n```lua\nprint('hi')\n```"
local rust_blocks = aip.md.extract_blocks(md, "rust")
-- rust_blocks = { { content = "fn main() {}", lang = "rust", info = "" } }
local lua_blocks, remain = aip.md.extract_blocks(md, {lang = "lua", extrude = "content"})
-- lua_blocks = { { content = "print('hi')", lang = "lua", info = "" } }
-- remain = "Some text.\n" (approx.)
Error
Returns an error (Lua table { error: string }
) on invalid options or parsing errors.
aip.md.extract_meta
Extracts and merges metadata from #!meta
TOML blocks.
-- API Signature
aip.md.extract_meta(md_content: string | nil): (table | nil, string | nil)
Finds all toml #!meta ...
blocks, parses their TOML content, merges them into a single Lua table, and returns the table along with the original content stripped of the meta blocks.
Arguments
md_content: string
: The markdown content.
Returns
table
: Merged metadata from all#!meta
blocks (empty object if not found)string
: Original content with meta blocks removed.
If md_content
the return will be (nil, nil)
Example
local content = "Intro.\n```toml\n#!meta\ntitle=\"T\"\n```\nMain.\n```toml\n#!meta\nauthor=\"A\"\n```"
local meta, remain = aip.md.extract_meta(content)
-- meta = { title = "T", author = "A" }
-- remain = "Intro.\n\nMain.\n" (approx.)
Error
Returns an error (Lua table { error: string }
) if any meta block contains invalid TOML.
aip.md.outer_block_content_or_raw
Extracts content from the outermost code block, or returns raw content.
-- API Signature
aip.md.outer_block_content_or_raw(md_content: string): string
If md_content
starts and ends with a fenced code block (```), returns the content inside. Otherwise, returns the original md_content
. Useful for processing LLM responses.
Arguments
md_content: string
: The markdown content.
Returns
string
: Content inside the outer block, or the original string.
Example
local block = "```rust\ncontent\n```"
local raw = "no block"
print(aip.md.outer_block_content_or_raw(block)) -- Output: "content\n"
print(aip.md.outer_block_content_or_raw(raw)) -- Output: "no block"
aip.json
JSON parsing and stringification functions.
Functions Summary
aip.json.parse(content: string): table | value
aip.json.parse_ndjson(content: string): list<table>
aip.json.stringify(content: table): string
aip.json.stringify_pretty(content: table): string
aip.json.stringify_to_line(content: table): string -- Deprecated alias for `stringify`
aip.json.parse
Parse a JSON string into a Lua table or value.
-- API Signature
aip.json.parse(content: string): table | value
Arguments
content: string
: The JSON string to parse.
Returns
table | value
: A Lua value representing the parsed JSON.
Example
local obj = aip.json.parse('{"name": "John", "age": 30}')
print(obj.name) -- Output: John
Error
Returns an error (Lua table { error: string }
) if content
is not valid JSON.
aip.json.parse_ndjson
Parse a newline-delimited JSON (NDJSON) string into a list of tables/values.
-- API Signature
aip.json.parse_ndjson(content: string): list<table>
Parses each non-empty line as a separate JSON object/value.
Arguments
content: string
: The NDJSON string.
Returns
list<table>
: A Lua list containing the parsed value from each line.
Example
local ndjson = '{"id":1}\n{"id":2}'
local items = aip.json.parse_ndjson(ndjson)
print(items[1].id) -- Output: 1
print(items[2].id) -- Output: 2
Error
Returns an error (Lua table { error: string }
) if any line contains invalid JSON.
aip.json.stringify
Stringify a Lua table/value into a compact, single-line JSON string.
-- API Signature
aip.json.stringify(content: table): string
Arguments
content: table
: The Lua table/value to stringify.
Returns
string
: A single-line JSON string representation.
Example
local obj = {name = "John", age = 30}
local json_str = aip.json.stringify(obj)
-- json_str = '{"age":30,"name":"John"}' (order may vary)
Error
Returns an error (Lua table { error: string }
) if content
cannot be serialized.
aip.json.stringify_pretty
Stringify a Lua table/value into a pretty-formatted JSON string (2-space indent).
-- API Signature
aip.json.stringify_pretty(content: table): string
Arguments
content: table
: The Lua table/value to stringify.
Returns
string
: A formatted JSON string with newlines and indentation.
Example
local obj = {name = "John", age = 30}
local json_str = aip.json.stringify_pretty(obj)
-- json_str =
-- {
-- "age": 30,
-- "name": "John"
-- } (order may vary)
Error
Returns an error (Lua table { error: string }
) if content
cannot be serialized.
aip.json.stringify_to_line (Deprecated)
Deprecated alias for aip.json.stringify
.
-- API Signature
aip.json.stringify_to_line(content: table): string
aip.web
Functions for making HTTP GET and POST requests, and for URL manipulation.
Functions Summary
aip.web.get(url: string): WebResponse
aip.web.post(url: string, data: string | table): WebResponse
aip.web.parse_url(url: string | nil): table | nil
aip.web.resolve_href(href: string | nil, base_url: string): string | nil
aip.web.get
Makes an HTTP GET request.
-- API Signature
aip.web.get(url: string): WebResponse
Arguments
url: string
: The URL to request.
Returns
WebResponse
: A WebResponse table containing the result.
Example
local response = aip.web.get("https://httpbin.org/get")
if response.success then
print("Status:", response.status)
-- response.content might be a string or table (if JSON)
print("Content Type:", type(response.content))
else
print("Error:", response.error, "Status:", response.status)
end
Error
Returns an error (Lua table { error: string }
) if the request cannot be initiated (e.g., network error, invalid URL). Check response.success
for HTTP-level errors (non-2xx status).
aip.web.post
Makes an HTTP POST request.
-- API Signature
aip.web.post(url: string, data: string | table): WebResponse
Sends data
in the request body. If data
is a string, Content-Type
is text/plain
. If data
is a table, it's serialized to JSON and Content-Type
is application/json
.
Arguments
url: string
: The URL to request.data: string | table
: Data to send in the body.
Returns
WebResponse
: A WebResponse table containing the result.
Example
-- POST plain text
local r1 = aip.web.post("https://httpbin.org/post", "plain text data")
-- POST JSON
local r2 = aip.web.post("https://httpbin.org/post", { key = "value", num = 123 })
if r2.success and type(r2.content) == "table" then
print("Received JSON echo:", r2.content.json.key) -- Output: value
end
Error
Returns an error (Lua table { error: string }
) if the request cannot be initiated or data serialization fails. Check response.success
for HTTP-level errors.
aip.web.parse_url
Parses a URL string and returns its components as a table.
-- API Signature
aip.web.parse_url(url: string | nil): table | nil
Parses the given URL string and extracts its various components.
Arguments
url: string | nil
: The URL string to parse. Ifnil
is provided, the function returnsnil
.
Returns
(table | nil
)
- If the
url
is a valid string, returns a table with the following fields:scheme: string
(e.g., "http", "https")host: string | nil
(e.g., "example.com")port: number | nil
(e.g., 80, 443)path: string
(e.g., "/path/to/resource")query: table | nil
(A Lua table where keys are query parameter names and values are their corresponding string values. E.g.,{ name = "value" }
)fragment: string | nil
(The part of the URL after '#')username: string
(The username for authentication, empty string if not present)password: string | nil
(The password for authentication)url: string
(The original or normalized URL string that was parsed)page_url: string
- (The url without the query and fragment
- If the input
url
isnil
, the function returnsnil
.
Example
local parsed = aip.web.parse_url("https://user:pass@example.com:8080/path/to/page.html?param1=val#fragment")
if parsed then
print(parsed.scheme) -- "https"
print(parsed.host) -- "example.com"
print(parsed.port) -- 8080
print(parsed.path) -- "/path/to/page.html"
print(parsed.query.param1) -- "val"
print(parsed.fragment) -- "fragment"
print(parsed.username) -- "user"
print(parsed.password) -- "pass"
print(parsed.url) -- "https://user:pass@example.com:8080/path/to/page.html?query=val#fragment"
print(parsed.page_url) -- "https://user:pass@example.com:8080/path/to/page.html"
end
local nil_result = aip.web.parse_url(nil)
-- nil_result will be nil
Error
Returns an error (Lua table { error: string }
) if the url
string is provided but is invalid and cannot be parsed.
aip.web.resolve_href
Resolves an href
(like one from an HTML <a>
tag) against a base_url
.
-- API Signature
aip.web.resolve_href(href: string | nil, base_url: string): string | nil
Arguments
href: string | nil
: The href string to resolve. This can be an absolute URL, a scheme-relative URL, an absolute path, or a relative path. Ifnil
, the function returnsnil
.base_url: string
: The base URL string against which to resolve thehref
. Must be a valid absolute URL.
Returns
(string | nil
)
- If
href
isnil
, returnsnil
. - If
href
is already an absolute URL (e.g., "https://example.com/page"), it's returned as is. - Otherwise,
href
is joined withbase_url
to form an absolute URL. - Returns the resolved absolute URL string.
Example
local base = "https://example.com/docs/path/"
-- Absolute href
print(aip.web.resolve_href("https://another.com/page.html", base))
-- Output: "https://another.com/page.html"
-- Relative path href
print(aip.web.resolve_href("sub/page.html", base))
-- Output: "https://example.com/docs/path/sub/page.html"
-- Absolute path href
print(aip.web.resolve_href("/other/resource.txt", base))
-- Output: "https://example.com/other/resource.txt"
-- Scheme-relative href
print(aip.web.resolve_href("//cdn.com/asset.js", base))
-- Output: "https://cdn.com/asset.js" (uses base_url's scheme)
print(aip.web.resolve_href("//cdn.com/asset.js", "http://example.com/"))
-- Output: "http://cdn.com/asset.js"
-- href is nil
print(aip.web.resolve_href(nil, base))
-- Output: nil (Lua nil)
Error
Returns an error (Lua table { error: string }
) if:
base_url
is not a valid absolute URL.href
andbase_url
cannot be successfully joined (e.g., due to malformedhref
).
aip.uuid
The aip.uuid
module exposes functions for generating various UUIDs and converting timestamped UUIDs.
Functions Summary
aip.uuid.new(): string
aip.uuid.new_v4(): string
aip.uuid.new_v7(): string
aip.uuid.new_v4_b64(): string
aip.uuid.new_v4_b64u(): string
aip.uuid.new_v4_b58(): string
aip.uuid.new_v7_b64(): string
aip.uuid.new_v7_b64u(): string
aip.uuid.new_v7_b58(): string
aip.uuid.to_time_epoch_ms(value: string | nil): integer | nil
aip.uuid.new
Generates a new UUID version 4. This is an alias for aip.uuid.new_v4()
.
-- API Signature
aip.uuid.new(): string
Returns
string
: The generated UUIDv4 as a string (e.g., "f47ac10b-58cc-4372-a567-0e02b2c3d479").
Example
local id = aip.uuid.new()
print(id)
aip.uuid.new_v4
Generates a new UUID version 4.
-- API Signature
aip.uuid.new_v4(): string
Returns
string
: The generated UUIDv4 as a string (e.g., "f47ac10b-58cc-4372-a567-0e02b2c3d479").
Example
local id_v4 = aip.uuid.new_v4()
print(id_v4)
aip.uuid.new_v7
Generates a new UUID version 7 (time-ordered).
-- API Signature
aip.uuid.new_v7(): string
Returns
string
: The generated UUIDv7 as a string.
Example
local id_v7 = aip.uuid.new_v7()
print(id_v7)
aip.uuid.new_v4_b64
Generates a new UUID version 4 and encodes it using standard Base64.
-- API Signature
aip.uuid.new_v4_b64(): string
Returns
string
: The Base64 encoded UUIDv4 string.
Example
local id_v4_b64 = aip.uuid.new_v4_b64()
print(id_v4_b64)
aip.uuid.new_v4_b64u
Generates a new UUID version 4 and encodes it using URL-safe Base64 without padding.
-- API Signature
aip.uuid.new_v4_b64u(): string
Returns
string
: The URL-safe Base64 encoded (no padding) UUIDv4 string.
Example
local id_v4_b64u = aip.uuid.new_v4_b64u()
print(id_v4_b64u)
aip.uuid.new_v4_b58
Generates a new UUID version 4 and encodes it using Base58.
-- API Signature
aip.uuid.new_v4_b58(): string
Returns
string
: The Base58 encoded UUIDv4 string.
Example
local id_v4_b58 = aip.uuid.new_v4_b58()
print(id_v4_b58)
aip.uuid.new_v7_b64
Generates a new UUID version 7 and encodes it using standard Base64.
-- API Signature
aip.uuid.new_v7_b64(): string
Returns
string
: The Base64 encoded UUIDv7 string.
Example
local id_v7_b64 = aip.uuid.new_v7_b64()
print(id_v7_b64)
aip.uuid.new_v7_b64u
Generates a new UUID version 7 and encodes it using URL-safe Base64 without padding.
-- API Signature
aip.uuid.new_v7_b64u(): string
Returns
string
: The URL-safe Base64 encoded (no padding) UUIDv7 string.
Example
local id_v7_b64u = aip.uuid.new_v7_b64u()
print(id_v7_b64u)
aip.uuid.new_v7_b58
Generates a new UUID version 7 and encodes it using Base58.
-- API Signature
aip.uuid.new_v7_b58(): string
Returns
string
: The Base58 encoded UUIDv7 string.
Example
local id_v7_b58 = aip.uuid.new_v7_b58()
print(id_v7_b58)
aip.uuid.to_time_epoch_ms
Converts a timestamped UUID string (V1, V6, V7) to milliseconds since Unix epoch.
Returns nil
if the input is nil
, not a valid UUID string, or if the UUID type
does not contain an extractable timestamp (e.g., V4).
-- API Signature
aip.uuid.to_time_epoch_ms(value: string | nil): integer | nil
Arguments
value: string | nil
: The UUID string ornil
.
Returns
integer | nil
: Milliseconds since Unix epoch, or nil
.
Example
local v7_uuid_str = aip.uuid.new_v7()
local millis = aip.uuid.to_time_epoch_ms(v7_uuid_str)
if millis then
print("Timestamp in ms: " .. millis)
else
print("Could not extract timestamp.")
end
local v4_uuid_str = aip.uuid.new_v4()
local millis_v4 = aip.uuid.to_time_epoch_ms(v4_uuid_str)
-- millis_v4 will be nil
local invalid_millis = aip.uuid.to_time_epoch_ms("not-a-uuid")
-- invalid_millis will be nil
local nil_millis = aip.uuid.to_time_epoch_ms(nil)
-- nil_millis will be nil
aip.time
aip.time.now_iso_utc(): string -- RFC 3339 UTC (seconds precision)
aip.time.now_iso_local(): string -- RFC 3339 local time (seconds precision)
aip.time.now_iso_utc_micro(): string -- RFC 3339 UTC (microseconds)
aip.time.now_iso_local_micro(): string -- RFC 3339 local time (microseconds)
aip.time.now_utc_micro(): integer -- epoch microseconds (UTC)
aip.time.today_utc(): string -- "YYYY-MM-DD" (UTC)
aip.time.today_local(): string -- "YYYY-MM-DD" (local)
aip.lua
Lua value inspection functions.
Functions Summary
aip.lua.dump(value: any): string
aip.lua.dump
Dump a Lua value into its string representation.
-- API Signature
aip.lua.dump(value: any): string
Provides a detailed string representation of any Lua value, useful for debugging.
Arguments
value: any
: The Lua value to dump.
Returns
string
: A string representation of the value.
Example
local tbl = { key = "value", nested = { num = 42 } }
print(aip.lua.dump(tbl))
-- Output: Example: table: 0x... { key = "value", nested = table: 0x... { num = 42 } }
Error
Returns an error (Lua table { error: string }
) if the value cannot be converted to string.
aip.agent
Functions for running other AIPACK agents from within a Lua script.
Functions Summary
aip.agent.run(agent_name: string, options?: table): any
aip.agent.extract_options(value: any): table | nil
aip.agent.run
Runs another agent and returns its response.
-- API Signature
aip.agent.run(agent_name: string, options?: table): any
Executes the agent specified by agent_name
. The function waits for the called agent
to complete and returns its result. This allows for chaining agents together.
Arguments
agent_name: string
: The name of the agent to run. This can be a relative path (e.g.,"../my-other-agent.aip"
) or a fully qualified pack reference (e.g.,"my-ns@my-pack/feature/my-agent.aip"
). Relative paths are resolved from the directory of the calling agent.options?: table
: An optional table containing input data and agent options.inputs?: string | list | table
: Input data for the agent. Can be a single string, a list of strings, or a table of structured inputs.options?: table
: Agent-specific options. These options are passed directly to the called agent's execution environment and can override settings defined in the called agent's.aip
file.
Input Examples:
-- Run an agent with a single string input
local response = aip.agent.run("agent-name", { inputs = "hello" })
-- Run an agent with multiple string inputs
local response = aip.agent.run("agent-name", { inputs = {"input1", "input2"} })
-- Run an agent with structured inputs (e.g., file records)
local response = aip.agent.run("agent-name", {
inputs = {
{ path = "file1.txt", content = "..." },
{ path = "file2.txt", content = "..." }
}
})
Returns
The result of the agent execution. The type of the returned value depends on the agent's output:
- If the agent produces an AI response without a specific output script, it returns a table representing the
AiResponse
object. - If the agent has an output script, it returns the value returned by that output script.
// Example structure of a returned AiResponse object (if no output script)
{
action: string, // e.g., "PrintToConsole", "WriteFiles"
outputs: any, // Depends on the action/output
options: table // Options used during the run
// ... other properties from AiResponse
}
Error
Returns an error if:
- The
agent_name
is invalid or the agent file cannot be located/loaded. - The options table contains invalid parameters.
- The execution of the called agent fails.
- An internal communication error occurs while waiting for the agent's result.
{
error: string // Error message
}
aip.agent.extract_options
Extracts relevant agent options from a given Lua value.
-- API Signature
aip.agent.extract_options(value: any): table | nil
If the input value
is a Lua table, this function creates a new table and copies
the following properties if they exist in the input table:
model
model_aliases
input_concurrency
temperature
Other properties are ignored. If the input value
is nil
or not a table,
the function returns nil
.
Arguments
value: any
: The Lua value from which to extract options.
Returns
A new Lua table containing the extracted options, or nil
if the input
was nil
or not a table.
aip.task
Functions for recording pins at the task level (attached to the current task of the current run).
Functions Summary
aip.task.pin(iden: string, content: any)
aip.task.pin(iden: string, priority: number, content: any)
aip.task.pin
Creates a pin attached to the current task. Requires that both CTX.RUN_UID and CTX.TASK_UID are available (i.e., must be called during a task cycle, not in before_all or after_all).
-- API Signatures
aip.task.pin(iden: string, content: any)
aip.task.pin(iden: string, priority: number, content: any)
Records a pin for the current task. When the optional priority is provided, it will be stored along with the pin.
Arguments
-
iden: string
Identifier (name) for this pin. -
priority: number (optional)
Optional numeric priority to associate with the pin. -
content: any
Arbitrary content to associate with the pin (string, table, etc.).
Returns
- Nothing. This function records the pin as a side effect.
Example
-- Simple pin (no priority)
aip.task.pin("review", "Needs follow-up")
-- Pin with priority
aip.task.pin("checkpoint", 0.7, { step = 3, note = "after validation" })
Error
Returns an error (Lua table { error: string }
) if called outside a task context (no CTX.TASK_UID
), if there is no run context, or if arguments are invalid.
aip.run
Functions for recording pins at the run level (attached to the overall run).
Functions Summary
aip.run.pin(iden: string, content: any)
aip.run.pin(iden: string, priority: number, content: any)
aip.run.pin
Creates a pin attached to the current run. Requires that CTX.RUN_UID is available.
-- API Signatures
aip.run.pin(iden: string, content: any)
aip.run.pin(iden: string, priority: number, content: any)
Records a pin for the current run. When the optional priority is provided, it will be stored along with the pin.
Arguments
-
iden: string
Identifier (name) for this pin. -
priority: number (optional)
Optional numeric priority to associate with the pin. -
content: any
Arbitrary content to associate with the pin (string, table, etc.).
Returns
- Nothing. This function records the pin as a side effect.
Example
-- Simple pin (no priority)
aip.run.pin("summary", "Run started successfully")
-- Pin with priority
aip.run.pin("quality-score", 0.85, { score = 0.85, rationale = "good coverage" })
Error
Returns an error (Lua table { error: string }
) if there is no run context (no CTX.RUN_UID
) or if arguments are invalid.
aip.flow
Functions for controlling the AIPACK agent execution flow from within script blocks (before_all
, data
).
Functions Summary
aip.flow.before_all_response(data: BeforeAllData) -> table
aip.flow.data_response(data: DataData) -> table
aip.flow.skip(reason?: string): table
These functions return special tables that instruct the agent executor how to proceed. They should be the return value of the script block.
aip.flow.before_all_response
Customizes execution flow at the 'Before All' stage (in before_all
script block).
-- API Signature
aip.flow.before_all_response(data: BeforeAllData) -> table
This function is typically called within the before_all
block of an agent script
to override the default behavior of passing all initial inputs to the agent.
Arguments
data: table
- A table defining the new inputs and options for the agent execution cycle.
related types: AgentOptionstype BeforeAllData = { inputs?: any[], // Optional. A list of new inputs to use for the agent run cycle. Overrides initial inputs. options?: AgentOptions, // Optional. Partial AgentOptions to override for this run. before_all?: any, // Optional. The before_all data that can be access via before_all... } & any // Can also include other arbitrary data fields if needed.
Example
local result = aip.flow.before_all_response({
inputs = {"processed_input_1", "processed_input_2"},
options = {
model = "gemini-2.5-flash",
input_concurrency = 3
},
before_all = {some_data = "hello world" } -- Arbitrary data is allowed
})
-- The agent executor will process this result table.
Error
This function does not directly return any errors. Errors might occur during the creation of lua table.
aip.flow.data_response
Customizes execution flow at the 'Data' stage for a single input (in data
script block).
-- API Signature
aip.flow.data_response(data: DataData) -> table
This function is typically called within the data
block of an agent script.
It allows overriding the input and/or options for the current input cycle,
or returning additional arbitrary data.
Arguments
data: table
- A table defining the new input, options, and/or other data for the current cycle.
related types: AgentOptionstype DataData = { input?: any | nil, // Optional. The new input to use for this cycle. If nil, the original input is used. data?: any | nil, // Data that will be available in the next stage. Same as returning a simple data. options?: AgentOptions, // Optional. Partial AgentOptions to override for this cycle. } & any // Can also include other arbitrary data fields (e.g., computed values, flags)
Example
-- Use a transformed input and override the model for this cycle
return aip.flow.data_response({
data = data, -- The data that would have been returned
input = transformed_input,
options = { model = "gpt-4o" },
})
-- The agent executor will process this result table.
Error
This function does not directly return any errors. Errors might occur during the creation of lua table.
aip.flow.skip
Skips processing the current input cycle (in data
script block).
-- API Signature
aip.flow.skip(reason?: string): table
This function is typically called within the data
block of an agent script
to instruct AIPACK to skip processing the current input value and move to the next one.
Arguments
reason: string (optional)
: An optional string providing the reason for skipping the input cycle. This reason might be logged or displayed depending on the AIPACK execution context.
Example
-- Skip processing if the input is nil or empty
if input == nil or input == "" then
return aip.flow.skip("Input is empty")
end
-- Continue processing the input if not skipped
-- ... rest of data block ...
Error
This function does not directly return any errors. Errors might occur during the creation of lua table.
aip.cmd
Functions for executing system commands.
Functions Summary
aip.cmd.exec(cmd_name: string, args?: string | list<string>): CmdResponse | {error: string, stdout?: string, stderr?: string, exit?: number}
aip.cmd.exec
Execute a system command with optional arguments.
-- API Signature
aip.cmd.exec(cmd_name: string, args?: string | list<string>): CmdResponse | {error: string, stdout?: string, stderr?: string, exit?: number}
Executes the command using the system shell. On Windows, wraps with cmd /C
.
Arguments
cmd_name: string
: Command name or path.args?: string | list<string>
(optional): Arguments as a single string or list of strings.
Returns
CmdResponse
: A CmdResponse table with stdout, stderr, and exit code, even if the exit code is non-zero.
Example
-- Single string argument
local r1 = aip.cmd.exec("echo", "hello world")
print("stdout:", r1.stdout) -- Output: hello world\n (or similar)
print("exit:", r1.exit) -- Output: 0
-- Table of arguments
local r2 = aip.cmd.exec("ls", {"-l", "-a", "nonexistent"})
print("stderr:", r2.stderr) -- Output: ls: nonexistent: No such file... (or similar)
print("exit:", r2.exit) -- Output: non-zero exit code
-- Example of potential error return (e.g., command not found)
local r3 = aip.cmd.exec("nonexistent_command")
if type(r3) == "table" and r3.error then
print("Execution Error:", r3.error)
end
Error
Returns an error (Lua table { error: string, stdout?: string, stderr?: string, exit?: number }
) only if the process fails to start (e.g., command not found, permission issue). Non-zero exit codes from the command itself are captured in the CmdResponse and do not cause a Lua error by default.
aip.semver
Functions for semantic versioning (SemVer 2.0.0) operations.
Functions Summary
aip.semver.compare(version1: string, operator: string, version2: string): boolean | {error: string}
aip.semver.parse(version: string): {major: number, minor: number, patch: number, prerelease: string | nil, build: string | nil} | {error: string}
aip.semver.is_prerelease(version: string): boolean | {error: string}
aip.semver.valid(version: string): boolean
aip.semver.compare
Compares two version strings using an operator.
-- API Signature
aip.semver.compare(version1: string, operator: string, version2: string): boolean | {error: string}
Compares versions according to SemVer rules (prerelease < release, build metadata ignored).
Arguments
version1: string
: First version string.operator: string
: Comparison operator (<
,<=
,=
,==
,>=
,>
,!=
,~=
).version2: string
: Second version string.
Returns
boolean
:true
if the comparison holds,false
otherwise.{error: string}
: An error table on failure.
Example
print(aip.semver.compare("1.2.3", ">", "1.2.0")) -- Output: true
print(aip.semver.compare("1.0.0-alpha", "<", "1.0.0")) -- Output: true
print(aip.semver.compare("1.0.0+build", "==", "1.0.0")) -- Output: true
local r = aip.semver.compare("abc", ">", "1.0.0")
if type(r) == "table" and r.error then
print("Error:", r.error)
end
Error
Returns an error (Lua table { error: string }
) if operator is invalid or versions are not valid SemVer strings.
aip.semver.parse
Parses a version string into its components.
-- API Signature
aip.semver.parse(version: string): {major: number, minor: number, patch: number, prerelease: string | nil, build: string | nil} | {error: string}
Arguments
version: string
: The SemVer string to parse.
Returns
table
: A table containingmajor
,minor
,patch
,prerelease
(string or nil), andbuild
(string or nil) components.{error: string}
: An error table on failure.
Example
local v = aip.semver.parse("1.2.3-beta.1+build.123")
print(v.major, v.minor, v.patch) -- Output: 1 2 3
print(v.prerelease) -- Output: beta.1
print(v.build) -- Output: build.123
local r = aip.semver.parse("invalid")
if type(r) == "table" and r.error then
print("Error:", r.error)
end
Error
Returns an error (Lua table { error: string }
) if version
is not a valid SemVer string.
aip.semver.is_prerelease
Checks if a version string has a prerelease component.
-- API Signature
aip.semver.is_prerelease(version: string): boolean | {error: string}
Arguments
version: string
: The SemVer string to check.
Returns
boolean
:true
if it has a prerelease component (e.g.,-alpha
),false
otherwise.{error: string}
: An error table on failure.
Example
print(aip.semver.is_prerelease("1.2.3-beta")) -- Output: true
print(aip.semver.is_prerelease("1.2.3")) -- Output: false
print(aip.semver.is_prerelease("1.0.0+build")) -- Output: false
local r = aip.semver.is_prerelease("invalid")
if type(r) == "table" and r.error then
print("Error:", r.error)
end
Error
Returns an error (Lua table { error: string }
) if version
is not a valid SemVer string.
aip.semver.valid
Checks if a string is a valid SemVer 2.0.0 version.
-- API Signature
aip.semver.valid(version: string): boolean
Arguments
version: string
: The string to validate.
Returns
boolean
:true
if valid,false
otherwise.
Example
print(aip.semver.valid("1.2.3")) -- Output: true
print(aip.semver.valid("1.2.3-alpha.1")) -- Output: true
print(aip.semver.valid("1.0")) -- Output: false
print(aip.semver.valid("invalid")) -- Output: false
Error
This function does not typically error, returning false
for invalid formats.
aip.rust
Functions for processing Rust code.
Functions Summary
aip.rust.prune_to_declarations(code: string): string | {error: string}
aip.rust.prune_to_declarations
Prunes Rust code, replacing function bodies with { ... }
.
-- API Signature
aip.rust.prune_to_declarations(code: string): string | {error: string}
Replaces function bodies with { ... }
, preserving comments, whitespace, and non-function code structures.
Arguments
code: string
: The Rust code to prune.
Returns
string
: The pruned Rust code string on success.{error: string}
: An error table on failure.
Example
local rust_code = "fn greet(name: &str) {\n println!(\"Hello, {}!\", name);\n}\n\nstruct Data;"
local pruned = aip.rust.prune_to_declarations(rust_code)
-- pruned might be: "fn greet(name: &str) { ... }\n\nstruct Data;" (exact spacing may vary)
Error
Returns an error (Lua table { error: string }
) if pruning fails.
aip.html
Functions for processing HTML content.
Functions Summary
aip.html.slim(html_content: string): string | {error: string}
aip.html.to_md(html_content: string): string | {error: string}
aip.html.slim
Strips non-content elements and most attributes from HTML.
-- API Signature
aip.html.slim(html_content: string): string | {error: string}
Removes <script>
, <link>
, <style>
, <svg>
, comments, empty lines, and most attributes (keeps class
, aria-label
, href
).
Arguments
html_content: string
: The HTML content string.
Returns
string
: The cleaned HTML string on success.{error: string}
: An error table on failure.
Example
local html = "<script>alert('hi')</script><p class='c' style='color:red'>Hello</p>"
local cleaned = aip.html.slim(html)
-- cleaned might be: "<p class=\"c\">Hello</p>" (exact output may vary)
Error
Returns an error (Lua table { error: string }
) if pruning fails.
aip.html.to_md
Converts HTML content to Markdown format.
-- API Signature
aip.html.to_md(html_content: string): string | {error: string}
Arguments
html_content: string
: The HTML content to be converted.
Returns
string
: The Markdown representation of the HTML content.{error: string}
: An error table on failure.
Example
local markdown_content = aip.html.to_md("<h1>Hello</h1><p>World</p>")
-- markdown_content will be "# Hello\n\nWorld\n"
Error
Returns an error (Lua table { error: string }
) if the HTML content fails to be converted to Markdown.
aip.git
Functions for performing basic Git operations in the workspace.
Functions Summary
aip.git.restore(path: string): string | {error: string, stdout?: string, stderr?: string, exit?: number}
aip.git.restore
Executes git restore <path>
in the workspace directory.
-- API Signature
aip.git.restore(path: string): string | {error: string, stdout?: string, stderr?: string, exit?: number}
Restores the specified file or directory path to its state from the Git index.
Arguments
path: string
: The file or directory path to restore (relative to workspace root).
Returns
string
: Standard output from thegit restore
command on success.{error: string, stdout?: string, stderr?: string, exit?: number}
: An error table if the command fails (e.g., path not known to Git, non-zero exit code, stderr output). This error table is similar to a CmdResponse but includes an additionalerror
field.
Example
-- Restore a modified file
local result = aip.git.restore("src/main.rs")
-- Check if result is an error table or the stdout string
if type(result) == "table" and result.error then
print("Error restoring:", result.error)
print("Stderr:", result.stderr) -- May contain git error message
else
print("Restore stdout:", result)
end
Error
Returns an error (Lua table { error: string, stdout?: string, stderr?: string, exit?: number }
) if the git restore
command encounters an issue, such as the path not being known to Git, insufficient permissions, or the command returning a non-zero exit code with stderr output.
aip.hash
The aip.hash
module exposes functions for various hashing algorithms and encodings.
Functions Summary
aip.hash.sha256(input: string): string
aip.hash.sha256_b58(input: string): string
aip.hash.sha256_b64(input: string): string
aip.hash.sha256_b64u(input: string): string
aip.hash.sha512(input: string): string
aip.hash.sha512_b58(input: string): string
aip.hash.sha512_b64(input: string): string
aip.hash.sha512_b64u(input: string): string
aip.hash.blake3(input: string): string
aip.hash.blake3_b58(input: string): string
aip.hash.blake3_b64(input: string): string
aip.hash.blake3_b64u(input: string): string
aip.hash.sha256
Computes the SHA256 hash of the input string and returns it as a lowercase hex-encoded string.
-- API Signature
aip.hash.sha256(input: string): string
Arguments
input: string
: The string to hash.
Returns
string
: The SHA256 hash, hex-encoded.
Example
local hex_hash = aip.hash.sha256("hello world")
-- hex_hash will be "b94d27b9934d3e08a52e52d7da7dabfac484efe37a5380ee9088f7ace2efcde9"
print(hex_hash)
Error
This function does not typically error if the input is a string.
aip.hash.sha256_b58
Computes the SHA256 hash of the input string and returns it as a Base58-encoded string.
-- API Signature
aip.hash.sha256_b58(input: string): string
Arguments
input: string
: The string to hash.
Returns
string
: The SHA256 hash, Base58-encoded.
Example
local b58_hash = aip.hash.sha256_b58("hello world")
-- b58_hash will be "CnKqR4x6r4nAv2iGk8DrZSSWp7n3W9xKRj69eZysS272"
print(b58_hash)
Error
This function does not typically error if the input is a string.
aip.hash.sha256_b64
Computes the SHA256 hash of the input string and returns it as a standard Base64-encoded string (RFC 4648).
-- API Signature
aip.hash.sha256_b64(input: string): string
Arguments
input: string
: The string to hash.
Returns
string
: The SHA256 hash, standard Base64-encoded.
Example
local b64_hash = aip.hash.sha256_b64("hello world")
-- b64_hash will be "uU0nuZNNPgilLlLX2n2r+sSE7+N6U4DukIj3rOLvzek="
print(b64_hash)
Error
This function does not typically error if the input is a string.
aip.hash.sha256_b64u
Computes the SHA256 hash of the input string and returns it as a URL-safe Base64-encoded string (RFC 4648, section 5), without padding.
-- API Signature
aip.hash.sha256_b64u(input: string): string
Arguments
input: string
: The string to hash.
Returns
string
: The SHA256 hash, URL-safe Base64-encoded without padding.
Example
local b64u_hash = aip.hash.sha256_b64u("hello world")
-- b64u_hash will be "uU0nuZNNPgilLlLX2n2r-sSE7-N6U4DukIj3rOLvzek"
print(b64u_hash)
Error
This function does not typically error if the input is a string.
aip.hash.sha512
Computes the SHA512 hash of the input string and returns it as a lowercase hex-encoded string.
-- API Signature
aip.hash.sha512(input: string): string
Arguments
input: string
: The string to hash.
Returns
string
: The SHA512 hash, hex-encoded.
Example
local hex_hash = aip.hash.sha512("hello world")
-- hex_hash will be "309ecc489c12d6eb4cc40f50c902f2b4d0ed77ee511a7c7a9bcd3ca86d4cd86f989dd35bc5ff499670da34255b45b0cfd830e81f605dcf7dc5542e93ae9cd76f"
print(hex_hash)
Error
This function does not typically error if the input is a string.
aip.hash.sha512_b58
Computes the SHA512 hash of the input string and returns it as a Base58-encoded string.
-- API Signature
aip.hash.sha512_b58(input: string): string
Arguments
input: string
: The string to hash.
Returns
string
: The SHA512 hash, Base58-encoded.
Example
local b58_hash = aip.hash.sha512_b58("hello world")
-- b58_hash will be "yP4cqy7jmaRDzC2bmcGNZkuQb3VdftMk6YH7ynQ2Qw4zktKsyA9fk52xghNQNAdkpF9iFmFkKh2bNVG4kDWhsok"
print(b58_hash)
Error
This function does not typically error if the input is a string.
aip.hash.sha512_b64
Computes the SHA512 hash of the input string and returns it as a standard Base64-encoded string (RFC 4648).
-- API Signature
aip.hash.sha512_b64(input: string): string
Arguments
input: string
: The string to hash.
Returns
string
: The SHA512 hash, standard Base64-encoded.
Example
local b64_hash = aip.hash.sha512_b64("hello world")
-- b64_hash will be "MJ7MSJwS1utMxA9QyQLytNDtd+5RGnx6m808qG1M2G+YndNbxf9JlnDaNCVbRbDP2DDoH2Bdz33FVC6TrpzXbw=="
print(b64_hash)
Error
This function does not typically error if the input is a string.
aip.hash.sha512_b64u
Computes the SHA512 hash of the input string and returns it as a URL-safe Base64-encoded string (RFC 4648, section 5), without padding.
-- API Signature
aip.hash.sha512_b64u(input: string): string
Arguments
input: string
: The string to hash.
Returns
string
: The SHA512 hash, URL-safe Base64-encoded without padding.
Example
local b64u_hash = aip.hash.sha512_b64u("hello world")
-- b64u_hash will be "MJ7MSJwS1utMxA9QyQLytNDtd-5RGnx6m808qG1M2G-YndNbxf9JlnDaNCVbRbDP2DDoH2Bdz33FVC6TrpzXbw"
print(b64u_hash)
Error
This function does not typically error if the input is a string.
aip.hash.blake3
Computes the Blake3 hash of the input string and returns it as a lowercase hex-encoded string.
-- API Signature
aip.hash.blake3(input: string): string
Arguments
input: string
: The string to hash.
Returns
string
: The Blake3 hash, hex-encoded.
Example
local hex_hash = aip.hash.blake3("hello world")
-- hex_hash will be "d74981efa70a0c880b8d8c1985d075dbcbf679b99a5f9914e5aaf96b831a9e24"
print(hex_hash)
Error
This function does not typically error if the input is a string.
aip.hash.blake3_b58
Computes the Blake3 hash of the input string and returns it as a Base58-encoded string.
-- API Signature
aip.hash.blake3_b58(input: string): string
Arguments
input: string
: The string to hash.
Returns
string
: The Blake3 hash, Base58-encoded.
Example
local b58_hash = aip.hash.blake3_b58("hello world")
-- b58_hash will be "FVPfbg9bK7mj7jnaSRXhuVcVakkXcjMPgSwxmauUofYf"
print(b58_hash)
Error
This function does not typically error if the input is a string.
aip.hash.blake3_b64
Computes the Blake3 hash of the input string and returns it as a standard Base64-encoded string (RFC 4648).
-- API Signature
aip.hash.blake3_b64(input: string): string
Arguments
input: string
: The string to hash.
Returns
string
: The Blake3 hash, standard Base64-encoded.
Example
local b64_hash = aip.hash.blake3_b64("hello world")
-- b64_hash will be "10mB76cKDIgLjYwZhdB128v2ebmaX5kU5ar5a4ManiQ="
print(b64_hash)
Error
This function does not typically error if the input is a string.
aip.hash.blake3_b64u
Computes the Blake3 hash of the input string and returns it as a URL-safe Base64-encoded string (RFC 4648, section 5), without padding.
-- API Signature
aip.hash.blake3_b64u(input: string): string
Arguments
input: string
: The string to hash.
Returns
string
: The Blake3 hash, URL-safe Base64-encoded without padding.
Example
local b64u_hash = aip.hash.blake3_b64u("hello world")
-- b64u_hash will be "10mB76cKDIgLjYwZhdB128v2ebmaX5kU5ar5a4ManiQ"
print(b64u_hash)
Error
This function does not typically error if the input is a string.
aip.hbs
Functions for rendering Handlebars templates.
Functions Summary
aip.hbs.render(content: string, data: any): string | {error: string}
aip.hbs.render
Renders a Handlebars template string with Lua data.
-- API Signature
aip.hbs.render(content: string, data: any): string | {error: string}
Converts Lua data
to JSON internally and renders the Handlebars content
template.
Arguments
content: string
: The Handlebars template string.data: any
: The data as a Lua value (table, number, string, boolean, nil). Note that function types or userdata are not supported.
Returns
string
: The rendered template string on success.{error: string}
: An error table on failure (data conversion or template rendering).
Example
local template = "Hello, !"
local data = {name = "World"}
local rendered_content = aip.hbs.render(template, data)
print(rendered_content) -- Output: Hello, World!
local data_list = {
name = "Jen Donavan",
todos = {"Bug Triage AIPACK", "Fix Windows Support"}
}
local template_list = [[
Hello ,
Your tasks today:
Have a good day (after you completed this tasks)
]]
local content_list = aip.hbs.render(template_list, data_list)
print(content_list)
Error
Returns an error (Lua table { error: string }
) if Lua data cannot be converted to JSON or if Handlebars rendering fails.
aip.code
Utility functions for code formatting and manipulation.
Functions Summary
aip.code.comment_line(lang_ext: string, comment_content: string): string | {error: string}
aip.code.comment_line
Creates a single comment line appropriate for a given language extension.
-- API Signature
aip.code.comment_line(lang_ext: string, comment_content: string): string | {error: string}
Formats comment_content
as a single-line comment based on lang_ext
.
Arguments
lang_ext: string
: File extension or language identifier (e.g., "rs", "lua", "py", "js", "css", "html"). Case-insensitive.comment_content: string
: The text to put inside the comment.
Returns
string
: The formatted comment line (without trailing newline) on success.{error: string}
: An error table on failure.
Example
print(aip.code.comment_line("rs", "TODO: Refactor")) -- Output: // TODO: Refactor
print(aip.code.comment_line("py", "Add validation")) -- Output: # Add validation
print(aip.code.comment_line("lua", "Fix this later")) -- Output: -- Fix this later
print(aip.code.comment_line("html", "Main content")) -- Output: <!-- Main content -->
Error
Returns an error (Lua table { error: string }
) on conversion or formatting issues.
Common Types
Common data structures returned by or used in API functions.
FileRecord
Represents a file with its metadata and content. Returned by aip.file.load
and aip.file.list_load
.
{
path : string, // Relative or absolute path used to load/find the file
dir: string, // Parent directory of the path (empty if no parent)
name : string, // File name with extension (e.g., "main.rs")
stem : string, // File name without extension (e.g., "main")
ext : string, // File extension (e.g., "rs")
ctime?: number, // Creation timestamp (microseconds since epoch), optional
ctime?: number, // Modification timestamp (microseconds), optional
size?: number, // File size in bytes, optional
content: string // The text content of the file
}
FileInfo
Represents file metadata without content. Returned by aip.file.list
, aip.file.first
, aip.file.ensure_exists
, aip.file.save_html_to_md
, and aip.file.save_html_to_slim
.
{
path : string, // Relative or absolute path
dir: string, // Parent directory of the path
name : string, // File name with extension
stem : string, // File name without extension
ext : string, // File extension
ctime?: number, // Creation timestamp (microseconds), optional (if with_meta=true for list)
mtime?: number, // Modification timestamp (microseconds), optional (if with_meta=true for list)
size?: number // File size in bytes, optional (if with_meta=true for list)
}
FileStats
Aggregated statistics for a collection of files. Returned by aip.file.stats
.
{
total_size: number, // Total size of all matched files in bytes
number_of_files: number, // Number of files matched
ctime_first: number, // Creation timestamp of the oldest file (microseconds since epoch)
ctime_last: number, // Creation timestamp of the newest file (microseconds since epoch)
mtime_first: number, // Modification timestamp of the oldest file (microseconds since epoch)
mtime_last: number // Modification timestamp of the newest file (microseconds since epoch)
}
DestOptions
Options table used for specifying the destination path in functions like aip.file.save_html_to_md
and aip.file.save_html_to_slim
.
{
base_dir?: string, // Base directory for resolving the destination
file_name?: string, // Custom file name for the output
suffix?: string // Suffix appended to the source file stem
}
MdSection
Represents a section of a Markdown document, potentially associated with a heading. Returned by aip.file.load_md_sections
and aip.file.load_md_split_first
.
{
content: string, // Full content of the section (including heading line and sub-sections)
heading?: { // Present if the section starts with a heading
content: string, // The raw heading line (e.g., "## Section Title")
level: number, // Heading level (1-6)
name: string // Extracted heading name (e.g., "Section Title")
}
}
MdBlock
Represents a fenced block (usually code) in Markdown. Returned by aip.md.extract_blocks
.
{
content: string, // Content inside the block (excluding fence lines)
lang?: string, // Language identifier (e.g., "rust", "lua"), optional
info: string // Full info string from the opening fence (e.g., "rust file:main.rs"), optional
}
WebResponse
Represents the result of an HTTP request made by aip.web.get
or aip.web.post
.
{
success: boolean, // true if HTTP status code is 2xx, false otherwise
status: number, // HTTP status code (e.g., 200, 404, 500)
url: string, // The final URL requested (after redirects)
content: string | table, // Response body. Decoded to a Lua table if Content-Type is application/json, otherwise a string.
error?: string // Error message if success is false or if request initiation failed
}
CmdResponse
Represents the result of executing a system command via aip.cmd.exec
.
{
stdout: string, // Standard output captured from the command
stderr: string, // Standard error captured from the command
exit: number // Exit code returned by the command (0 usually indicates success)
}
AgentOptions
Configuration options for an agent. Used in aip.flow.before_all_response
and aip.flow.data_response
to override settings for a run or a specific cycle.
{
model?: string,
temperature?: number,
top_p?: number,
input_concurrency?: number,
model_aliases?: { [key: string]: string }
}
CTX
All Lua scripts get the CTX
table in scope, providing context about the current execution environment.
Key | Example Value | Description |
---|---|---|
CTX.WORKSPACE_DIR | /Users/dev/my-project |
Absolute path to the workspace directory (containing .aipack/ ). |
CTX.WORKSPACE_AIPACK_DIR | /Users/dev/my-project/.aipack |
Absolute path to the .aipack/ directory in the workspace. |
CTX.BASE_AIPACK_DIR | /Users/dev/.aipack-base |
Absolute path to the user's base AIPACK directory. |
CTX.AGENT_NAME | my_pack/my-agent or path/to/my-agent.aip |
The name or path used to invoke the agent. |
CTX.AGENT_FILE_PATH | /Users/home/john/.aipack-base/pack/installed/acme/my_pack/my-agent.aip |
Absolute path to the resolved agent .aip file. |
CTX.AGENT_FILE_DIR | /Users/home/john/.aipack-base/pack/installed/acme/my_pack |
Absolute path to the directory containing the agent file. |
CTX.AGENT_FILE_NAME | my-agent.aip |
The base name of the my-agent file. |
CTX.AGENT_FILE_STEM | my-agent |
The base name of the agent file without extension. |
CTX.TMP_DIR | .aipack/.session/0196adbf-b792-7070-a5be-eec26698c065/tmp |
The tmp dir for this session (all redos in same session) |
CTX.SESSION_UID | 0196adbf-b792-7070-a5be-eec26698c065 |
The Session Unique ID for this CLI Session |
CTX.RUN_UID | 0196adbf-b792-7070-a5be-ddc33698c065 |
The Run Unique ID |
CTX.TASK_UID | 0196adbf-b792-7070-a5be-aac55698c065 |
The Task Unique ID (when in a task stage) |
When running a pack. (when no packs, those will be all nil)
For aip run acme@my_pack/my-agent
Key | Example Value | Description |
---|---|---|
CTX.PACK_IDENTITY | acme@my_pack |
Pack identity (namespace@name) (nil if not run via pack ref). |
CTX.PACK_NAMESPACE | acme |
Namespace of the pack (nil if not run via pack reference). |
CTX.PACK_NAME | my_pack |
Name of the pack (nil if not run via pack reference). |
CTX.PACK_REF | acme@my_pack/my-agent |
(Nil if not a pack) Full pack reference used (nil if not run via pack reference). |
CTX.PACK_WORKSPACE_SUPPORT_DIR | /Users/dev/my-project/.aipack/support/pack/acme/my_pack |
Workspace-specific support directory for this agent (if applicable). |
CTX.PACK_BASE_SUPPORT_DIR | /Users/home/john/.aipack-base/support/pack/acme/my_pack |
Base support directory for this agent (if applicable). |
- All paths are absolute and normalized for the OS.
CTX.PACK...
fields arenil
if the agent was invoked directly via its file path rather than a pack reference (e.g.,aip run my-agent.aip
).- The
AGENT_NAME
reflects how the agent was called, whileAGENT_FILE_PATH
is the fully resolved location.