AI workflows as executable contracts: structuring autonomous agents in TypeScript

2 min readMay 2, 2026#workflow#agent#ia#architecture#mcp#typescript#json

The workflow as an executable contract

Most AI systems are black boxes. You know what they do. You don't know how.

A declarative workflow solves this. The JSON is the documentation, and it runs.


The structure

Each task in a workflow contains:

{
  "id": "generate-wa",
  "name": "Generate WhatsApp messages",
  "prompt": "For each lead in savedLeads, generate a personalized prospecting message via generateMessage(lead, 'whatsapp'). Use the business name, its Google rating, and its digital presence status.",
  "tools": [
    { "name": "generateMessage", "source": "internal" }
  ],
  "input": {
    "leads": {
      "type": "array",
      "source": "${save-leads.output.savedLeads}",
      "required": true
    }
  },
  "output": {
    "messages": { "type": "array" }
  },
  "dependsOn": ["save-leads"]
}

The prompt is natural language. tools lists the functions to use. source in input references a previous task's output.


What this enables

Any AI agent — Claude Code, GPT via API, a local model — can read this JSON and run the workflow with its own tools. dependsOn gives the order. source gives the data lineage.

context = {}
for task in topological_sort(workflow.tasks):
    inputs = resolve_sources(task.input, context)
    result = execute(task, inputs)
    context[task.id] = {"output": result}

It's a contract between the business process and any execution runtime.


The rule

Any repetitive process with defined steps can be modeled as a workflow.

The format guarantees that if the code changes, if the tool changes, if the agent changes — the definition of what needs to happen stays readable and executable.

Documentation that doesn't execute drifts from the code. A workflow that is the execution stays aligned forever.