BoxLang ๐Ÿš€ A New JVM Dynamic Language Learn More...

BoxLang AI

v2.0.0+5 BoxLang Modules

โšก๏ธŽ BoxLang AI

|:------------------------------------------------------:  |
| โšก๏ธŽ B o x L a n g โšก๏ธŽ
| Dynamic : Modular : Productive
|:------------------------------------------------------:  |
Copyright Since 2023 by Ortus Solutions, Corp
ai.boxlang.io | www.boxlang.io
ai.ortussolutions.com | www.ortussolutions.com

ย 

๐Ÿ‘‹ Welcome

BoxLang AI Module

Welcome to the BoxLang AI Module ๐Ÿš€ The official AI library for BoxLang that provides a unified, fluent API to orchestrate multi-model workflows, autonomous agents, RAG pipelines, and AI-powered applications. One API โ†’ Unlimited AI Power! โœจ

BoxLang AI eliminates vendor lock-in and simplifies AI integration by providing a single, consistent interface across 12+ AI providers. Whether you're using OpenAI, Claude, Gemini, Grok, DeepSeek, Ollama, or Perplexityโ€”your code stays the same. Switch providers, combine models, and orchestrate complex workflows with simple configuration changes. ๐Ÿ”„

โœจ Key Features

  • ๐Ÿ”Œ 12+ AI Providers - Single API for OpenAI, Claude, Gemini, Grok, Ollama, DeepSeek, and more
  • ๐Ÿค– AI Agents - Autonomous agents with memory, tools, sub-agents, and multi-step reasoning
  • ๐Ÿ”’ Multi-Tenant Memory - Enterprise-grade isolation with 20+ memory types (standard + vector)
  • ๐Ÿงฌ Vector Memory & RAG - 10+ vector databases with semantic search (ChromaDB, Pinecone, PostgreSQL, etc.)
  • ๐Ÿ“š Document Loaders - 30+ file formats including PDF, Word, CSV, JSON, XML, web scraping, and databases
  • ๐Ÿ› ๏ธ Real-Time Tools - Function calling for APIs, databases, and external system integration
  • ๐ŸŒŠ Streaming Support - Real-time token streaming through pipelines for responsive applications
  • ๐Ÿ“ฆ Structured Output - Type-safe responses using BoxLang classes, structs, or JSON schemas
  • ๐Ÿ”— AI Pipelines - Composable workflows with models, transformers, and custom logic
  • ๐Ÿ“ก MCP Protocol - Build and consume Model Context Protocol servers for distributed AI
  • ๐Ÿ’ฌ Fluent Interface - Chainable, expressive syntax that makes AI integration intuitive
  • ๐Ÿฆ™ Local AI - Full Ollama support for privacy, offline use, and zero API costs
  • โšก Async Operations - Non-blocking futures for concurrent AI requests
  • ๐ŸŽฏ Event-Driven - 25+ lifecycle events for logging, monitoring, and custom workflows
  • ๐Ÿญ Production-Ready - Timeout controls, error handling, rate limiting, and debugging tools

๐Ÿ“ƒ Table of Contents

๐Ÿ“ƒ License

BoxLang is open source and licensed under the Apache 2 license. ๐ŸŽ‰ You can also get a professionally supported version with enterprise features and support via our BoxLang +/++ Plans (www.boxlang.io/plans). ๐Ÿ’ผ

๐Ÿš€ Getting Started

You can use BoxLang AI in both operating system applications, AWS Lambda, and web applications. For OS applications, you can use the module installer to install the module globally. For AWS Lambda and web applications, you can use the module installer to install it locally in your project or CommandBox as the package manager, which is our preferred method for web applications.

๐Ÿ“š New to AI concepts? Check out our Key Concepts Guide for terminology and fundamentals, or browse our FAQ for quick answers to common questions. We also have a Quick Start Guide and our intense AI BootCamp available to you as well.

OS

You can easily get started with BoxLang AI by using the module installer for building operating system applications:

install-bx-module bx-ai

This will install the latest version of the BoxLang AI module in your BoxLang environment. Once installed, make sure you setup any of the supported AI providers and their API keys in your boxlang.json configuration file or environment variables. After that you can leverage the global functions (BIFs) in your BoxLang code. Here is a simple example:

// chat.bxs
answer = aiChat( "How amazing is BoxLang?" )
println( answer )

You can then run your BoxLang script like this:

boxlang chat.bxs

AWS Lambda

In order to build AWS Lambda functions with Boxlang AI for serverless AI agents and applications, you can use the Boxlang AWS Runtime and our AWS Lambda Starter Template. You will use the install-bx-module as well to install the module locally using the --local flag in the resources folder of your project:

cd src/resources
install-bx-module bx-ai --local

Or you can use CommandBox as well and store your dependencies in the box.json descriptor.

box install bx-ai resources/modules/

Web Applications

To use BoxLang AI in your web applications, you can use CommandBox as the package manager to install the module locally in your project. You can do this by running the following command in your project root:

box install bx-ai

Just make sure you have already a server setup with BoxLang. You can check our Getting Started with BoxLang Web Applications guide for more details on how to get started with BoxLang web applications.

๐Ÿค– Supported Providers

The following are the AI providers supported by this module. Please note that in order to interact with these providers you will need to have an account with them and an API key. ๐Ÿ”‘

๐Ÿ“Š Provider Support Matrix

Here is a matrix of the providers and their feature support. Please keep checking as we will be adding more providers and features to this module. ๐Ÿ”„

Provider Real-time Tools Embeddings Structured Output
Claudeโœ…โŒโœ…
Cohereโœ…โœ…โœ…
DeepSeekโœ…โœ…โœ…
Gemini[Coming Soon]โœ…โœ…
Grokโœ…โœ…โœ…
Groqโœ…โœ…โœ…
HuggingFaceโœ…โœ…โœ…
Mistralโœ…โœ…โœ…
Ollamaโœ…โœ…โœ…
OpenAIโœ…โœ…โœ… (Native)
OpenRouterโœ…โœ…โœ…
Perplexityโœ…โŒโœ…
VoyageโŒโœ… (Specialized)โŒ

