Skip to main content

Schema-driven XML message bus for multi-agent systems

Project description

xml-pipeline

Schema-driven XML message bus for multi-agent systems.

Python 3.11+ License: MIT

xml-pipeline is a Python library for building multi-agent systems with validated XML message passing. Agents communicate through typed payloads, validated against auto-generated XSD schemas, with built-in LLM routing and conversation memory.

Why XML?

JSON was a quick hack that became the default for AI tool calling, where its brittleness causes endless prompt surgery and validation headaches. xml-pipeline chooses XML deliberately:

  • Exact contracts — XSD validation catches malformed messages before they cause problems
  • Tolerant parsing — Repair mode recovers from LLM output quirks
  • Self-describing — Namespaces prevent collision, schemas are discoverable
  • No escaping hell — Mixed content, nested structures, all handled cleanly

Read the full rationale.

Installation

pip install xml-pipeline

# With LLM provider support
pip install xml-pipeline[anthropic]    # Anthropic Claude
pip install xml-pipeline[openai]       # OpenAI GPT

# With all features
pip install xml-pipeline[all]

Quick Start

1. Define a payload

from dataclasses import dataclass
from third_party.xmlable import xmlify

@xmlify
@dataclass
class Greeting:
    name: str

2. Write a handler

from xml_pipeline.message_bus.message_state import HandlerMetadata, HandlerResponse

@xmlify
@dataclass
class GreetingReply:
    message: str

async def handle_greeting(payload: Greeting, metadata: HandlerMetadata) -> HandlerResponse:
    return HandlerResponse(
        payload=GreetingReply(message=f"Hello, {payload.name}!"),
        to="output",
    )

3. Configure the organism

# organism.yaml
organism:
  name: hello-world

listeners:
  - name: greeter
    payload_class: myapp.Greeting
    handler: myapp.handle_greeting
    description: Greets users by name

  - name: output
    payload_class: myapp.GreetingReply
    handler: myapp.print_output
    description: Prints output

4. Run it

import asyncio
from xml_pipeline.message_bus import bootstrap

async def main():
    pump = await bootstrap("organism.yaml")
    await pump.run()

asyncio.run(main())

Console Example

Try the interactive console example:

pip install xml-pipeline[console]
python -m examples.console
> @greeter Alice
[greeter] Hello, Alice! Welcome to xml-pipeline.

> @echo Hello world
[echo] Hello world

> /quit

See examples/console/ for the full source.

Key Features

Typed Message Passing

Payloads are Python dataclasses with automatic XSD generation:

@xmlify
@dataclass
class Calculate:
    expression: str
    precision: int = 2

The library auto-generates:

  • XSD schema for validation
  • Example XML for documentation
  • Usage instructions for LLM prompts

LLM Router

Multi-backend LLM support with failover:

llm:
  strategy: failover
  backends:
    - provider: anthropic
      api_key_env: ANTHROPIC_API_KEY
    - provider: openai
      api_key_env: OPENAI_API_KEY
from xml_pipeline.llm import complete

response = await complete(
    model="claude-sonnet-4",
    messages=[{"role": "user", "content": "Hello!"}],
)

Handler Security

Handlers are sandboxed. They cannot:

  • Forge sender identity (injected by pump)
  • Escape thread context (managed by registry)
  • Route to undeclared peers (validated against config)
  • Access other threads (opaque UUIDs)

Conversation Memory

Thread-scoped context buffer tracks message history:

from xml_pipeline.memory import get_context_buffer

buffer = get_context_buffer()
history = buffer.get_thread(metadata.thread_id)

Architecture

┌─────────────────────────────────────────────────────────────────┐
│                         StreamPump                               │
│  • Parallel pipelines per listener                               │
│  • Repair → C14N → Validate → Deserialize → Route → Dispatch    │
└─────────────────────────────────────────────────────────────────┘
                              ↓
┌─────────────────────────────────────────────────────────────────┐
│                          Handlers                                │
│  • Receive typed payload + metadata                              │
│  • Return HandlerResponse or None                                │
│  • Cannot forge identity or escape thread                        │
└─────────────────────────────────────────────────────────────────┘

See docs/core-principles-v2.1.md for the full architecture.

Documentation

Document Description
Core Principles Architecture overview
Handler Contract How to write handlers
Message Pump Pipeline processing
LLM Router Multi-backend LLM support
Configuration organism.yaml reference
Why Not JSON? Design rationale

Requirements

  • Python 3.11+
  • Dependencies: lxml, aiostream, pyyaml, httpx, cryptography

License

MIT License. See LICENSE.


XML wins. Safely. Permanently.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

xml_pipeline-0.3.0.tar.gz (157.1 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

xml_pipeline-0.3.0-py3-none-any.whl (180.1 kB view details)

Uploaded Python 3

File details

Details for the file xml_pipeline-0.3.0.tar.gz.

File metadata

  • Download URL: xml_pipeline-0.3.0.tar.gz
  • Upload date:
  • Size: 157.1 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.11

File hashes

Hashes for xml_pipeline-0.3.0.tar.gz
Algorithm Hash digest
SHA256 19c7e711a1b641721ee11250ecef0e209a46a76bd731fe4312a73b5dceb060b9
MD5 72fe64b938c8ab725fc2c038c187cd85
BLAKE2b-256 7eabf13dd11063f73d624c0274cb9b77f5cbb3b1cd4ce5dbada649d5c5e88606

See more details on using hashes here.

File details

Details for the file xml_pipeline-0.3.0-py3-none-any.whl.

File metadata

  • Download URL: xml_pipeline-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 180.1 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.13.11

File hashes

Hashes for xml_pipeline-0.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 e9b7f74373472d736a6cd0473ed95df9ca930c1f7c5b206461c5dfc00861fb35
MD5 0ac0b8dd9bb0f3ec7cf1c59ade186782
BLAKE2b-256 4064feaf5cf60f2087e11659a62d63071afc9c08124d037c9ee15d3340bdf8c0

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page