Response Contracts

Response contracts define the expected output structure from your LLM. They version together with your prompt and are derived automatically from JSON blocks.

Basic Response Contract

response do
  {
    "response_type": "greeting",
    "content": "..."
  }
end response

The compiler derives the schema from the JSON structure:

{
  "type": "object",
  "properties": {
    "response_type": { "type": "string", "enum": ["greeting"] },
    "content": { "type": "string" }
  },
  "required": ["response_type", "content"]
}

Nested Objects

response do
  {
    "user": {
      "name": "...",
      "preferences": {
        "theme": "..."
      }
    }
  }
end response

Multiple Response Blocks

You can have multiple response blocks in different branches. The compiler validates compatibility:

if @is_premium is true do
Premium content here.

response do
  {
    "content": "...",
    "premium_features": ["a", "b", "c"]
  }
end response

else
Free content here.

response do
  {
    "content": "..."
  }
end response

end @is_premium

Compatibility Rules

  • Compatible — Fields in common have matching types
  • Warning — Some fields differ but are compatible
  • Error — Incompatible types for the same field

Using Variables

Reference variables in response contracts:

response do
  {
    "response_type": "teaching",
    "step": @current_step,
    "next_step": @current_step + 1
  }
end response

Contract Validation

The derived schema is returned with every compiled prompt. Your application can validate LLM responses against the contract:

{
  "prompt": "...",
  "response_contract": {
    "type": "object",
    "properties": {
      "response_type": { "type": "string" },
      "content": { "type": "string" }
    }
  }
}

Benefits

  • Automatic schema derivation
  • Versioned with the prompt
  • Breaking change detection
  • Runtime validation support

Next Steps