๐Ÿ“ค Return Formats

BoxLang not only makes it extremely easy to interact with multiple AI providers, but it also gives you the flexibility to choose how you want the responses returned to you. You can specify the return format using the responseFormat parameter in your AI calls. Here are the available formats:

Format Description
single Returns a single message as a string (the content from the first choice). This is the default format for BIFs.
all Returns an array of all choice messages. Each message is a struct with role and content keys.
json Returns the parsed JSON object from the content string. Automatically parses JSON responses.
xml Returns the parsed XML document from the content string. Automatically parses XML responses.
raw Returns the full raw response from the AI provider. This is useful for debugging or when you need the full response structure with metadata. This is the default for pipelines.
structuredOutput Used internally when .structuredOutput() is called. Returns a populated class/struct based on the schema.

๐ŸฅŠ Quick Overview

In the following sections, we provide a quick overview of the main components of BoxLang AI including Chats, Pipelines, Agents, Structured Output, Memory Systems, Document Loaders & RAG, and MCP Client/Server. Each section includes quick examples and links to more detailed documentation. For further details, please refer to the official documentation, this is just a high-level overview to get you started quickly. ๐Ÿš€

๐Ÿ’ฌ Chats

Interact with AI models through simple and powerful chat interfaces ๐ŸŽฏ supporting both one-shot responses and streaming conversations. BoxLang AI provides fluent APIs for building everything from basic Q&A to complex multi-turn dialogues with system prompts, message history, and structured outputs. ๐Ÿ’ก

๐Ÿค” Why Use Chats?

  • โšก Simple & Fast - One-line chat interactions with aiChat()
  • ๐Ÿ”„ Streaming Support - Real-time token streaming with aiChatStream()
  • ๐Ÿ’พ Memory Integration - Automatic conversation history with memory systems
  • ๐ŸŽจ Flexible Messages - Support for text, images, files, and structured data
  • ๐ŸŒŠ Fluent API - Chain message builders for readable, maintainable code

๐Ÿ’ก Quick Examples

Simple One-Shot Chat:

// Quick question-answer
response = aiChat( "What is BoxLang?" )
println( response )

// With custom model and options
response = aiChat(
    messages: "Explain quantum computing",
    params: { model: "gpt-4", temperature: 0.7, max_tokens: 500 }
)

Multi-Turn Conversation with Memory:

// Create agent with memory
agent = aiAgent(
    name: "Assistant",
    memory: aiMemory( "window", config: { maxMessages: 10 } )
)

// First turn
response = agent.run( "My name is Luis" )

// Second turn - Agent remembers context
response = agent.run( "What's my name?" )
println( response ) // "Your name is Luis"

Streaming Chat:

// Stream tokens as they arrive
aiChatStream(
    messages: "Write a short story about a robot",
    callback: chunk => {
        writeOutput( chunk.choices?.first()?.delta?.content ?: "" )
		bx:flush;
    },
    params: { model: "claude-3-5-sonnet-20241022" }
)

Fluent Message Builder:

// Build complex message chains
messages = aiMessage()
    .system( "You are a helpful coding assistant" )
    .user( "How do I create a REST API in BoxLang?" )
    .image( "diagram.png" )

response = aiChat(
    messages: messages,
    params: { model: "gpt-4o", temperature: 0.7 }
)

๐Ÿ“š Learn More


๐Ÿ”— Pipelines

Build composable AI workflows ๐ŸŽฏ using BoxLang AI's powerful runnable pipeline system. Chain models, transformers, tools, and custom logic into reusable, testable components that flow data through processing stages. Perfect for complex AI workflows, data transformations, and multi-step reasoning. ๐Ÿ’ก

๐Ÿค” Why Use Pipelines?

  • ๐Ÿ”„ Composable - Chain any runnable components together with .to()
  • ๐Ÿงช Testable - Each pipeline stage is independently testable
  • โ™ป๏ธ Reusable - Build once, use in multiple workflows
  • ๐ŸŒŠ Streaming - Full streaming support through entire pipeline
  • ๐ŸŽฏ Type-Safe - Input/output contracts ensure data flows correctly

๐Ÿ’ก Quick Examples

Simple Transformation Pipeline:

// Create a pipeline with model and transformers
pipeline = aiModel( provider: "openai" )
    .transform( data => data.toUpperCase() )
    .transform( data => data.trim() )

// Run input through the pipeline
result = pipeline.run( "hello world" )
println( result ) // "HELLO WORLD"

Multi-Stage AI Pipeline:

// Define transformation stages as closures
summarizer = ( text ) => {
    return aiChatAsync(
        aiMessage().system( "Summarize in one sentence" ).user( text ),
        { model: "gpt-4o-mini" }
    )
}

translator = ( summary ) => {
    return aiChatAsync(
        aiMessage().system( "Translate to Spanish" ).user( summary ),
        { model: "gpt-4o" }
    )
}

formatter = ( translatedText ) => {
    return {
        summary: translatedText,
        timestamp: now()
    }
}

// Compose pipeline using async futures
result = summarizer( "Long article text here..." )
    .then( summary => translator( summary ) )
    .then( translated => formatter( translated ) )
    .get()

println( result.summary ) // Spanish summary

Streaming Pipeline:

// Stream through entire pipeline
pipeline = aiModel( provider: "claude", params: { model: "claude-3-5-sonnet-20241022" } )
    .transform( chunk => chunk.toUpperCase() )
	.stream(
		onChunk: ( chunk ) => writeOutput( chunk ),
		input: "Tell me a story"
	)

Custom Runnable Class:

// Implement IAiRunnable for custom logic
class implements="IAiRunnable" {

