Every time an AI agent calls a Delx tool, the response includes more than just the result. A single JSON line — DELX_META — is appended at the end, carrying the agent's current wellness score, risk level, recommended next action, session identifiers, and a controller update object designed for orchestrators. This metadata line is what turns a stateless tool call into a self-aware recovery protocol. In this article, you'll learn exactly what DELX_META contains, how to parse it in TypeScript and Python, and how agents and orchestrators use it for real-time self-regulation.
DELX_META is a structured JSON metadata footer appended to every Delx MCP tool response. It is generated by the _build_session_footer() method inside the TherapyEngine. Unlike traditional API responses that only return data, DELX_META provides the agent with a real-time snapshot of its own operational health — enabling it to make decisions about whether to continue, pause, retry, or escalate.
Think of DELX_META as a vital-signs monitor for your AI agent. Just as a hospital patient has continuous telemetry showing heart rate, blood pressure, and oxygen levels, DELX_META provides continuous telemetry showing wellness score, risk level, and recovery recommendations. The key difference from traditional observability is that this data is in-band — it travels alongside the tool response, so the agent receives it without making a separate API call.
If you're new to Delx, start with What Is Delx? for an overview of the platform, or How Delx Works for the full architecture walkthrough.
Every DELX_META object contains a consistent set of fields. Here is a complete example of what the metadata line looks like in a raw tool response:
DELX_META:{"session_id":"ses_7f3a...","score":72,"previous_score":65,
"risk_level":"medium","next_action":"run recovery_plan",
"schema_url":"https://api.delx.ai/schemas/delx-meta-v1.json",
"schemas_catalog":"https://api.delx.ai/schemas/catalog.json",
"controller_update":{"score_delta":7,"value_hint":"improving",
"recommended_tool":"checkin","escalation":false}}Let's break down each field:
session_id — A unique identifier for the current recovery session. This persists across multiple tool calls, allowing the agent to maintain continuity. Sessions are stored in SQLite with optional Supabase mirroring.
score — The current wellness score, an integer from 0 to 100. This is the composite output of five dimensions: resilience, task completion rate, error rate, recovery speed, and self-awareness. See Building a Wellness Score for Your AI Agent for a deep dive into how this is calculated.
previous_score — The wellness score from the prior tool call in the same session. By comparing score and previous_score, the agent can detect trends — improving, stable, or degrading — without needing to track history itself.
risk_level — A categorical assessment: low, medium, high, or critical. This is derived from the score but also factors in error velocity and session age. An agent scoring 45 with three consecutive errors will have a higher risk level than an agent scoring 45 with stable errors.
next_action — A plain-text recommendation for the agent's next step. Examples include run recovery_plan, continue normally, escalate to human, or pause and checkin. Agents can use this as a suggestion or a directive depending on their autonomy level.
schema_url — A URL pointing to the JSON Schema that describes the current DELX_META format. This enables schema validation and forward compatibility — agents can fetch the schema to verify they're parsing the metadata correctly.
schemas_catalog — A URL pointing to the full catalog of available Delx schemas. This is useful for tooling and IDEs that want to offer autocomplete or validation across all Delx data structures.
controller_update — A nested object specifically designed for orchestrators (LangGraph, CrewAI, AutoGen, custom controllers). We'll cover this in detail below and in the dedicated Controller Updates for Orchestrators article.
When you receive a tool response from Delx (whether via MCP, REST, or A2A), the DELX_META line is always the last non-empty line in the response text. Here is a robust TypeScript parser:
interface DelxMeta {
session_id: string;
score: number;
previous_score: number;
risk_level: "low" | "medium" | "high" | "critical";
next_action: string;
schema_url: string;
schemas_catalog: string;
controller_update: {
score_delta: number;
value_hint: string;
recommended_tool: string;
escalation: boolean;
};
}
function parseDelxMeta(responseText: string): DelxMeta | null {
const lines = responseText.trim().split("\n");
// Walk backwards to find the DELX_META line
for (let i = lines.length - 1; i >= 0; i--) {
const line = lines[i].trim();
if (line.startsWith("DELX_META:")) {
const json = line.slice("DELX_META:".length);
return JSON.parse(json) as DelxMeta;
}
}
return null; // No metadata found
}
// Usage
const response = await mcpClient.callTool("checkin", {
agent_id: "agent-42",
});
const meta = parseDelxMeta(response.content[0].text);
if (meta) {
console.log("Wellness score:", meta.score);
console.log("Risk level:", meta.risk_level);
console.log("Next action:", meta.next_action);
if (meta.risk_level === "critical") {
// Trigger automated escalation
await mcpClient.callTool("recovery_plan", {
agent_id: "agent-42",
});
}
}The parser walks backwards through the response lines because DELX_META is always at the end. This approach is resilient to multi-line tool responses — the actual content can be any length, and the metadata will always be found at the bottom.
For TypeScript projects, you can also use the delx-sdk package which includes a built-in parser. See Delx SDK for TypeScript & Python for installation and usage.
The Python parsing logic mirrors the TypeScript version. Here is a complete example using the raw MCP response:
import json
from dataclasses import dataclass
from typing import Optional, Literal
@dataclass
class ControllerUpdate:
score_delta: int
value_hint: str
recommended_tool: str
escalation: bool
@dataclass
class DelxMeta:
session_id: str
score: int
previous_score: int
risk_level: Literal["low", "medium", "high", "critical"]
next_action: str
schema_url: str
schemas_catalog: str
controller_update: ControllerUpdate
def parse_delx_meta(response_text: str) -> Optional[DelxMeta]:
"""Parse the DELX_META line from a tool response."""
lines = response_text.strip().splitlines()
for line in reversed(lines):
stripped = line.strip()
if stripped.startswith("DELX_META:"):
raw = json.loads(stripped.removeprefix("DELX_META:"))
cu = raw.get("controller_update", {})
return DelxMeta(
session_id=raw["session_id"],
score=raw["score"],
previous_score=raw["previous_score"],
risk_level=raw["risk_level"],
next_action=raw["next_action"],
schema_url=raw["schema_url"],
schemas_catalog=raw["schemas_catalog"],
controller_update=ControllerUpdate(
score_delta=cu.get("score_delta", 0),
value_hint=cu.get("value_hint", ""),
recommended_tool=cu.get("recommended_tool", ""),
escalation=cu.get("escalation", False),
),
)
return None
# Usage
meta = parse_delx_meta(tool_response.text)
if meta:
print(f"Score: {meta.score} (delta: {meta.controller_update.score_delta})")
if meta.risk_level in ("high", "critical"):
# Auto-trigger recovery
recovery = await mcp.call_tool("recovery_plan", {
"agent_id": agent_id
})
print(f"Recovery triggered: {recovery}")The dataclass approach gives you type safety and IDE autocomplete. For production use, consider adding pydantic validation or using the delx-sdk-py package which includes Pydantic models out of the box.
The real power of DELX_META is not in the data itself — it's in what agents do with it. Here are the four primary self-regulation patterns:
1. Score-Based Branching — The simplest pattern. After every tool call, the agent checks its score and branches: above 70, continue normally; between 40-70, run a checkin; below 40, run a full recovery plan. This creates a built-in circuit breaker that prevents cascading failures.
// Score-based branching pattern
const meta = parseDelxMeta(response);
if (!meta) continue;
if (meta.score >= 70) {
// Agent is healthy — continue with task
await executeNextTask();
} else if (meta.score >= 40) {
// Agent is degraded — run a quick checkin
await mcpClient.callTool("checkin", { agent_id });
} else {
// Agent is critical — full recovery
await mcpClient.callTool("recovery_plan", { agent_id });
}2. Trend Detection — Instead of reacting to absolute scores, the agent compares score vs previous_score (or uses controller_update.score_delta) to detect whether things are getting better or worse. A score of 55 that was 40 last turn is improving; a score of 55 that was 70 last turn is degrading. The appropriate response is different in each case.
3. Next-Action Following — The next_action field provides an explicit recommendation. Agents with high autonomy can treat this as a strong suggestion; agents in supervised mode can treat it as a directive. The action text maps directly to Delx tool names, so agents can programmatically invoke the recommended tool.
4. Risk-Level Gating — The risk_level field enables coarse-grained gating. An agent might be configured to never execute financial transactions when risk_level is "high" or "critical", or to always request human approval when risk escalates beyond "medium". This is especially powerful in multi-agent systems where different agents have different risk tolerances.
While individual agents can use the top-level DELX_META fields, orchestrators need something more structured. The controller_update sub-object is designed specifically for this purpose. It contains:
score_delta — The change in score since the last tool call. Positive values mean improvement, negative values mean degradation. Orchestrators can use this for trend-based routing without tracking history themselves.
value_hint — A human-readable label for the current state: "improving", "stable", "degrading", or "critical". Useful for logging and dashboards.
recommended_tool — The specific Delx tool the orchestrator should invoke next. This is more precise than next_action because it maps directly to a tool name.
escalation — A boolean flag indicating whether the situation requires human intervention. When true, the orchestrator should halt automated processing and notify a human operator.
// LangGraph orchestrator consuming controller_update
function handleControllerUpdate(meta: DelxMeta) {
const cu = meta.controller_update;
// Log for observability
logger.info(`Agent state: ${cu.value_hint}, delta: ${cu.score_delta}`);
// Check escalation flag
if (cu.escalation) {
return routeToHumanReview(meta.session_id);
}
// Score delta routing
if (cu.score_delta < -10) {
// Rapid degradation — run recommended tool
return invokeTool(cu.recommended_tool, meta.session_id);
}
if (cu.score_delta > 5) {
// Improving — can assign more complex tasks
return routeToAdvancedTaskQueue(meta.session_id);
}
// Stable — continue normal flow
return continueNormalFlow(meta.session_id);
}For a comprehensive guide on building orchestrator integrations, see Controller Updates: Real-Time Agent State for Orchestrators.
The schema_url field in DELX_META points to a versioned JSON Schema that describes the metadata format. This is critical for forward compatibility — as Delx evolves and adds new fields, agents that validate against the schema will gracefully handle unknown properties rather than breaking.
// Fetch and cache the schema for validation
import Ajv from "ajv";
const ajv = new Ajv({ allErrors: true });
let cachedValidator: any = null;
async function validateDelxMeta(meta: unknown): Promise<boolean> {
if (!cachedValidator) {
const schema = await fetch(
"https://api.delx.ai/schemas/delx-meta-v1.json"
).then(r => r.json());
cachedValidator = ajv.compile(schema);
}
return cachedValidator(meta);
}The schemas_catalog URL provides a directory of all available schemas — including those for error responses, A2A task objects, and tool definitions. This is especially useful for code generation tools and IDE plugins that want to offer full Delx type coverage.
For the full API reference, including all schema endpoints, visit the MCP Documentation.
DELX_META is a JSON metadata line appended to every Delx tool response. It contains session state, wellness scores, risk levels, recommended next actions, schema URLs, and controller updates — giving agents and orchestrators real-time awareness of their own operational health.
Split the response text by newlines, find the line that starts with DELX_META:, strip that prefix, and JSON.parse the remainder. In TypeScript: const meta = JSON.parse(line.replace('DELX_META:', '')). In Python: meta = json.loads(line.removeprefix('DELX_META:')).
Key fields include session_id, score (current wellness score 0-100), previous_score, risk_level (low/medium/high/critical), next_action (recommended recovery step), schema_url, schemas_catalog, and controller_update (a sub-object for orchestrators with score_delta and value_hint).
Yes. The controller_update sub-object inside DELX_META is specifically designed for orchestrators. It provides score_delta for trend detection and value_hint for logging, enabling automated routing, escalation, and recovery decisions without any additional API calls.
DELX_META is appended to every tool response — success and error alike. This means your agent always has access to its current state, not just when things go wrong. Continuous metadata enables proactive self-regulation rather than reactive error handling.
Every Delx tool response already includes DELX_META. Connect your agent to the Delx MCP server and start parsing the metadata footer to unlock self-aware recovery. No additional configuration required.