{"slug": "compose-ai-agents-like-reusable-components", "title": "Compose AI agents like reusable components", "summary": "A developer introduced Agent Markup Language (AML), a JSX-based framework for composing AI agents as reusable components, enabling explicit dataflow and parallel execution. The Codex SDK provides a low-level thread API, while AML abstracts orchestration into a declarative component model.", "body_md": "Imagine composing AI assistants the way you create reusable React components.\n\nOne agent reviews correctness. Another plans the tests. Their outputs flow into a third agent that produces one release recommendation.\n\n```\nCorrectness ──┐\n              ├──> Synthesis ──> Release recommendation\nTest plan ────┘\n```\n\nThat is agent composition: small specialists, explicit dataflow, one final result.\n\nThe [Codex SDK](https://github.com/openai/codex/tree/main/sdk/typescript) gives TypeScript applications a clean thread-and-turn API. Composing several threads is still your application's job:\n\n``` js\nimport { Codex } from \"@openai/codex-sdk\"\n\nconst codex = new Codex()\n\nasync function run(prompt: string) {\n  const thread = codex.startThread()\n  return (await thread.run(prompt)).finalResponse\n}\n\nconst correctness = await run(\"Review the current diff for correctness defects.\")\nconst tests = await run(\"Write the smallest useful test plan for the current diff.\")\n\nconst coordinator = codex.startThread()\nconst result = await coordinator.run(`\nWrite one release recommendation from these reports.\nDo not invent findings.\n\nCORRECTNESS\n${correctness}\n\nTEST PLAN\n${tests}\n`)\n\nconsole.log(result.finalResponse)\n```\n\nThis is perfectly reasonable TypeScript. It also makes the application responsible for threads, execution order, result extraction, and prompt assembly. As the workflow grows, the glue becomes the thing you spend time reading.\n\n[Agent Markup Language](https://aml.wearesingular.com/) puts that composition into TypeScript and JSX:\n\n```\nfunction ReleaseReview() {\n  return (\n    <Agent provider={Codex} system=\"Synthesize evidence without inventing findings.\">\n      ## Correctness\n      <Agent provider={Codex}>Review the current diff for correctness defects.</Agent>\n      ## Test plan\n      <Agent provider={Codex}>Write the smallest useful test plan.</Agent>\n      Write one release recommendation.\n    </Agent>\n  )\n}\n```\n\nAML runs the two child agents from left to right. Their outputs land exactly where they appear in the parent prompt. The synthesis agent starts after both are ready.\n\nAML is not React, but the component model is deliberately familiar. Functions package behaviour. Props carry inputs. JSX shows which agent receives each result. Ordinary TypeScript handles conditions.\n\nYou can keep the workflow compact, or split a larger one into named specialists:\n\n``` js\nimport { Agent, AmlRuntime, type AmlRenderable, codexAgent, FollowUp } from \"@aml-jsx/sdk\"\n\nconst Codex = codexAgent({})\n\nfunction CorrectnessReview() {\n  return <Agent provider={Codex}>Find concrete correctness defects in the current diff.</Agent>\n}\n\nfunction SecurityReview({ paths }: { paths: readonly string[] }) {\n  return <Agent provider={Codex}>Find security risks in: {paths.join(\", \")}.</Agent>\n}\n\nfunction TestPlan({ children, runner }: { children?: AmlRenderable; runner: string }) {\n  return (\n    <Agent provider={Codex}>\n      Write the smallest useful test plan for {children}. Use {runner}.\n    </Agent>\n  )\n}\n\nfunction DocsImpact({ publicChange }: { publicChange: boolean }) {\n  return publicChange ? (\n    <Agent provider={Codex}>Check whether the current diff changes documented behaviour.</Agent>\n  ) : (\n    \"No public documentation review requested.\"\n  )\n}\n\nfunction ReleaseCouncil({\n  changedFiles,\n  publicChange,\n  target,\n}: {\n  changedFiles: readonly string[]\n  publicChange: boolean\n  target: string\n}) {\n  return (\n    <Agent provider={Codex} system=\"Use only the supplied evidence. Resolve conflicts explicitly.\">\n      # Release evidence for {target}\n      ## Correctness\n      <CorrectnessReview />\n      ## Security\n      <SecurityReview paths={changedFiles} />\n      ## Tests\n      <TestPlan runner=\"npm test\">regressions around {target}</TestPlan>\n      ## Documentation\n      <DocsImpact publicChange={publicChange} />\n      <FollowUp>Decide whether this is ready to release and explain why or why not.</FollowUp>\n    </Agent>\n  )\n}\n\nconst runtime = new AmlRuntime()\nawait runtime.evaluate(\n  <ReleaseCouncil\n    changedFiles={[\"src/auth.ts\", \"src/session.ts\"]}\n    publicChange\n    target=\"the current diff\"\n  />,\n)\n```\n\nThe components now use JSX in different ways: no props, an array prop, nested children, and a boolean that conditionally returns an Agent or plain text. They run in authored order. The parent opens after their outputs have been assembled into its prompt, then `FollowUp`\n\nasks for the release decision in the same session.\n\nSwap a specialist, reuse it elsewhere, or give it a different provider without redesigning the workflow.\n\nThe developer still authors the control flow. Agent output stays data; AML never executes model-generated JSX as a new workflow. Tools and MCP servers also stay scoped to the agent that receives them.\n\nWe are building AML so complex agent systems can be read as composed parts instead of a pile of orchestration glue.\n\nAML is open source, MIT licensed, and under active development. [Read the code, run the examples, and star the repository on GitHub.](https://github.com/we-are-singular/aml)", "url": "https://wpnews.pro/news/compose-ai-agents-like-reusable-components", "canonical_source": "https://dev.to/jtavares/compose-ai-agents-like-reusable-components-3o51", "published_at": "2026-07-30 20:00:51+00:00", "updated_at": "2026-07-30 20:34:35.766707+00:00", "lang": "en", "topics": ["ai-agents", "developer-tools", "large-language-models"], "entities": ["Codex SDK", "Agent Markup Language", "OpenAI"], "alternates": {"html": "https://wpnews.pro/news/compose-ai-agents-like-reusable-components", "markdown": "https://wpnews.pro/news/compose-ai-agents-like-reusable-components.md", "text": "https://wpnews.pro/news/compose-ai-agents-like-reusable-components.txt", "jsonld": "https://wpnews.pro/news/compose-ai-agents-like-reusable-components.jsonld"}}