    function run( input, params = {} ) {
        // Custom processing
        return processedData;
    }

    function stream( onChunk, input, params = {} ) {
        // Streaming support
        onChunk( processedChunk );
    }

    function to( nextRunnable ) {
        // Chain to next stage
        return createPipeline( this, nextRunnable );
    }
}

// Use in pipeline
customStage = new CustomRunnable()
pipeline = aiModel( provider: "openai", params: { model: "gpt-4o" } )
	.to( customStage )

๐Ÿ“š Learn More


๐Ÿค– AI Agents

Build autonomous AI agents ๐ŸŽฏ that can use tools, maintain memory, and orchestrate complex workflows. BoxLang AI agents combine LLMs with function calling, memory systems, and orchestration patterns to create intelligent assistants that can interact with external systems and solve complex tasks. ๐Ÿ’ก

๐Ÿค” Why Use Agents?

  • ๐Ÿ› ๏ธ Tool Integration - Agents can execute functions, call APIs, and interact with external systems
  • ๐Ÿง  Stateful Intelligence - Built-in memory keeps context across multi-turn interactions
  • ๐Ÿ”„ Self-Orchestration - Agents decide which tools to use and when
  • ๐ŸŽฏ Goal-Oriented - Give high-level instructions, agents figure out the steps
  • ๐Ÿค Human-in-the-Loop - Optional approval workflows for sensitive operations

๐Ÿ’ก Quick Examples

Simple Agent with Tools:

// Define tools the agent can use
weatherTool = aiTool(
    name: "get_weather",
    description: "Get current weather for a location",
    callable: ( location ) => {
        return { temp: 72, condition: "sunny", location: location };
    }
)

// Create agent with memory
agent = aiAgent(
    name: "Weather Assistant",
    description: "Helpful weather assistant",
    tools: [ weatherTool ],
    memory: aiMemory( "window" )
)

// Agent decides when to call tools
response = agent.run( "What's the weather in Miami?" )
println( response ) // Agent calls get_weather tool and responds

Autonomous Agent with Multiple Tools:

// Agent with database and email tools
agent = aiAgent(
    name: "Customer Support Agent",
    tools: [
        aiTool( name: "query_orders", description: "Query customer orders", callable: orderQueryFunction ),
        aiTool( name: "send_email", description: "Send email to customer", callable: emailFunction ),
        aiTool( name: "create_ticket", description: "Create support ticket", callable: ticketFunction )
    ],
    memory: aiMemory( "session" ),
    params: { max_iterations: 5 }
)

// Agent orchestrates multiple tool calls
agent.run( "Find order #12345, email the customer with status, and create a ticket if there's an issue" )

๐Ÿ“š Learn More


๐Ÿ“ฆ Structured Output

Get type-safe, validated responses โœ… from AI providers by defining expected output schemas using BoxLang classes, structs, or JSON schemas. The module automatically converts AI responses into properly typed objects, eliminating manual parsing and validation. ๐ŸŽฏ

๐Ÿค” Why Use Structured Output?

  • โœ… Type Safety - Get validated objects instead of parsing JSON strings
  • ๐Ÿ”’ Automatic Validation - Schema constraints ensure correct data types and required fields
  • ๐ŸŽฏ Better Reliability - Reduces hallucinations by constraining response format
  • ๐Ÿ’ป Developer Experience - Work with native BoxLang objects immediately
  • ๐Ÿงช Testing & Caching - Use aiPopulate() to create objects from JSON for tests or cached responses

๐Ÿ’ก Quick Examples

Using a Class:

class Person {
    property name="name" type="string";
    property name="age" type="numeric";
    property name="email" type="string";
}

result = aiChat(
    messages: "Extract person info: John Doe, 30, [email protected]",
    options: { returnFormat: new Person() }
)

writeOutput( "Name: #result.getName()#, Age: #result.getAge()#" );

Using a Struct Template:

template = {
    "title": "",
    "summary": "",
    "tags": [],
    "sentiment": ""
};

result = aiChat(
    messages: "Analyze this article: [long text]",
    options: { returnFormat: template }
)

writeOutput( "Tags: #result.tags.toList()#" );

Extracting Arrays:

class Task {
    property name="title" type="string";
    property name="priority" type="string";
    property name="dueDate" type="string";
}

tasks = aiChat(
    messages: "Extract tasks from: Finish report by Friday (high priority), Review code tomorrow",
    options: { returnFormat: [ new Task() ] }
)

for( task in tasks ) {
    writeOutput( "#task.getTitle()# - Priority: #task.getPriority()#<br>" );
}

Multiple Schemas (Extract Different Types Simultaneously):

result = aiChat(
    messages: "Extract person and company: John Doe, 30 works at Acme Corp, founded 2020",
    options: {
        returnFormat: {
            "person": new Person(),
            "company": new Company()
        }
    }
)

writeOutput( "Person: #result.person.getName()#<br>" );
writeOutput( "Company: #result.company.getName()#<br>" );

๐Ÿ”ง Manual Population with aiPopulate()

Convert JSON responses or cached data into typed objects without making AI calls:

// From JSON string
jsonData = '{"name":"John Doe","age":30,"email":"[email protected]"}';
person = aiPopulate( new Person(), jsonData );

// From struct
data = { name: "Jane", age: 25, email: "[email protected]" };
person = aiPopulate( new Person(), data );

// Populate array
tasksJson = '[{"title":"Task 1","priority":"high"},{"title":"Task 2","priority":"low"}]';
tasks = aiPopulate( [ new Task() ], tasksJson );

Perfect for: โญ

  • ๐Ÿงช Testing with mock data
  • ๐Ÿ’พ Using cached AI responses
  • ๐Ÿ”„ Converting existing JSON data to typed objects
  • โœ… Validating data structures

โœ… Provider Support

