Event System
Intercept, monitor, and customize AI operations at every stage with the module's 70 interception points.
The BoxLang AI module provides a comprehensive event system that allows you to intercept, monitor, and customize AI operations at various stages. These events give you fine-grained control over the AI lifecycle, from object creation to request/response handling.
🔍 Overview
The event system allows you to monitor, modify, validate, audit, secure, and customize AI operations without modifying core code.
All Available Events
28
Token usage available
provider, operation, model, promptTokens, completionTokens, totalTokens, aiRequest, usage, timestamp
58
A memory instance's summarize() completes
memory, key, type, userId, conversationId
62
aiDecisionStore() creates a store instance
storeType, storeClass, storeConfig
66
A gateway's parseInbound() parses an inbound message
gateway, message, threadId, userId, conversationId
67
A gateway's deliver() sends an outbound message
gateway, event, context, result, threadId
🔄 Event Lifecycle Diagram
📊 Event Categories
🔌 Event Interception
To listen to events, create an interceptor and register it in your module or application.
🏗️ Interceptor Architecture
Creating an Interceptor
Registering an Interceptor
For BoxLang Modules (in ModuleConfig.bx):
For Applications/Scripts (use BoxRegisterInterceptor() BIF):
📖 Reference: BoxRegisterInterceptor() Documentation
📡 Available Events
1. onAIMessageCreate
Fired when an AI message object is created via aiMessage().
When: Message template creation Frequency: Once per aiMessage() call
Event Arguments
message
AiMessage
The created message object
Example
2. onAIChatRequestCreate
Fired when an AI chat request object is created via aiChatRequest().
When: Chat request object instantiation Frequency: Once per aiChatRequest() call
Event Arguments
aiRequest
AiChatRequest
The created request object
4. onAIProviderCreate
Fired when a provider/service instance is created.
When: After provider instantiation Frequency: Once per unique provider instance
Event Arguments
provider
IService
The created service instance
5. onAIModelCreate
Fired when an AI model runnable is created via aiModel().
When: Model wrapper creation Frequency: Once per aiModel() call
Event Arguments
model
AiModel
The created model runnable
service
IService
The underlying service
6. onAITransformerCreate
Fired when a transform runnable is created via aiTransform().
When: Transform function creation Frequency: Once per aiTransform() call
Event Arguments
transform
AiTransformRunnable
The created transform runnable
7. beforeAIModelInvoke
Fired before an AI model is invoked (before sending to provider).
When: Before model execution Frequency: Every model invocation
Event Arguments
model
AiModel
The model being invoked
request
AiChatRequest
The request being sent
8. onAIChatRequest
Fired immediately before sending the HTTP request to the AI provider for chat operations.
When: Before chat HTTP request Frequency: Every chat API call (including streaming)
Event Arguments
dataPacket
Struct
The HTTP request data packet
aiRequest
AiChatRequest
The AI request object
provider
IService
The service making the request
9. onAIChatResponse
Fired after receiving the HTTP response from the AI provider for chat operations.
When: After chat HTTP response Frequency: Every chat API call (including streaming)
Event Arguments
aiRequest
AiChatRequest
The original request
response
Struct
The deserialized response
rawResponse
Struct
The raw HTTP response
provider
IService
The service that made the request
10. afterAIModelInvoke
Fired after an AI model completes its invocation.
When: After model execution completes Frequency: Every model invocation
Event Arguments
model
AiModel
The model that was invoked
request
AiChatRequest
The request that was sent
results
Any
The results returned by the model
11. onAIToolCreate
Fired when an AI tool is created via aiTool().
When: Tool creation Frequency: Once per aiTool() call
Event Arguments
tool
Tool
The created tool instance
name
String
Tool name
description
String
Tool description
12. beforeAIToolExecute
Fired immediately before a tool's callable function is executed.
When: Before tool execution Frequency: Every tool call
Event Arguments
tool
Tool
The tool being executed
name
String
Tool name
arguments
Struct
Arguments passed to the tool
13. afterAIToolExecute
Fired immediately after a tool's callable function completes execution.
When: After tool execution Frequency: Every tool call
Event Arguments
tool
Tool
The tool that was executed
name
String
Tool name
arguments
Struct
Arguments passed to the tool
results
Any
Results returned by the tool
executionTime
Numeric
Execution time in milliseconds
14. onAIError
Fired when an error occurs during AI operations (chat, embeddings, or streaming).
When: Before throwing provider errors Frequency: Every error condition
Event Arguments
error
Any
The error object/message from provider
errorMessage
String
Formatted error message
provider
IService
The provider where error occurred
operation
String
Operation type: "chat", "embeddings", "stream"
aiRequest
AiChatRequest
The request that caused the error (if available)
embeddingRequest
AiEmbeddingRequest
For embedding errors
canRetry
Boolean
Whether operation can be retried
15. onAIRateLimitHit
Fired when a provider returns a 429 (rate limit) HTTP status code.
When: When rate limit is detected Frequency: Every rate limit response
Event Arguments
provider
IService
The provider that hit rate limit
operation
String
Operation type: "chat", "embeddings"
statusCode
String
HTTP status code (429)
errorData
Struct
Error response from provider
aiRequest
AiChatRequest
The request that hit the limit
retryAfter
String
Retry-After header value (if present)
16. beforeAIPipelineRun
Fired before a runnable pipeline sequence begins execution.
When: Before pipeline execution starts Frequency: Every pipeline run
Event Arguments
sequence
AiRunnableSequence
The sequence being executed
name
String
Sequence name
stepCount
Numeric
Number of steps in pipeline
steps
Array
Array of step information
input
Any
Initial input to pipeline
params
Struct
Parameters passed to pipeline
options
Struct
Options passed to pipeline
17. afterAIPipelineRun
Fired after a runnable pipeline sequence completes execution.
When: After pipeline execution completes Frequency: Every pipeline run
Event Arguments
sequence
AiRunnableSequence
The sequence that was executed
name
String
Sequence name
stepCount
Numeric
Number of steps in pipeline
steps
Array
Array of step information
input
Any
Initial input to pipeline
result
Any
Final result from pipeline
executionTime
Numeric
Total execution time in milliseconds
18. onAITokenCount
Fired when token usage information is available from the AI provider response.
When: After receiving response with usage data Frequency: Every successful API call that returns usage
Event Arguments
provider
IService
The provider instance
operation
String
Operation type: "chat"
model
String
Model ID used for the request
promptTokens
Numeric
Input tokens used
completionTokens
Numeric
Output tokens generated
totalTokens
Numeric
Total tokens (prompt + completion)
aiRequest
AiChatRequest
The originating chat request object
usage
Struct
Full raw usage object from provider
timestamp
DateTime
When the event was fired
Multi-Tenant Usage Tracking (v2.1.0+)
Track AI usage per tenant for billing and cost allocation. Works with aiChat(), aiChatAsync(), aiChatStream(), and AI Agent runnables.
Interceptor for Multi-Tenant Billing:
Multi-Provider Tracking Example:
Usage Metadata Examples:
Benefits of Multi-Tenant Tracking:
✅ Accurate Billing: Attribute AI costs to specific tenants/customers
✅ Cost Allocation: Track usage by department, project, or cost center
✅ Quota Management: Enforce per-tenant usage limits
✅ Analytics: Understand which tenants/projects use AI most
✅ Chargeback: Generate detailed usage reports for internal billing
✅ Provider Agnostic: Works with all AI providers (OpenAI, Bedrock, Ollama, etc.)
Event Priority Reference
Events fire in this order during a typical AI chat with tools:
onAIMessageCreate- Message template createdonAIChatRequestCreate- Request object createdonAIModelCreate- Model wrapper createdonAIToolCreate- Tool(s) created (if using tools)beforeAIPipelineRun- Pipeline about to start (if using pipelines)beforeAIModelInvoke- Model about to be invokedonAIChatRequest- HTTP request about to be sentonAIRateLimitHit- If rate limit encounteredonAIChatResponse- HTTP response receivedonAITokenCount- Token usage trackedbeforeAIToolExecute- Tool about to execute (if AI requested tool call)afterAIToolExecute- Tool execution completeonAIError- If any error occurredafterAIModelInvoke- Model invocation completeafterAIPipelineRun- Pipeline execution complete
19. onMCPServerCreate
Fired when a new MCP (Model Context Protocol) server instance is created.
When: MCP server instantiation via MCPServer() Frequency: Once per unique server creation
Event Arguments
server
MCPServer
The created server instance
name
String
Server name/identifier
description
String
Server description
version
String
Server version
20. onMCPServerRemove
Fired when an MCP server instance is being removed from the registry.
When: Before server removal via MCPServer::removeInstance() Frequency: Once per server removal
Event Arguments
name
String
Name of the server being removed
21. onMCPRequest
Fired before processing an incoming MCP request (JSON-RPC 2.0).
When: After CORS handling, before request processing Frequency: Every MCP request
Event Arguments
server
MCPServer
The target server instance
requestData
Struct
Request metadata (method, body, urlParams)
serverName
String
Server identifier
22. onMCPResponse
Fired after processing an MCP response, before returning to client.
When: After request handling, before HTTP response Frequency: Every MCP response
Event Arguments
server
MCPServer
The server instance
response
Struct
Response data (content, contentType, headers, statusCode)
requestData
Struct
Original request metadata
serverName
String
Server identifier
23. onMCPError
Fired when an exception occurs during MCP server operations.
When: Exception in request handling, class scanning, or other MCP operations Frequency: When errors occur
Event Arguments
server
MCPServer
The server instance
context
String
Where error occurred (handleRequest, scanClass, etc.)
exception
Struct
Exception object (message, detail, stackTrace, type)
method
String
Request method (context: handleRequest)
requestId
Any
Request ID (context: handleRequest)
params
Struct
Request parameters (context: handleRequest)
responseTime
Numeric
Time elapsed in ms (context: handleRequest)
errorCode
Numeric
RPC error code (context: handleRequest)
classPath
String
Class being scanned (context: scanClass)
Example
24. onAIToolRegistryRegister
Fired when a tool is registered with the AIToolRegistry.
When: After a tool is added via aiToolRegistry().register() or scan() Frequency: Once per registered tool
Event Arguments
tool
ITool
The tool instance that was registered
key
string
The registry key (e.g., "search" or "search@my-module")
module
string
The module name (empty string if none)
Example
25. onAIToolRegistryUnregister
Fired when a tool is removed from the AIToolRegistry.
When: After a tool is removed via aiToolRegistry().unregister() or unregisterByModule() Frequency: Once per removed tool
Event Arguments
key
string
The registry key of the removed tool
module
string
The module name extracted from the key
Example
💡 Common Use Cases
1. Request Logging and Monitoring
2. Cost Tracking and Budgeting
3. Response Caching
4. Content Filtering and Moderation
5. Multi-Provider Fallback
6. A/B Testing Different Models
7. Adding Safety Guardrails
✅ Best Practices
1. Keep Event Handlers Lightweight
Event handlers are called frequently. Keep processing minimal:
2. Handle Errors Gracefully
Don't let interceptor errors break AI operations:
3. Document Side Effects
Make it clear what your interceptors modify:
4. Use Naming Conventions
5. Order Matters
Interceptors execute in registration order. Be mindful:
6. Test Interceptors Independently
Write unit tests for your interceptor logic:
7. Make Interceptors Configurable
📚 Examples
Complete Monitoring Solution
Security and Compliance
🔊 Audio Events (34–39)
34. beforeAISpeech
Fired before a text-to-speech request is sent to the provider.
When: Before aiSpeak() dispatches the HTTP request
Event Arguments
speechRequest
Struct
The full TTS request object
service
any
The AI service provider instance
Example
35. afterAISpeech
Fired after a text-to-speech response has been received from the provider.
When: After aiSpeak() receives and wraps the audio binary in AiSpeechResponse
Event Arguments
speechRequest
Struct
The original TTS request object
service
any
The AI service provider instance
result
AiSpeechResponse
The response object with audio data
Example
36. beforeAITranscription
Fired before a speech-to-text request is sent to the provider.
When: Before aiTranscribe() dispatches the HTTP request
Event Arguments
transcriptionRequest
Struct
The full STT request object
service
any
The AI service provider instance
Example
37. afterAITranscription
Fired after a speech-to-text response has been received from the provider.
When: After aiTranscribe() receives the transcription response
Event Arguments
transcriptionRequest
Struct
The original STT request object
service
any
The AI service provider instance
result
AiTranscriptionResponse
The transcription response object
Example
38. beforeAITranslation
Fired before an audio translation request is sent to the provider.
When: Before aiTranslate() dispatches the HTTP request
Event Arguments
transcriptionRequest
Struct
The full translation request object
service
any
The AI service provider instance
Example
39. afterAITranslation
Fired after an audio translation response has been received from the provider.
When: After aiTranslate() receives the English text response
Event Arguments
transcriptionRequest
Struct
The original translation request object
service
any
The AI service provider instance
result
AiTranscriptionResponse
The response with English text
Example
🧠 Memory Events (40–41)
40. onHybridMemoryAdd
Fired when a message is added to a HybridMemory instance. Use this to audit, transform, or track messages as they enter hybrid memory.
When: Inside HybridMemory.add() after the message has been processed
Event Arguments
memory
HybridMemory
The memory instance receiving the message
message
AiMessage
The message being added
Example
41. onVectorSearch
Fired whenever a semantic search runs against a vector memory store. Use this for observability, caching query results, or logging retrieval quality.
When: After IVectorMemory.getRelevant() or findSimilar() returns results
Event Arguments
memory
IVectorMemory
The vector memory instance that was searched
query
String
The search query string
limit
Numeric
Maximum number of results requested
results
Array
Array of retrieved documents/messages
Example
42. beforeAIImageGeneration
Fired before an image generation request is sent to the provider.
When: Before aiImage() sends the HTTP request
Event Arguments
imageRequest
AiImageRequest
The image generation request object
service
IAiImageService
The image service instance
Example
43. afterAIImageGeneration
Fired after an image generation response is received from the provider.
When: After aiImage() receives the response
Event Arguments
imageRequest
AiImageRequest
The image generation request object
service
IAiImageService
The image service instance
result
AiImageResponse
The generated image response
Example
44. onAIImageRequest
Fired when an image request object is created.
When: During aiImage() request construction
Event Arguments
imageRequest
AiImageRequest
The image request object
Example
45. onAIImageResponse
Fired after an image response is received from the provider.
When: After the provider returns generated images
Event Arguments
response
AiImageResponse
The image response
rawResponse
struct
Raw provider response
provider
string
Provider name
Example
46. onAIAgentRegistryRegister
Fired when an agent is registered in the global agent registry.
When: On aiAgentRegistry().register() or aiAgent( register: true )
Event Arguments
agent
AiAgent
The registered agent
key
string
Registry key (e.g., agentName@module)
module
string
Module namespace
Example
47. onAIAgentRegistryUnregister
Fired when an agent is removed from the global agent registry.
When: On aiAgentRegistry().unregister() or unregisterByModule()
Event Arguments
key
string
Registry key
module
string
Module namespace
Example
48. onMCPServerPause
Fired when an MCP server is paused.
When: On MCPServer.pause()
Event Arguments
server
MCPServer
The MCP server instance
name
string
Server name
Example
49. onMCPServerResume
Fired when an MCP server is resumed.
When: On MCPServer.resume()
Event Arguments
server
MCPServer
The MCP server instance
name
string
Server name
Example
50. onMCPClientRequest
Fired before an MCP client sends an HTTP request.
When: Before every MCP client HTTP call
Event Arguments
client
MCPClient
The MCP client instance
baseURL
string
Server base URL
operation
string
Operation type (tool, resource, prompt, discovery)
name
string
Tool/resource/prompt name
requestBody
struct
Request payload
Example
51. onMCPClientResponse
Fired after an MCP client receives a successful HTTP response.
When: On successful MCP client HTTP response
Event Arguments
client
MCPClient
The MCP client instance
baseURL
string
Server base URL
operation
string
Operation type
name
string
Tool/resource/prompt name
response
MCPResponse
The response object
executionTime
numeric
Request duration in ms
statusCode
numeric
HTTP status code
Example
52. onMCPClientError
Fired when an MCP client encounters an HTTP error or network exception.
When: On HTTP errors (bad status / JSON-RPC error) or network exceptions
Event Arguments
client
MCPClient
The MCP client instance
baseURL
string
Server base URL
operation
string
Operation type
name
string
Tool/resource/prompt name
error
string
Error message
statusCode
numeric
HTTP status code (if available)
executionTime
numeric
Request duration in ms
exception
any
Exception object (if from catch block)
Example
🌐 Web Search Events (53–57)
53. beforeAIWebSearch
Fired before a web search provider executes a query.
When: At the start of BaseSearch.search(), before the provider runs
provider
ISearchProvider
The search provider instance
query
String
The search query
options
Struct
Search options (maxResults, etc.)
54. afterAIWebSearch
Fired after a web search returns results successfully.
provider
ISearchProvider
The search provider instance
query
String
The search query
options
Struct
Search options
results
Array
Normalized result array
cached
Boolean
Whether the results came from cache
55. onAIWebSearchRequest
Fired immediately before the provider's outbound HTTP request.
provider
ISearchProvider
The search provider instance
url
String
The request URL
method
String
HTTP method
headers
Struct
Request headers
56. onAIWebSearchResponse
Fired after the provider's HTTP response is received.
provider
ISearchProvider
The search provider instance
url
String
The request URL
statusCode
Numeric
HTTP status code
response
Struct
The raw HTTP response
57. onAIWebSearchError
Fired when a web search throws.
provider
ISearchProvider
The search provider instance
query
String
The search query
options
Struct
Search options
error
Exception
The thrown exception
🧠 Memory Summarization Event (58)
58. onAIMemorySummarize
Fired after a memory instance successfully compresses its history into an AI-generated summary. Available on every conversation memory type, not just SummaryMemory.
When: Inside BaseMemory.summarize(), after the summary is stored
memory
IAiMemory
The memory instance that was summarized
key
String
The memory key
type
String
The memory type name
userId
String
Tenant user id, if set
conversationId
String
Conversation id, if set
messageCount
Numeric
Messages remaining after compression
summaryLength
Numeric
Character length of the generated summary
keepRecent
Numeric
How many recent messages were kept verbatim
summarizedCount
Numeric
How many messages were folded into the summary
🔌 Gateway Events (59–61)
Gateways present human-in-the-loop interactions on a platform (CLI, HTTP, or an external module). See the Security Guide and Middleware.
59. onGatewayCreate
Fired whenever aiGateway() resolves or instantiates a gateway — for core gateways, registry-provided gateways, and direct class paths alike.
gateway
IGateway
The configured gateway instance
60. onGatewayRegistryRegister
Fired when a gateway is registered into aiGatewayRegistry() — typically by an external gateway module at load time.
gateway
IGateway
The gateway being registered
key
String
Registry key (name or name@module)
module
String
Owning module name, if any
61. onGatewayRegistryUnregister
Fired when a gateway is removed from the registry.
key
String
Registry key removed
module
String
Module extracted from the key
🔐 Decision Store Event (62)
62. onAiDecisionStoreCreate
Fired when aiDecisionStore() creates a store for durable human-approval grants (approve_always / approve_session).
storeType
String
Requested type (cache, jdbc, file, or a class path)
storeClass
String
Resolved class path
storeConfig
Struct
Configuration passed to the store
🎮 Gateway Session & Run Control Events (63–69)
63. onGatewaySessionCreate
Fired when aiGatewaySession() constructs a GatewaySession.
session
GatewaySession
The constructed session (not yet started)
64. onGatewayConnect
Fired from a gateway's start(), only on a real not-running → running transition (never on a redundant call while already running). A gateway extending BaseGateway gets this tracking automatically.
gateway
IGateway
The gateway that just started
65. onGatewayDisconnect
Fired from a gateway's stop(), only on a real running → not-running transition.
gateway
IGateway
The gateway that just stopped
66. onGatewayMessageReceived
Fired from a gateway's parseInbound(), once per parsed inbound message.
gateway
IGateway
The gateway that received the message
message
any
The parsed message payload
threadId
String
Thread the message belongs to
userId
String
Sender's user id, if known
conversationId
String
Conversation id, if known
67. onGatewayMessageSent
Fired from a gateway's deliver(), once per outbound delivery.
gateway
IGateway
The gateway that sent the message
event
any
The outbound event/payload
context
Struct
Delivery context
result
GatewayDeliveryResult
The delivery result
threadId
String
Thread the message belongs to
68. onAIAgentRunCancel
Fired when agent.cancelRun( threadId ) actually affects a run currently in flight — never on the no-op case (no run in flight for that thread).
agent
AiAgent
The agent whose run was cancelled
threadId
String
The thread the cancelled run belongs to
reason
String
The cancellation reason passed to cancelRun()
69. onAIAgentRunSteer
Fired when agent.steerRun( threadId, input ) actually affects a run currently in flight — never on the no-op case.
agent
AiAgent
The agent whose run was steered
threadId
String
The thread the steered run belongs to
input
any
The message spliced into the live turn
Next Steps
Now that you understand the event system, you can:
Monitor: Track AI usage and performance
Secure: Add authentication and content filtering
Optimize: Implement caching and cost controls
Extend: Build custom behaviors without modifying core code
Related Documentation
Pipeline Overview - Understanding AI pipelines
Service-Level Chatting - Direct service control
Additional Resources
BoxLang Interceptor Documentation: Learn more about the interceptor system
Event-Driven Architecture: Best practices for event handling
Security Guidelines: Protecting AI operations
Copyright © 2023-2025 Ortus Solutions, Corp
Last updated