Module Reference

46+ built-in modules, zero dependencies. Use assay context <query> for LLM-ready docs on any module.

assay modules                    # list all modules
assay context "grafana health"   # get detailed docs for LLM

Rust Builtins

Available globally in all .lua scripts — no require needed.

HTTP & Networking

Module Key Functions Description
http http.get/post/put/patch/delete/serve HTTP client, server, and SSE streaming
ws ws.connect/send/recv/close WebSocket client

SSE Streaming Example

http.serve(8080, {
  GET = {
    ["/events"] = function(req)
      return {
        sse = function(send)
          send({ data = "connected" })
          sleep(1)
          send({ event = "update", data = json.encode({count = 1}), id = "1" })
          -- stream closes when function returns
        end
      }
    end
  }
})

The send callback accepts event, data, id, and retry fields. SSE headers (text/event-stream, no-cache, keep-alive) are set automatically.

Serialization

Module Key Functions Description
json json.parse/encode JSON parse and encode
yaml yaml.parse/encode YAML parse and encode
toml toml.parse/encode TOML parse and encode
base64 base64.encode/decode Base64 encoding

System

Module Key Functions Description
fs fs.read/write Filesystem operations
env env.get Environment variables
sleep sleep(n) Pause execution
time time() Unix timestamp

Cryptography

Module Key Functions Description
crypto crypto.jwt_sign/hash/hmac/random JWT, hashing, HMAC
regex regex.match/find/replace Regular expressions

Database

Module Key Functions Description
db db.connect/query/execute/close SQL — Postgres, MySQL, SQLite

Templates & Async

Module Key Functions Description
template template.render/render_string Jinja2-compatible templates
async async.spawn/spawn_interval Async task execution

Testing & Logging

Module Key Functions Description
assert assert.eq/ne/gt/lt/contains/not_nil/matches Assertions
log log.info/warn/error Structured logging

Stdlib Modules

29 embedded Lua modules loaded via require("assay.<name>"). All follow the client pattern: M.client(url, opts) → client object → c:method().

Monitoring & Observability

Module require() Description Client Pattern
assay.prometheus require("assay.prometheus") PromQL queries, alerts, targets prom.query(url, expr)
assay.alertmanager require("assay.alertmanager") Alert management, silences am.client(url)
assay.loki require("assay.loki") Log push, query, labels loki.client(url)
assay.grafana require("assay.grafana") Health, dashboards, datasources gf.client(url, opts)

Kubernetes & GitOps

Module require() Description Client Pattern
assay.k8s require("assay.k8s") 30+ K8s resource types, CRDs k8s.client(url, opts)
assay.argocd require("assay.argocd") Apps, sync, health, projects argo.client(url, opts)
assay.kargo require("assay.kargo") Stages, freight, promotions kargo.client(url, opts)
assay.flux require("assay.flux") GitRepositories, Kustomizations flux.client(url, opts)
assay.traefik require("assay.traefik") Routers, services, middlewares traefik.client(url)

Security & Identity

Module require() Description Client Pattern
assay.vault require("assay.vault") KV secrets, transit, PKI vault.client(url, opts)
assay.openbao require("assay.openbao") OpenBao (Vault API-compatible) bao.client(url, opts)
assay.certmanager require("assay.certmanager") Certificates, issuers, ACME cm.client(url, opts)
assay.eso require("assay.eso") ExternalSecrets, SecretStores eso.client(url, opts)
assay.dex require("assay.dex") OIDC discovery, JWKS, health dex.client(url)
assay.zitadel require("assay.zitadel") OIDC identity, JWT machine auth zitadel.client(url, opts)

Infrastructure

Module require() Description Client Pattern
assay.crossplane require("assay.crossplane") Providers, XRDs, compositions xp.client(url, opts)
assay.velero require("assay.velero") Backups, restores, schedules velero.client(url, opts)
assay.temporal require("assay.temporal") Workflows, task queues temporal.client(url, opts)
assay.harbor require("assay.harbor") Projects, repos, vulnerability scanning harbor.client(url, opts)

Data & Storage

Module require() Description Client Pattern
assay.postgres require("assay.postgres") PostgreSQL user/db management pg.client(url, opts)
assay.s3 require("assay.s3") S3-compatible storage, Sig V4 s3.client(url, opts)

Utilities

Module require() Description Client Pattern
assay.healthcheck require("assay.healthcheck") HTTP checks, JSON path, latency hc.check(url, opts)
assay.unleash require("assay.unleash") Feature flags, environments unleash.client(url, opts)

AI Agent & Workflow

Integrate with AI agent platforms, GitHub, Gmail, and Google Calendar — all via native HTTP, zero shell dependencies.

assay.openclaw

OpenClaw AI agent platform integration. Invoke tools, send messages, manage state, spawn sub-agents, approval gates, LLM tasks.

local openclaw = require("assay.openclaw")
local c = openclaw.client()  -- auto-discovers $OPENCLAW_URL + $OPENCLAW_TOKEN

-- Invoke any OpenClaw tool
local result = c:invoke("message", "send", { target = "#general", message = "Hello!" })

-- Shorthand: send message
c:send("discord", "#alerts", "Service is down!")
c:notify("ops-team", "Deployment complete")

-- Persistent state
c:state_set("last-deploy", { version = "1.2.3", time = time() })
local prev = c:state_get("last-deploy")

-- Diff detection
local diff = c:diff("pr-state", new_snapshot)
if diff.changed then log.info("State changed!") end