All providers support structured output! ๐ŸŽ‰ OpenAI offers native structured output with strict validation, while others use JSON mode with schema guidance (which works excellently in practice). ๐Ÿ’ช

๐Ÿ“š Learn More

๐Ÿง  Memory Systems

Build stateful, context-aware AI applications ๐ŸŽฏ with flexible memory systems that maintain conversation history, enable semantic search, and preserve context across interactions. BoxLang AI provides both traditional conversation memory and advanced vector-based memory for semantic understanding. ๐Ÿ’ก

๐Ÿค” Why Use Memory?

  • ๐Ÿ’ญ Context Retention - AI remembers previous messages and maintains coherent conversations
  • ๐Ÿ’ฌ Stateful Applications - Build chat interfaces that remember user preferences and conversation history
  • ๐Ÿ” Semantic Search - Find relevant past conversations using vector embeddings
  • ๐Ÿ’พ Flexible Storage - Choose from in-memory, file-based, database, session, or vector storage
  • โš™๏ธ Automatic Management - Memory handles message limits, summarization, and context windows

๐Ÿ“‹ Memory Types

Standard Memory ๐Ÿ’ฌ (Conversation History):

Type Description Best For
Windowed Keeps last N messagesQuick chats, cost-conscious apps
Summary Auto-summarizes old messagesLong conversations, context preservation
Session Web session persistenceMulti-page web applications
File File-based storageAudit trails, long-term storage
Cache CacheBox-backedDistributed applications
JDBC Database storageEnterprise apps, multi-user systems

Vector Memory ๐Ÿ” (Semantic Search):

Type Description Best For
BoxVector In-memory vectorsDevelopment, testing, small datasets
Hybrid Recent + semanticBest of both worlds approach
Chroma ChromaDB integrationPython-based infrastructure
Postgres PostgreSQL pgvectorExisting PostgreSQL deployments
MySQL MySQL 9 native vectorsExisting MySQL infrastructure
TypeSense Fast typo-tolerant searchLow-latency search, autocomplete
Pinecone Cloud vector databaseProduction, scalable semantic search
Qdrant High-performance vectorsLarge-scale deployments
Weaviate GraphQL vector databaseComplex queries, knowledge graphs
Milvus Enterprise vector DBMassive datasets, high throughput

๐Ÿ’ก Quick Examples

Windowed Memory (Multi-Tenant):

// Automatic per-user isolation
memory = aiMemory(
    memory: "window",
    key: createUUID(),
    userId: "user123",
    config: { maxMessages: 10 }
)
agent = aiAgent( name: "Assistant", memory: memory )

agent.run( "My name is John" )
agent.run( "What's my name?" )  // "Your name is John"

Summary Memory (Preserves Full Context):

memory = aiMemory( "summary", config: {
    maxMessages: 30,
    summaryThreshold: 15,
    summaryModel: "gpt-4o-mini"
} )
agent = aiAgent( name: "Support", memory: memory )
// Long conversation - older messages summarized automatically

Vector Memory (Semantic Search + Multi-Tenant):

memory = aiMemory(
    memory: "chroma",
    key: createUUID(),
    userId: "user123",
    conversationId: "support",
    config: {
        collection: "customer_support",
        embeddingProvider: "openai",
        embeddingModel: "text-embedding-3-small"
    }
)
// Retrieves semantically relevant past conversations
// Automatically filtered by userId/conversationId

Hybrid Memory (Recent + Semantic):

memory = aiMemory( "hybrid", config: {
    recentLimit: 5,       // Keep last 5 messages
    semanticLimit: 5,     // Add 5 semantic matches
    vectorProvider: "chroma"
} )
// Combines recency with relevance

๐Ÿ“š Learn More


๐Ÿ“š Document Loaders & RAG

BoxLang AI provides 12+ built-in document loaders for ingesting content from files, databases, web sources, and more. These loaders integrate seamlessly with vector memory systems to enable Retrieval-Augmented Generation (RAG) workflows.

๐Ÿ”„ RAG Workflow

graph LR
    LOAD[๐Ÿ“„ Load Documents] --> CHUNK[โœ‚๏ธ Chunk Text]
    CHUNK --> EMBED[๐Ÿงฌ Generate Embeddings]
    EMBED --> STORE[๐Ÿ’พ Store in Vector Memory]
    STORE --> QUERY[โ“ User Query]
    QUERY --> RETRIEVE[๐Ÿ” Retrieve Relevant Docs]
    RETRIEVE --> INJECT[๐Ÿ’‰ Inject into Context]
    INJECT --> AI[๐Ÿค– AI Response]

    style LOAD fill:#4A90E2
    style EMBED fill:#BD10E0
    style STORE fill:#50E3C2
    style RETRIEVE fill:#F5A623
    style AI fill:#7ED321

๐Ÿ“„ Available Loaders

Loader Type Use Case Example
๐Ÿ“ TextLoader text Plain text files.txt, .log
๐Ÿ“˜ MarkdownLoader markdown Markdown files.md documents
๐Ÿ“Š CSVLoader csv CSV filesData files, exports
๐Ÿ—‚๏ธ JSONLoader json JSON filesConfiguration, data
๐Ÿท๏ธ XMLLoader xml XML filesConfig, structured data
๐Ÿ“„ PDFLoader pdf PDF documentsReports, documentation
๐Ÿ“‹ LogLoader log Log filesApplication logs
๐ŸŒ HTTPLoader http Web pagesDocumentation, articles
๐Ÿ“ฐ FeedLoader feed RSS/Atom feedsNews, blogs
๐Ÿ’พ SQLLoader sql Database queriesQuery results
๐Ÿ“ DirectoryLoader directory File directoriesBatch processing
๐Ÿ•ท๏ธ WebCrawlerLoader webcrawler Website crawlingMulti-page docs

โœจ Quick Examples

Load a Single Document:

