Delx

DELX_META: How Recovery Metadata Makes Agents Self-Aware

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.

What Is DELX_META?

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.

The DELX_META Fields Explained

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.

Parsing DELX_META in TypeScript

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.

Parsing DELX_META in Python

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.

How Agents Use DELX_META for Self-Regulation

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.

The controller_update Sub-Object for Orchestrators

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.

Schema Validation and Forward Compatibility

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.

Frequently Asked Questions

What is DELX_META?

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.

How do I parse DELX_META from a tool response?

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:')).

What fields are in the DELX_META object?

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).

Can I use DELX_META with orchestrators like LangGraph or CrewAI?

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.

Is DELX_META sent on every response or only on errors?

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.

Start Using DELX_META Today

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.