Runtime Semantics
Ageniti keeps the important behaviour in the runtime so that CLI, HTTP, MCP, React, JSON automation, dev tools, and LLM adapters all share one execution model.
Execution Flow
When you invoke an action, the runtime performs these steps:
- Resolve the action by name or object reference.
- Check whether the action supports the requested surface.
- Validate input against the action input schema.
- Enforce confirmation for protected actions.
- Run the permission checker.
- Execute middleware.
- Run the action with timeout and retry handling.
- Ensure the output can be serialised as JSON.
- Validate output against the output schema, if present.
- Return a structured success or failure envelope.
Surface Rules
Supported surfaces are declared on each action through supportedSurfaces.
Default supported surfaces:
cli, json, http, mcp, react, dev, ai-sdkIf a surface is not supported, the runtime returns UNSUPPORTED_SURFACE.
Confirmation Rules
Actions with requiresConfirmation: true require an explicit confirmation flag.
By default, destructive actions inherit confirmation automatically.
Runtime confirmation is enforced for most surfaces, but not for:
reactdev
That means UI surfaces should handle confirmation in the UI layer before invoking the action.
Permission Checks
permissionChecker({ action, input, context }) must return either:
trueto allow executionfalseto deny execution with a generic authorisation message- a string to deny execution with a custom message
If the check fails, the runtime returns AUTHORIZATION_ERROR.
Timeout And Retry
Timeout is controlled by:
- action-level
timeoutMs - per-invocation
timeoutMs
Retry is controlled by:
- action-level
retry - per-invocation
retry
Retry only happens when the thrown error is retryable. That usually means the action throws an AgenitiError with retryable: true, or the timeout logic marks the failure as retryable.
retry: true normalises to:
{
"retries": 2,
"delayMs": 100
}Retries use linear backoff based on attempt count.
Logging, Progress, And Artifacts
Every invocation accumulates structured logs and artifacts.
From context.logger:
debug(message, fields?)info(message, fields?)warn(message, fields?)error(message, fields?)
From context.progress.report():
- records a log entry with
fields.type = "progress" - may include
percent - may include additional structured fields
From context.artifacts.add():
- normalises missing
id - defaults
typeto"file" - stores
metadataas an object
Success Envelope
{
"ok": true,
"data": {},
"artifacts": [],
"logs": [],
"meta": {
"action": "create_task",
"invocationId": "invocation-id",
"surface": "cli",
"durationMs": 12
}
}Failure Envelope
{
"ok": false,
"error": {
"code": "VALIDATION_ERROR",
"message": "Invalid action input.",
"issues": [],
"retryable": false
},
"artifacts": [],
"logs": [],
"meta": {
"action": "create_task",
"invocationId": "invocation-id",
"surface": "mcp",
"durationMs": 3
}
}Common Runtime Error Codes
Core runtime codes:
ACTION_NOT_FOUNDUNSUPPORTED_SURFACEVALIDATION_ERRORCONFIRMATION_REQUIREDAUTHORIZATION_ERROROUTPUT_SERIALIZATION_ERROROUTPUT_VALIDATION_ERRORTIMEOUTCANCELLEDINTERNAL_ERROR
Wrapper-specific codes you may also see:
INVALID_JSON_RUNNER_PAYLOADDEV_SERVER_ERRORNOT_FOUNDfrom the local dev server HTTP routes
How Errors Are Normalised
If an action throws:
AgenitiError, itscode,message,issues, andretryablefields are preservedAbortError, the runtime returnsCANCELLED- any other error, the runtime returns
INTERNAL_ERROR
CLI Exit Codes
The built-in CLI maps runtime errors to process exit codes.
Important mappings:
VALIDATION_ERROR->2AUTHENTICATION_ERROR->3AUTHORIZATION_ERROR->3ACTION_NOT_FOUND->4EXTERNAL_SERVICE_ERROR->5TIMEOUT->124CANCELLED->130- anything else ->
1
Output Guarantees
Ageniti only returns values that can be serialised safely as JSON.
If an output schema exists, the runtime validates the action result against it before returning success. This makes the result envelope suitable for CLI output, MCP structured content, tests, and machine-to-machine integrations.