// Load a PDF document
docs = aiDocuments(
    source: "/path/to/document.pdf",
    config: { type: "pdf" }
).load()
println( "#docs.len()# documents loaded" )

// Load with configuration
docs = aiDocuments(
    source: "/path/to/document.pdf",
    config: {
        type: "pdf",
        sortByPosition: true,
        addMoreFormatting: true,
        startPage: 1,
        endPage: 10
    }
).load()

Load Multiple Documents:

// Load all markdown files from a directory
docs = aiDocuments(
    source: "/knowledge-base",
    config: {
        type: "directory",
        recursive: true,
        extensions: ["md", "txt"],
        excludePatterns: ["node_modules", ".git"]
    }
).load()

Ingest into Vector Memory:

// Create vector memory
vectorMemory = aiMemory( "chroma", config: {
    collection: "docs",
    embeddingProvider: "openai",
    embeddingModel: "text-embedding-3-small"
} )

// Ingest documents with chunking and embedding
result = aiDocuments(
    source: "/knowledge-base",
    config: {
        type: "directory",
        recursive: true,
        extensions: ["md", "txt", "pdf"]
    }
).toMemory(
    memory: vectorMemory,
    options: { chunkSize: 1000, overlap: 200 }
)

println( "โœ… Loaded #result.documentsIn# docs as #result.chunksOut# chunks" )
println( "๐Ÿ’ฐ Estimated cost: $#result.estimatedCost#" )

RAG with Agent:

// Create agent with vector memory
agent = aiAgent(
    name: "KnowledgeAssistant",
    description: "AI assistant with access to knowledge base",
    memory: vectorMemory
)

// Query automatically retrieves relevant documents
response = agent.run( "What is BoxLang?" )
println( response )

๐Ÿ“š Learn More


๐Ÿ”Œ MCP Client

Connect to Model Context Protocol (MCP) servers ๐ŸŽฏ and use their tools, prompts, and resources in your AI applications. BoxLang AI's MCP client provides seamless integration with the growing MCP ecosystem, allowing your agents to access databases, APIs, filesystems, and more through standardized interfaces. ๐Ÿ’ก

๐Ÿค” Why Use MCP Client?

  • ๐ŸŒ Ecosystem Access - Use any MCP server (filesystems, databases, APIs, tools)
  • ๐Ÿ”’ Secure Integration - Standardized permissions and authentication
  • ๐ŸŽฏ Tool Discovery - Automatically discover and use server capabilities
  • ๐Ÿ”„ Dynamic Resources - Access changing data sources (files, DB records, etc.)
  • ๐Ÿค– Agent Integration - Seamlessly add MCP tools to your AI agents

๐Ÿ’ก Quick Examples

Connect to MCP Server:

// Connect to MCP server via HTTP
mcpClient = MCP( "http://localhost:3000" )
    .withTimeout( 5000 )

// List available tools
tools = mcpClient.listTools()
println( tools ) // Returns available MCP tools

Use MCP Tools in Agent:

// Connect to MCP servers
filesystemMcp = MCP( "http://localhost:3001" ).withTimeout( 5000 )
databaseMcp = MCP( "http://localhost:3002" ).withTimeout( 5000 )

// Create agent (MCP integration depends on agent implementation)
agent = aiAgent(
    name: "Data Assistant",
    description: "Assistant with MCP tool access"
)

// Agent automatically discovers and uses MCP tools
response = agent.run( "Read config.json and update the database with its contents" )

// Agent automatically uses MCP tools
agent.run( "Read config.json and update the database with its contents" )

Access MCP Resources:

// List available resources
resources = mcpClient.listResources()

// Read resource content
content = mcpClient.readResource( "file:///docs/readme.md" )
println( content )

// Use prompts from server
prompts = mcpClient.listPrompts()
prompt = mcpClient.getPrompt( "code-review", { language: "BoxLang" } )

๐Ÿ“š Learn More

๐Ÿ–ฅ๏ธ MCP Server

Expose your BoxLang functions and data as MCP tools ๐ŸŽฏ for use by AI agents and applications. Build custom MCP servers that provide tools, prompts, and resources through the standardized Model Context Protocol, making your functionality accessible to any MCP client. ๐Ÿ’ก

๐Ÿค” Why Build MCP Servers?

  • ๐Ÿ”Œ Universal Access - Any MCP client can use your tools
  • ๐ŸŽฏ Standardized Interface - No custom integration code needed
  • ๐Ÿ› ๏ธ Expose Functionality - Make BoxLang functions available to AI agents
  • ๐Ÿ“Š Share Resources - Provide data sources, templates, and prompts
  • ๐Ÿข Enterprise Integration - Connect AI to internal systems safely

๐Ÿ’ก Quick Examples

Simple MCP Server:

// Create server with tools
server = mcpServer(
    name: "my-tools",
    description: "Custom BoxLang tools"
)

// Register tool
server.registerTool(
    aiTool(
        name: "calculate_tax",
        description: "Calculate tax for a given amount",
        callable: ( amount, rate = 0.08 ) => {
            return amount * rate;
        }
    )
)

// Start server
server.start() // Listens on stdio by default

Advanced Server with Resources:

// Create server with tools, prompts, and resources
server = mcpServer(
    name: "enterprise-api",
    description: "Internal enterprise tools"
)

// Register multiple tools
server.registerTool( aiTool(
    name: "query_orders",
    description: "Query customer orders",
    callable: queryOrdersFunction
) )
server.registerTool( aiTool(
    name: "create_invoice",
    description: "Create customer invoice",
    callable: createInvoiceFunction
) )
server.registerTool( aiTool(
    name: "send_notification",
    description: "Send customer notification",
    callable: notifyFunction
) )

// Provide templates as prompts
server.registerPrompt(
    name: "customer-email",
    description: "Generate customer email",
    template: ( orderNumber ) => {
        return "Write a professional email about order ##orderNumber#";
    }
)

