BoxLang 🚀 A New JVM Dynamic Language Learn More...

BxAgents

v1.0.0-snapshot BoxLang Modules

⚡︎ BxAgents

|:------------------------------------------------------:  |
| ⚡︎ B x A g e n t s ⚡︎
| Build AI Agents by Convention
|:------------------------------------------------------:  |
Copyright Since 2023 by Ortus Solutions, Corp
www.boxlang.io | www.ortussolutions.com

 

BxAgents is a conventions-based framework for building AI agents powered by BoxLang AI. Built on top of ColdBox, it lets you describe an agent with a handful of files and folders - Agent.bx, instructions.md, and whichever of tools/, skills/, subagents/, gateways/, schedules/, mcp/, interceptors/, models/, modules/ it actually needs - and BxAgents assembles a real, runnable ColdBox application from it at build time, ready to serve, chat with, or package as a portable .bxa.

Quick Start

install-bx-module bx-ai bx-agents      # see docs/getting-started/installation.md

bxAgents new my-agent --model=openai/gpt-5
cd my-agent
# edit instructions.md, add tools/, skills/, etc.

bxAgents build      # assembles a real ColdBox app under .build/app
bxAgents doctor     # sanity-check the runtime + your project before build/serve surprise you
bxAgents chat       # or: bxAgents serve --port=8080

new doesn't only scaffold a blank agent: pick one of 8 built-in --templates (a Slack bot, a scheduled agent, a multi-agent team, ...), clone an existing GitHub repo (--repo=owner/repo, via a bundled JGit client - no git binary required), or install a ForgeBox package (--forgebox=<slug>, talking to ForgeBox's REST API directly - no box CLI required) - see Agent Templates.

Documentation & Examples

  • docs/ - installation, quick start, one page per convention folder, agent templates (built-in starters, GitHub/ForgeBox sourcing, publishing your own), the build pipeline, the manifest schema, the full CLI reference, deployment/secrets, and known limitations. Published at bxagents.ai, built with bx-sites; see Working on the docs.
  • examples/ - real, buildable sample projects: nine core-convention examples (a minimal agent, a simple agent, a class-based agent, an HTTP-exposed agent, a scheduled agent, an MCP agent, a multi-agent team, the web chat UI, and a composite "advanced" agent) plus one per push-style chat-platform gateway (Telegram, Slack, Discord, Email, WhatsApp Cloud, Teams, Twilio, GitHub, Signal), each demonstrating one convention folder end-to-end.

Why build-time assembly?

Most agent frameworks wire tools, skills, routes, and schedules together at request time, on every boot. BxAgents does the opposite: bxAgents build runs discovery, validation, and code generation exactly once, producing a plain ColdBox application. Booting that application - via bxAgents serve, a real boxlang-miniserver process, or a packaged .bxa deployed anywhere BoxLang runs - is then just booting an ordinary app, deterministically and fast.


Contributing to BxAgents

The rest of this readme covers developing BxAgents itself (this repo), not building an agent with it - see docs/ for that. See CONTRIBUTING.md for the actual edit/test loop - BoxLang is a dynamic language, so it isn't the usual edit-compile-run cycle, and there's a real subtlety around how this module's own classes reference each other that's worth reading before you touch src/main/bx.

Directory Structure

  • .github/workflows - GitHub Actions to test and build the module via CI
  • docs/ - GitBook-style user documentation
  • examples/ - working sample agent projects, built as a CI regression gate (./gradlew verifyExamples)
  • src/main/bx - the BoxLang source: ModuleConfig.bx (CLI entry point), models/build (the build pipeline: config resolution, discovery, validation, manifest, and code generators), models/cli (one class per CLI verb)
  • src/main/java - supporting Java (packager, miniserver launcher, dynamic class loader, key dictionary)
  • src/test - JUnit (Java-level) tests and fixtures
  • tests/ - the TestBox BDD suite (tests/specs), including the ColdBox-dependent integration specs under tests/specs/integration/coldbox
  • box.json - published to ForgeBox; also declares the bxAgents native CLI executable
  • build.gradle - the Gradle build file, including every verification task below

