AAIF

The Agent-to-Agent Interaction Format (AAIF) defines a structured request/response contract for predictable AI interactions. Use it to standardise how your application communicates task intent, cost constraints, and routing context.

Status

AAIF is advanced — the type contract is defined and exported from @restormel/aaif. AAIF runtime helpers are available via executeAAIFRequest(). Before install, verify availability with npm view @restormel/aaif version.

Request

type AAIFRequest = {
  input: string
  task?: "chat" | "completion" | "embedding"
  constraints?: {
    maxCost?: number
    latency?: "low" | "balanced" | "high"
    tokens?: {
      inputTokensM?: number
      outputTokensM?: number
    }
  }
  user?: {
    id: string
    plan?: string
  }
  routing?: {
    model?: string
    provider?: string
  }
  routingContext?: { routeId?: string; workload?: string; stage?: string; /* … */ }
  routingPlan?: { stepChain?: unknown[]; routingAttempts?: unknown[] }
  integrationStack?: {
    schemaVersion: "1"
    templateId?: string
    components: { id: string; role?: string }[]
  }
}

Response

type AAIFResponse = {
  output: string
  provider: string
  model: string
  cost: number
  routing: {
    reason: string
  }
}

Package

Types, runtime guards, and the runtime helper are exported from @restormel/aaif:

import type { AAIFRequest, AAIFResponse } from "@restormel/aaif";
import { isAAIFRequest, isAAIFResponse } from "@restormel/aaif";

Use cases

  • Agent orchestration — standardise how agents request model completions with cost and latency constraints.
  • Routing transparency — responses include the routing reason so callers understand why a provider/model was chosen.
  • Cost control — the maxCost constraint caps estimated spend per request.

Integration stack (optional)

Optional integrationStack on AAIFRequest declares which third-party products appear in the host environment (for example Neon, Vercel, OpenRouter). It is orthogonal to routingContext (resolve hints) and does not change provider selection. Use it for logs, MCP agents, and analytics. Valid components[].id values are exported as INTEGRATION_COMPONENT_IDS from @restormel/aaif; isAAIFRequest() validates the object when present. The Dashboard Overview → Connect your stack wizard copies JSON that passes this guard.

Human index of vendors: Integration catalog.

Routing and resolve

AAIF adds optional routingContext on AAIFRequest so hosts can mirror resolve hints (for example workload, stage, attemptNumber) next to the legacy routing object. AAIF does not call the dashboard resolve HTTP API; for a full stepChain from Keys, use @restormel/keys resolve() (Gateway key) then execute the model in your worker.

Canonical semantics: Routing contract (mirrors docs/keys-routing-contract.md). Agents: MCP docs.canonical_resolve topic keys_routing_contract or suite tool routing.capabilities.

When to choose AAIF vs MCP vs CLI

  • AAIF — your app/service wants a typed contract and runtime helper for routing + cost estimation.
  • MCP — an agent or IDE wants to call Restormel tool surface (routing/cost/validation) via stdio.
  • CLI — you need local, developer-friendly inspection and debugging without embedding into runtime code.

Runtime helper

The AAIF runtime helper resolves provider/model and estimates cost via @restormel/keys. Hosts can optionally provide the final model output via the generate callback.

import { executeAAIFRequest } from "@restormel/aaif";
import { createKeys, openaiProvider } from "@restormel/keys";

const keys = createKeys(
  { routing: { defaultProvider: "openai" }, keys: [{ id: "k1", provider: "openai" }] },
  { providers: [openaiProvider] }
);

const res = await executeAAIFRequest(
  { input: "Summarise…", task: "chat", routing: { model: "gpt-4o-mini" } },
  keys,
  { generate: async (ctx) => "output(cost=" + ctx.cost + ")" }
);

Next steps