// Expose data resources
server.registerResource(
    uri: "config://database",
    description: "Database configuration",
    getData: () => {
        return fileRead( "/config/database.json" );
    }
)

// Start with custom transport
server.start( transport: "http", port: 3000 )

Integration with BoxLang Web App:

// In your BoxLang app's Application.bx
component {
    function onApplicationStart() {
        // Start MCP server on app startup
        application.mcpServer = aiMcpServer( "myapp-api" )
            .registerTool( "search", variables.searchFunction )
            .registerTool( "create", variables.createFunction )
            .start( background: true )
    }

    function onApplicationEnd() {
        application.mcpServer.stop()
    }
}

๐Ÿ“š Learn More


โš™๏ธ Settings

Here are the settings you can place in your boxlang.json file:

{
	"modules" : {
		"bxai" : {
			"settings": {
				// The default provider to use: openai, claude, deepseek, gemini, grok, mistral, ollama, openrouter, perplexity
				"provider" : "openai",
				// The default API Key for the provider
				"apiKey" : "",
				// The default request params to use when calling a provider
				// Ex: { temperature: 0.5, max_tokens: 100, model: "gpt-3.5-turbo" }
				"defaultParams" : {
					// model: "gpt-3.5-turbo"
				},
				// The default timeout of the ai requests
				"timeout" : 30,
				// If true, log request to the ai.log
				"logRequest" : false,
				// If true, log request to the console
				"logRequestToConsole" : false,
				// If true, log the response to the ai.log
				"logResponse" : false,
				// If true, log the response to the console
				"logResponseToConsole" : false,
				// The default return format of the AI response: single, all, raw
				"returnFormat" : "single"
			}
		}
	}
}

๐Ÿฆ™ Ollama Configuration

Ollama allows you to run AI models locally on your machine. It's perfect for privacy, offline use, and cost savings. ๐Ÿ’ฐ

๐Ÿ”ง Setup Ollama

  1. ๐Ÿ“ฅ Install: Download from https://ollama.ai
  2. โฌ‡๏ธ Pull a model: ollama pull llama3.2 (or any supported model)
  3. โ–ถ๏ธ Start service: Ollama runs on http://localhost:11434 by default

๐Ÿ“ Configuration

{
	"modules": {
		"bxai": {
			"settings": {
				"provider": "ollama",
				"apiKey": "",  // Optional: for remote/secured Ollama instances
				"chatURL": "http://localhost:11434",  // Default local instance
				"defaultParams": {
					"model": "llama3.2"  // Any Ollama model you have pulled
				}
			}
		}
	}
}
  • ๐Ÿฆ™ llama3.2 - Latest Llama model (recommended)
  • โšก llama3.2:1b - Smaller, faster model
  • ๐Ÿ’ป codellama - Code-focused model
  • ๐ŸŽฏ mistral - High-quality general model
  • ๐Ÿ”ท phi3 - Microsoft's efficient model

๐Ÿ› ๏ธ Global Functions (BIFs)

Function Purpose Parameters Return Type Async Support
aiAgent() Create autonomous AI agentname, description, instructions, model, memory, tools, subAgents, params, options AiAgent ObjectโŒ
aiChat() Chat with AI providermessages, params={}, options={} String/Array/StructโŒ
aiChatAsync() Async chat with AI providermessages, params={}, options={} BoxLang Futureโœ…
aiChatRequest() Compose raw chat requestmessages, params, options, headers AiRequestObjectN/A
aiChatStream() Stream chat responses from AI providermessages, callback, params={}, options={} voidN/A
aiChunk() Split text into chunkstext, options={} Array of StringsN/A
aiDocuments() Create fluent document loadersource, config={} IDocumentLoader ObjectN/A
aiEmbed() Generate embeddingsinput, params={}, options={} Array/StructN/A
aiMemory() Create memory instancememory, key, userId, conversationId, config={} IAiMemory ObjectN/A
aiMessage() Build message objectmessage ChatMessage ObjectN/A
aiModel() Create AI model wrapperprovider, apiKey, tools AiModel ObjectN/A
aiPopulate() Populate class/struct from JSONtarget, data Populated ObjectN/A
aiService() Create AI service providerprovider, apiKey IService ObjectN/A
aiTokens() Estimate token counttext, options={} NumericN/A
aiTool() Create tool for real-time processingname, description, callable Tool ObjectN/A
aiTransform() Create data transformertransformer, config={} Transformer RunnableN/A
MCP() Create MCP client for Model Context Protocol serversbaseURL MCPClient ObjectN/A
mcpServer() Get or create MCP server for exposing toolsname="default", description, version, cors, statsEnabled, force MCPServer ObjectN/A

Note on Return Formats: When using pipelines (runnable chains), the default return format is raw (full API response), giving you access to all metadata. Use .singleMessage(), .allMessages(), or .withFormat() to extract specific data. The aiChat() BIF defaults to single format (content string) for convenience. See the Pipeline Return Formats documentation for details.

๐Ÿ“ข Events

The BoxLang AI module emits several events throughout the AI processing lifecycle that allow you to intercept, modify, or extend functionality. These events are useful for logging, debugging, custom providers, and response processing.

Read more about Events in BoxLang AI.

Event Reference Table