-- LLM task
local answer = c:llm_task("Summarize this PR", { model = "claude-sonnet" })

-- Cron jobs
c:cron_add({ schedule = "0 9 * * *", task = "daily-report" })

-- Sub-agents
c:spawn("Fix the login bug", { model = "gpt-4o" })

assay.github

GitHub REST API client. PRs, issues, actions, repositories, GraphQL. No gh CLI dependency.

local github = require("assay.github")
local c = github.client()  -- uses $GITHUB_TOKEN

-- Pull requests
local pr = c:pr_view("owner/repo", 123)
local prs = c:pr_list("owner/repo", { state = "open" })
local reviews = c:pr_reviews("owner/repo", 123)
c:pr_merge("owner/repo", 123, { merge_method = "squash" })

-- Issues
local issues = c:issue_list("owner/repo", { labels = "bug", state = "open" })
local issue = c:issue_get("owner/repo", 42)
c:issue_create("owner/repo", "Bug title", "Description", { labels = {"bug"} })
c:issue_comment("owner/repo", 42, "Fixed in PR #123")

-- Actions
local runs = c:runs_list("owner/repo", { status = "completed" })
local run = c:run_get("owner/repo", 12345)

-- GraphQL
local data = c:graphql("query { viewer { login } }")

assay.gmail

Gmail REST API with OAuth2 token auto-refresh. Search, read, reply, send emails.

local gmail = require("assay.gmail")
local c = gmail.client({
  credentials_file = "/path/to/credentials.json",
  token_file = "/path/to/token.json",
})

-- Search emails
local emails = c:search("newer_than:1d is:unread", { max = 20 })

-- Read a message
local msg = c:get("message-id-here")

-- Reply to an email
c:reply("message-id", { body = "Thanks for the update!" })

-- Send new email
c:send("user@example.com", "Subject", "Email body")

-- List labels
local labels = c:labels()

assay.gcal

Google Calendar REST API with OAuth2 token auto-refresh. Events CRUD, calendar list.

local gcal = require("assay.gcal")
local c = gcal.client({
  credentials_file = "/path/to/credentials.json",
  token_file = "/path/to/token.json",
})

-- List upcoming events
local events = c:events({ timeMin = "2026-04-05T00:00:00Z", maxResults = 10 })

-- Get specific event
local event = c:event_get("event-id")

-- Create event
c:event_create({
  summary = "Team standup",
  start = { dateTime = "2026-04-06T09:00:00Z" },
  ["end"] = { dateTime = "2026-04-06T09:30:00Z" },
})

-- Update / delete
c:event_update("event-id", updated_event)
c:event_delete("event-id")

-- List all calendars
local calendars = c:calendars()

assay.oauth2

Google OAuth2 token management. File-based credentials loading, automatic access token refresh, token persistence.

local oauth2 = require("assay.oauth2")

-- Load credentials and token from default paths
-- (~/.config/gog/credentials.json and ~/.config/gog/token.json)
local auth = oauth2.from_file()

-- Or specify custom paths
local auth = oauth2.from_file("/path/to/credentials.json", "/path/to/token.json")

-- Refresh access token
auth:refresh()

-- Persist updated token back to file
auth:save()

-- Get auth headers for API calls
local headers = auth:headers()
-- Returns: {Authorization = "Bearer ...", ["Content-Type"] = "application/json"}

-- Use with http builtins
local resp = http.get("https://www.googleapis.com/calendar/v3/calendars/primary/events", {
  headers = auth:headers()
})

assay.email_triage

Email classification and triage. Deterministic rule-based categorization or OpenClaw LLM-assisted classification into action, reply, and FYI buckets.

local email_triage = require("assay.email_triage")
local gmail = require("assay.gmail")

local gc = gmail.client({
  credentials_file = "/path/to/credentials.json",
  token_file = "/path/to/token.json",
})

-- Fetch recent emails
local emails = gc:search("newer_than:1d", { max = 50 })

-- Deterministic categorization (no LLM needed)
local buckets = email_triage.categorize(emails)
log.info("Needs reply: " .. #buckets.needs_reply)
log.info("Needs action: " .. #buckets.needs_action)
log.info("FYI: " .. #buckets.fyi)

-- LLM-assisted triage via OpenClaw (smarter classification)
local openclaw = require("assay.openclaw")
local oc = openclaw.client()
local smart_buckets = email_triage.categorize_llm(emails, oc)
Module require() Description Client Pattern
assay.openclaw require("assay.openclaw") AI agent tools, state, approve, LLM openclaw.client(url?, opts?)
assay.github require("assay.github") PRs, issues, actions, GraphQL github.client(opts?)
assay.gmail require("assay.gmail") Email search, read, reply, send gmail.client(opts)
assay.gcal require("assay.gcal") Calendar events CRUD gcal.client(opts)
assay.oauth2 require("assay.oauth2") OAuth2 token management, auto-refresh oauth2.from_file(creds?, token?)
assay.email_triage require("assay.email_triage") Email classification, triage buckets email_triage.categorize(emails)

Custom Modules

Place .lua files in ./modules/ (project-local) or ~/.assay/modules/ (global). Or set ASSAY_MODULES_PATH to override the global directory. They are auto-discovered and appear in assay modules output.

./modules/
  myapi.lua        # require("assay.myapi")
~/.assay/modules/
  company.lua      # require("assay.company")

For LLM agents: llms.txt · llms-full.txt