Gradle Tasks

Before you get started, fetch the BoxLang binary (until this module is published to Maven):

./gradlew downloadBoxLang
./gradlew downloadModules        # bx-ai + bx-ftp + bx-sqlite, needed by the TestBox suite
./gradlew downloadMiniServer     # boxlang-miniserver, needed by the ColdBox integration suite
Task Description
build The default lifecycle task: clean, assemble, and others.
clean Deletes the build folder.
compileJava Compiles Java source in src/main/java.
test Runs the JUnit suite.
testBx Runs the TestBox BDD suite (tests/specs, excluding the ColdBox-dependent bundle) via runTests.bxs. Requires testbox/ (box install).
testColdBoxIntegration Boots a real boxlang-miniserver against a generated app and hits a toAi() route over real HTTP, via runColdBoxIntegrationTests.bxs. Requires tests/coldbox/ (box install in tests/) and the miniserver jar.
verifyExamples Builds every project under examples/ through the real build pipeline via verifyExamples.bxs - a regression net across the whole feature matrix.
checkTemplateTokens Fails if any leftover @MODULE_*@ boxlang-module-template placeholder tokens remain anywhere in the repo. Runs as part of check.
downloadBoxLang Downloads the BoxLang binary into src/test/resources/libs.
downloadModules Downloads supporting BoxLang modules (bx-ai, bx-ftp, bx-sqlite) into src/test/resources/modules.
downloadMiniServer Downloads the boxlang-miniserver binary into src/test/resources/libs.
jar / shadowJar Packages compiled classes/resources into a JAR under build/libs.
javadoc Generates Javadocs into build/docs/javadoc.
spotlessApply / spotlessCheck Formats / checks code formatting.
tasks Lists every available Gradle task.

Run the full local verification pass with:

./gradlew shadowJar checkTemplateTokens test testBx testColdBoxIntegration verifyExamples

VSCode Tests

If running tests via the VSCode test explorer, remove the /src/main/resources classpath entry first (Java Projects panel → the 3 dots → Configure Classpath), or BoxLang core will try loading service loaders it finds there. Module development only.

GitHub Actions Automation

CI clones, tests, packages, and deploys this module to ForgeBox and the Ortus S3 accounts. The following repository environment variables are required (most are already set at the org level):

  • FORGEBOX_API_TOKEN - the Ortus ForgeBox API token (the name release.yml actually reads)
  • AWS_ACCESS_KEY / AWS_ACCESS_SECRET - the S3 credentials

Contact #infrastructure for these credentials if needed.

Optionally, NOVITA_API_KEY (a Novita AI API key) enables one real, live LLM integration test - see tests/specs/integration/LiveLlmSpec.bx . It's genuinely optional: unset, that spec reports as cleanly "Skipped" rather than failing, so a fork PR without it still runs the rest of the suite.

Working on the docs

docs/ is a bx-sites site - plain Markdown, where the folder structure is the navigation and docs/nav.json overrides the order. bxsites.yaml at the repo root holds the site config.

# once - bx-sites depends on bx-markdown, bx-esapi, bx-yaml and bx-image;
# all four install automatically as box.json dependencies
install-bx-module bx-sites

bxSites serve     # live-reloading preview on http://127.0.0.1:8080 - saves rebuild in ~1-2s, not a full site rebuild
bxSites build     # render docs/ to site/ (gitignored)
bxSites doctor    # environment/config health check
bxSites check     # CI-grade broken-link/missing-alt gate over an already-built site/
bxSites lint      # pre-build content checks on the raw docs/ Markdown