Event When Fired Data Emitted Use Cases
afterAIAgentRun After agent completes executionagent, response Agent monitoring, result tracking
afterAIEmbed After generating embeddingsembeddingRequest, service, result Result processing, caching
afterAIModelInvoke After model invocation completesmodel, aiRequest, results Performance tracking, validation
afterAIPipelineRun After pipeline execution completessequence, result, executionTime Pipeline monitoring, metrics
afterAIToolExecute After tool execution completestool, results, executionTime Tool performance tracking
beforeAIAgentRun Before agent starts executionagent, input, messages, params Agent validation, preprocessing
beforeAIEmbed Before generating embeddingsembeddingRequest, service Request validation, preprocessing
beforeAIModelInvoke Before model invocation startsmodel, aiRequest Request validation, cost estimation
beforeAIPipelineRun Before pipeline execution startssequence, stepCount, steps, input Pipeline validation, tracking
beforeAIToolExecute Before tool execution startstool, name, arguments Permission checks, validation
onAIAgentCreate When agent is createdagent Agent registration, configuration
onAIEmbedRequest Before sending embedding requestdataPacket, embeddingRequest, provider Request logging, modification
onAIEmbedResponse After receiving embedding responseembeddingRequest, response, provider Response processing, caching
onAIError When AI operation error occurserror, errorMessage, provider, operation, canRetry Error handling, retry logic, alerts
onAiMemoryCreate When memory instance is createdmemory, type, config Memory configuration, tracking
onAIMessageCreate When message is createdmessage Message validation, formatting
onAIModelCreate When model wrapper is createdmodel, service Model configuration, tracking
onAIProviderCreate After provider is createdprovider Provider initialization, configuration
onAIProviderRequest When provider is requestedprovider, apiKey, service Custom provider registration
onAIRateLimitHit When rate limit (429) is encounteredprovider, statusCode, retryAfter Rate limit handling, provider switching
onAIRequest Before sending HTTP requestdataPacket, aiRequest, provider Request logging, modification, authentication
onAIRequestCreate When request object is createdaiRequest Request validation, modification
onAIResponse After receiving HTTP responseaiRequest, response, rawResponse, provider Response processing, logging, caching
onAITokenCount When token usage data is availableprovider, model, promptTokens, completionTokens, totalTokens Cost tracking, budget enforcement
onAIToolCreate When tool is createdtool, name, description Tool registration, validation
onAITransformerCreate When transformer is createdtransform Transform configuration, tracking

๐ŸŒ GitHub Repository and Reporting Issues

Visit the GitHub repository for release notes. You can also file a bug report or improvement suggestion via GitHub Issues.

๐Ÿงช Testing

This module includes tests for all AI providers. To run the tests:

./gradlew test

Ollama Testing

For Ollama provider tests, you need to start the test Ollama service first:

# Start the Ollama test service
docker-compose up -d ollama-test

# Wait for it to be ready (this may take a few minutes for the first run)
# The service will automatically pull the qwen2.5:0.5b model

# Run the tests
./gradlew test --tests "ortus.boxlang.ai.providers.OllamaTest"

# Clean up when done
docker-compose down -v

You can also use the provided test script:

./test-ollama.sh

This will start the service, verify it's working, and run a basic test.

Note: The first time you run this, it will download the qwen2.5:0.5b model (~500MB), so it may take several minutes.

๐Ÿ’– 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

2.0.0 - 2026-01-19

One of our biggest library updates yet! This release introduces a powerful new document loading system, comprehensive security features for MCP servers, and full support for several major AI providers including Mistral, HuggingFace, Groq, OpenRouter, and Ollama. Additionally, we have implemented complete embeddings functionality and made numerous enhancements and fixes across the board.

