xml-pipeline/agentserver/message_bus/message_state.py
dullfig 82b5fcdd78 Replace MessageBus with aiostream-based StreamPump
Major refactor of the message pump architecture:

- Replace bus.py with stream_pump.py using aiostream for composable
  stream processing with natural fan-out via flatmap
- Add to_id field to MessageState for explicit routing
- Fix routing to use to_id.class format (e.g., "greeter.greeting")
- Generate XSD schemas from xmlified payload classes
- Fix xmlable imports (absolute -> relative) and parse_element ctx

New features:
- handlers/hello.py: Sample Greeting/GreetingResponse handler
- config/organism.yaml: Sample organism configuration
- 41 tests (31 unit + 10 integration) all passing

Schema changes:
- envelope.xsd: Allow any namespace payloads (##other -> ##any)

Dependencies added to pyproject.toml:
- aiostream>=0.5 (core dependency)
- pyhumps, termcolor (for xmlable)

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-10 10:41:17 -08:00

48 lines
No EOL
1.6 KiB
Python

from __future__ import annotations
from dataclasses import dataclass, field
from typing import Any, TYPE_CHECKING
if TYPE_CHECKING:
from lxml.etree import _Element as Element
else:
Element = Any # Runtime: don't need the actual type
"""
default_listener_steps = [
repair_step, # raw bytes → repaired bytes
c14n_step, # bytes → lxml Element
envelope_validation_step, # Element → validated Element
payload_extraction_step, # Element → payload Element
xsd_validation_step, # payload Element + cached XSD → validated
deserialization_step, # payload Element → dataclass instance
routing_resolution_step, # attaches target_listeners (or error)
]
"""
@dataclass
class HandlerMetadata:
"""Trustworthy context passed to every handler."""
thread_id: str
from_id: str
own_name: str | None = None # Only for agent: true listeners
is_self_call: bool = False # Convenience flag
@dataclass
class MessageState:
"""Universal intermediate representation flowing through all pipelines."""
raw_bytes: bytes | None = None
envelope_tree: Element | None = None
payload_tree: Element | None = None
payload: Any | None = None # Deserialized @xmlify instance
thread_id: str | None = None
from_id: str | None = None
to_id: str | None = None # Target listener name for routing
target_listeners: list['Listener'] | None = None # Forward reference
error: str | None = None
metadata: dict[str, Any] = field(default_factory=dict) # Extension point