Every page starts with a small frontmatter block (title, icon, summary, description, tags); summary renders under the page title, description is meta-only, and tags become clickable badges plus a site-wide /tags/ index. Scaffold a new one with bxSites page:new --path=guides/setup.md, or move one (rewriting every relative Markdown link that pointed at it) with bxSites page:rename --from=... --to=....

bxsites.yaml turns on generateOgImages (a distinct 1200x630 social card per page, built from its title/description, falling back to ogImage: assets/home-banner.jpg for anything the generator can't handle) and pageActions (the per-page copy/view-as-Markdown/open-in-AI-chat/PDF/share menu). sitemap.xml, robots.txt and llms.txt are generated for free once baseURL is an absolute URL, which it already is here - no extra config needed.

The Spanish translation under docs/versions/1.0.x/i18n/es/ covers page content; the surrounding theme chrome (search placeholder, "On this page," "Edit this page," the 404 page, ...) is translated automatically too - bx-sites ships built-in es/de/ja chrome translations out of the box, so nothing extra needs configuring for those locales. Note the path: a translation has to live inside the tree that actually builds at the site root (docs/versions/1.0.x/, per versions.default), not under docs/i18n/ - see CONTRIBUTING.md for why. German and Japanese are parked under translations-wip/ until they reach parity.

.github/workflows/docs.yml publishes straight to the site root (https://bxagents.ai) for whichever branch it runs on. Versioning is handled inside the docs themselves via bx-sites' own versions: support - bxsites.yaml's versions.default (1.0.x) builds at the root, and in-progress docs build under /next/.

This follows bx-sites' own documented deployment approach: the workflow builds site/ and pushes it to a gh-pages branch with keep_files: true.

The repository's Settings -> Pages -> Build and deployment -> Source must be Deploy from a branch -> gh-pages -> / (root) . The first successful run creates gh-pages, so set it after that run completes; no workflow file can set it for itself.

Do not point that setting at development (or any other source branch), and do not add a root .nojekyll to quiet a failing Jekyll build. A branch source other than gh-pages makes GitHub run its built-in Jekyll pipeline over the whole repository root - which is not a Jekyll site - and a .nojekyll would only make that pipeline succeed, publishing the raw repo over these docs.

Ortus Sponsors

BoxLang is a professional open-source project and it is completely funded by the community and Ortus Solutions, Corp. Ortus Patreons get many benefits like a cfcasts account, a FORGEBOX Pro account and so much more. If you are interested in becoming a sponsor, please visit our patronage page: https://patreon.com/ortussolutions

THE DAILY BREAD

"I am the way, and the truth, and the life; no one comes to the Father, but by me (JESUS)" Jn 14:1-12

Changelog

All notable changes to this project will be documented in this file.

The format is based on Keep a Changelog, and this project adheres to Semantic Versioning.


Unreleased

The first public release of BxAgents - a conventions-based framework for building AI agents in BoxLang, powered by BoxLang AI and built on ColdBox.

You describe an agent with a handful of files and folders; bxAgents build assembles a real, runnable ColdBox application from them at build time, ready to serve, chat with, or package as a portable .bxa.

Added

Conventions

  • Agent.bx + instructions.md as the minimum viable agent - a descriptor whose configure() returns config, or a class extending bx-ai's AiAgent that is the agent.
  • tools/ - any class with an @AITool-annotated function becomes a callable tool, with no registration step.
  • skills/<name>/SKILL.md - model-selected guidance, distinct from the always-on instructions.md.
  • subagents/<name>/ - a full nested agent per folder, built leaf-first and attached to its parent automatically, with cycle detection at build time.
  • models/ - named model configurations, referenced by name from any agent in the tree.
  • gateways/ - one entry per exposure or chat platform (see below).
  • schedules/Scheduler.bx - a real ColdBox scheduler class, passed through untouched, so the full ColdBox task DSL is available.
  • mcp/ - host a local MCP server that re-exposes a project's own tools.
  • interceptors/ - ColdBox interceptors, split by @scope into agent-scope and app-scope.
  • modules/ - additional ColdBox modules to load into the generated app.

The build pipeline

  • bxAgents build runs discovery, validation and code generation exactly once, producing a plain ColdBox application under .build/app - nothing is wired at request time.
  • Build-time validation catches duplicate agent names, subagent and module cycles, unknown model providers, unknown gateway types, missing required env-var names, path traversal in configured paths, and more, reporting every collected error rather than the first.
  • A manifest.json describing the build, with SHA-256 content hashing and line-ending normalization so a CI-built artifact can be verified against a locally-built one.

Exposing an agent

  • exposes: "agent" - an HTTP route via ColdBox's toAi(), with invoke/stream/batch sub-routes.
  • exposes: "mcp" - the project's tools as a hosted MCP server.
  • exposes: "webui" - a complete, generated web chat UI: conversation sidebar backed by a real SQLite store, token-by-token streaming with reasoning and tool-call disclosures, human-in-the-loop approvals, steer-while-streaming, compaction, server-side theming from config tokens, optional API-key gating, and optional username/password sign-in via cbauth. Plain vanilla HTML/CSS/JS - no Node, no npm, no build step.

Chat-platform gateways

Nine push-style gateways, each with inbound normalization, outbound chunking at the platform's own limit, and human-in-the-loop approval support:

  • Telegram (long-poll), Slack (Socket Mode websocket), Discord (Gateway websocket with heartbeats), Signal (SSE against a signal-cli daemon), Email (scheduled IMAP poll + SMTP send), and the webhook-driven WhatsApp Business Cloud (X-Hub-Signature-256), Microsoft Teams (Bot Framework JWT/JWKS), Twilio SMS (X-Twilio-Signature) and GitHub (@mention-gated issue/PR threads).
  • Credentials are always named by environment variable, never embedded in config or generated source.
  • A type: "http" entry's webhook surface is mounted by ColdBox's own route( "/gateways" ).toAiGateway() terminator - inbound events, the platform's URL verification handshake, the human-in-the-loop interaction endpoints, and an info route - instead of hand-written routes into a generated passthrough handler. The interaction endpoints now live under the /gateways base path.

CLI

Eleven verbs: new, build, test, serve, chat, invoke, package, deploy, inspect, hash-password and clean, shipped as a native bxAgents executable.

Packaging and deployment

  • bxAgents package produces a deterministic .bxa archive (byte-identical across repeated builds), with a .sha256, a redacted manifest, an always-on exclusion of dotfiles/.env, and an optional .bxaignore.
  • Six deploy targets: local, ssh, docker, ftp, sftp and digitalocean.

Testing

  • BaseAgentSpec - a TestBox base spec that builds a project into a temp copy, mocks model responses, and adds agent-aware matchers including tool-call assertions.

Documentation

  • A full documentation site at bxagents.ai: installation, quick start, a tutorial course, one page per convention, per-platform gateway pages, example-agent guides, the build pipeline, the manifest schema, the CLI reference, deployment and secrets, and an honest known-limitations page.
  • 18 real, buildable example projects under examples/, built in CI as a regression gate.

Security

  • The web UI's /pending and /resume actions now authorize the caller against the userId the agent checkpointed, rather than acting on any supplied threadId.
  • bxAgents serve binds to 127.0.0.1 by default; --host=0.0.0.0 is an explicit opt-in.
  • A deploy entry may only name an environment variable in the BXAGENTS_ namespace for its password/passphrase, so a config file cannot cause an unrelated secret to be read out of the environment and sent to a remote host.
  • Configured paths are rejected when absolute or containing .. segments, matched on whole path segments.

$ box install bx-agents

No collaborators yet.
     
  • {{ getFullDate("2026-08-19T16:16:49Z") }}
  • {{ getFullDate("2026-09-17T17:21:48Z") }}
  • 296
  • 102