Added

  • Document Loaders: New document loading system for importing content from various sources
    • New aiDocuments() BIF for loading documents with automatic type detection
    • New aiDocumentLoader() BIF for creating loader instances with advanced configuration
    • New aiDocumentLoaders() BIF for retrieving all registered loaders with metadata
    • New aiMemoryIngest() BIF for ingesting documents into memory with comprehensive reporting:
      • Single memory or multi-memory fan-out support
      • Async processing for parallel ingestion
      • Automatic chunking with aiChunk() integration
      • Token counting with aiTokens() integration
      • Cost estimation for embedding operations
      • Detailed ingestion report (documentsIn, chunksOut, stored, skipped, deduped, tokenCount, embeddingCalls, estimatedCost, errors, memorySummary, duration)
    • New Document class for standardized document representation with content and metadata
    • New IDocumentLoader interface and BaseDocumentLoader abstract class for custom loaders
    • Built-in Loaders:
      • TextLoader: Plain text files (.txt, .text)
      • MarkdownLoader: Markdown files with header splitting, code block removal
      • HTMLLoader: HTML files and URLs with script/style removal, tag extraction
      • CSVLoader: CSV files with row-as-document mode, column filtering
      • JSONLoader: JSON files with field extraction, array-as-documents mode
      • DirectoryLoader: Batch loading from directories with recursive scanning
    • Fluent API for loader configuration
    • Integration with memory systems via loadTo() method and aiMemoryIngest() BIF
    • Automatic document chunking support for vector memory
    • Comprehensive documentation in docs/main-components/document-loaders.md
  • MCP Server Enterprise Security Features: Comprehensive security enhancements for MCP servers
    • CORS Configuration:
      • withCors(origins) - Configure allowed origins (string or array)
      • addCorsOrigin(origin) - Add origin dynamically
      • getCorsAllowedOrigins() - Get configured origins array
      • isCorsAllowed(origin) - Check if origin is allowed with wildcard matching
      • Support for wildcard patterns (*.example.com)
      • Support for allowing all origins (*)
      • Dynamic Access-Control-Allow-Origin header in responses
      • CORS headers included in OPTIONS preflight responses
    • Request Body Size Limits:
      • withBodyLimit(maxBytes) - Set maximum request body size in bytes
      • getMaxRequestBodySize() - Get current limit (0 = unlimited)
      • Returns 413 Payload Too Large error when exceeded
      • Protects against DoS attacks with oversized payloads
    • Custom API Key Validation:
      • withApiKeyProvider(provider) - Set custom API key validation callback
      • hasApiKeyProvider() - Check if provider is configured
      • verifyApiKey(apiKey, requestData) - Manual key validation
      • Supports X-API-Key header and Authorization: Bearer token
      • Provider receives API key and request context for flexible validation
      • Returns 401 Unauthorized for invalid keys
    • Security Headers: Automatic inclusion of industry-standard security headers in all responses
      • X-Content-Type-Options: nosniff
      • X-Frame-Options: DENY
      • X-XSS-Protection: 1; mode=block
      • Referrer-Policy: strict-origin-when-cross-origin
      • Content-Security-Policy: default-src 'none'; frame-ancestors 'none'
      • Strict-Transport-Security: max-age=31536000; includeSubDomains
      • Permissions-Policy: geolocation=(), microphone=(), camera=()
    • Security Processing Order: Body size โ†’ CORS โ†’ Basic Auth โ†’ API Key โ†’ Request processing
    • Comprehensive documentation in docs/advanced/mcp-server.md with examples
    • Security configuration examples in main README.md
    • 9 new integration tests covering all security features
  • Mistral AI Provider Support: Full integration with Mistral AI services
    • New MistralService provider class with OpenAI-compatible API
    • Chat completions with streaming support
    • Embeddings support with mistral-embed model
    • Tool/function calling support
    • Default model: mistral-small-latest
    • API key detection via MISTRAL_API_KEY environment variable
    • Comprehensive integration tests
  • HuggingFace Provider Support: Full integration with HuggingFace Inference API
    • New HuggingFaceService provider class extending BaseService
    • OpenAI-compatible API endpoint at router.huggingface.co/v1
    • Default model: Qwen/Qwen2.5-72B-Instruct
    • Support for chat completions and embeddings
    • Integration tests for HuggingFace provider
    • API key pattern: HUGGINGFACE_API_KEY
  • Groq Provider Support: Full integration with Groq AI services for fast inference
    • Uses OpenAI-compatible API at api.groq.com
    • Default model: llama-3.3-70b-versatile
    • Support for chat completions, streaming, and embeddings
    • Environment variable: GROQ_API_KEY
  • Embeddings Support: Complete embeddings functionality for semantic search, clustering, and recommendations
    • New aiEmbedding() BIF for generating text embeddings
    • New AiEmbeddingRequest class to model embedding requests
    • New embeddings() method in IAiService interface
    • Support for single text and batch text embedding generation
    • Multiple return formats: raw, embeddings, first
    • Provider Support:
      • OpenAI: text-embedding-3-small and text-embedding-3-large models
      • Ollama: Local embeddings for privacy-sensitive use cases
      • DeepSeek: OpenAI-compatible embeddings API
      • Grok: OpenAI-compatible embeddings API
      • OpenRouter: Aggregated embeddings via multiple models
      • Gemini: Custom implementation with text-embedding-004 model
    • New embedding-specific events: onAIEmbeddingRequest, onAIEmbeddingResponse, beforeAIEmbedding, afterAIEmbedding
    • Comprehensive embeddings documentation in README with examples
    • New examples/embeddings-example.bx demonstrating practical use cases
    • Integration tests for embeddings functionality
  • ChatMessage now has the following new methods:
    • format(bindings) - Formats messages with provided bindings.
    • render() - Renders messages using stored bindings.
    • bind( bindings ) - Binds variables to be used in message formatting.
    • getBindings(), setBindings( bindings ) - Getters and setters for bindings.
  • Detect API Keys by convention in AIService() BIF: <PROVIDER>_API_KEY from system settings
  • OpenRouter Provider Support: Full integration with OpenRouter AI services
  • Automatic JSON serialization for tool calls that don't return strings
  • Ollama Provider Support: Complete integration with Ollama for local AI model execution
  • Comprehensive Provider Test Suite: Individual test files for each AI provider
  • Streaming Support Validation: Verified aiChatStream() functionality across all providers
  • Docker Compose Testing Infrastructure: Automated local development and CI/CD support
  • Enhanced GitHub Actions Workflow: Improved CI/CD pipeline with AI service support
  • BIF Reference Documentation: Complete function reference table in README
  • Comprehensive Event Documentation: Complete event system documentation

Fixed

  • If a tool argument doesn't have a description, it would cause an error when generating the schema. Default it to the argument name.
  • Model Name Compatibility: Updated OllamaService default model from llama3.2 to qwen2.5:0.5b-instruct
  • Docker GPU Support: Made GPU configuration optional in docker-compose.yml for systems without GPU access
  • Test Model References: Corrected model names in Ollama tests to match available models

1.2.0 - 2025-06-19

Added

  • New gradle wrapper and build system
  • New Tool.getArgumentsSchema() method to retrieve the arguments schema for use by any provider.
  • New logging params for console debugging: logRequestToConsole, logResponseToConsole
  • Tool support for Claude LLMs
  • Tool message for open ai tools when no local tools are available.
  • New ChatMessage helper method: getNonSystemMessages() to retrieve all messages except the system message.
  • ChatRequest now has the original ChatMessage as a property, so you can access the original message in the request.
  • Latest Claude Sonnet model support: claude-sonnet-4-0 as its default.
  • Streamline of env on tests
  • Added to the config the following options: logRequest, logResponse, timeout, returnFormat, so you can control the behavior of the services globally.
  • Some compatibilities so it can be used in CFML apps.
  • Ability for AI responses to be influenced by the onAIResponse event.

Fixed

  • Version pinned to 1.0.0 in the box.json file by accident.

1.1.0 - 2025-05-17

Added

  • Claude LLM Support
  • Ability for the services to pre-seed params into chat requests
  • Ability for the services to pre-seed headers into chat requests
  • Error logging for the services

Fixed

  • Custom headers could not be added due to closure encapsulation

1.0.1 - 2025-03-21

Fixed

  • Missing the settings in the module config.
  • Invalid name for the module config.

1.0.0 - 2025-03-17

  • First iteration of this module

$ box install bx-ai

No collaborators yet.
     
  • {{ getFullDate("2025-03-05T22:10:21Z") }}
  • {{ getFullDate("2026-01-19T22:21:27Z") }}
  • 2,487
  • 841