A multi-agent workflow for processing audio, image, and video data.
Project description
async-media-agents
Async Multi-Agent POC using LangGraph + FastMCP + real media processing.
Overview
A lightweight async multi-agent system that processes images, audio, and video via base64-encoded payloads. Uses LangGraph for workflow orchestration, FastMCP for tool registration, and real processing libraries (Pillow, OpenCV, stdlib wave).
Architecture
User Request
|
SupervisorAgent
|
Fan-out (parallel conditional edge)
┌──────────┼──────────┐
| | |
ImageAgent AudioAgent VideoAgent
| | |
Pillow stdlib wave OpenCV
processor processor processor
| | |
└──────────┼──────────┘
Fan-in to Aggregator
Features
- ✅ Real media processing — Powered by Pillow (Images), OpenCV (Video), and stdlib
wave(Audio). - ✅ Parallel execution — High-performance fan-out/fan-in orchestration using LangGraph.
- ✅ MCP Integration — Model Context Protocol support via FastMCP for tool registration.
- ✅ Robust error handling — Graceful recovery from corrupt base64 or invalid formats.
- ✅ Shared state — Concurrent-safe state management via
Annotatedreducers. - ✅ Type Safety — Comprehensive static analysis with
basedpyright.
Requirements
langgraph
langchain
fastmcp
Pillow
opencv-python-headless
numpy
pytest
pytest-asyncio
Setup
1. Create and activate a virtual environment
# Create the virtual environment
python -m venv .venv
# Activate it
source .venv/bin/activate # Linux / macOS
.venv\Scripts\activate # Windows (cmd)
2. Install dependencies
pip install -r requirements.txt
Project Structure
project/
├── async_media_agents/
│ ├── agents/
│ │ ├── image_agent.py # Specialized image logic
│ │ ├── audio_agent.py # Specialized audio logic
│ │ ├── video_agent.py # Specialized video logic
│ │ └── supervisor.py # Orchestration & routing
│ │
│ ├── tools/
│ │ ├── mcp_server.py # FastMCP server registration
│ │ ├── mcp_client.py # Async client interface
│ │ └── processors/ # Pure processing logic (decoupled)
│ │ ├── image_processor.py # Pillow-based
│ │ ├── audio_processor.py # stdlib wave
│ │ └── video_processor.py # OpenCV-based
│ │
│ ├── graph/
│ │ └── workflow.py # LangGraph workflow definition
│ │
│ ├── state/
│ │ ├── state.py # Shared AgentState with reducers
│ │ └── shared_memory.py # Global shared context utilities
│ │
│ └── __init__.py
│
├── scripts/
│ └── test_workflow.py # Integration & payload tests
│
├── main.py # CLI demo & examples
├── requirements.txt
├── pyproject.toml # Project & Tool configuration
└── README.md
Usage
Run the demo
python main.py
The demo demonstrates three core patterns:
- Text-based routing — Auto-detects task type from user natural language.
- Parallel processing — Simultaneously processes multiple media types via fan-out.
- Supervisor workflow — Uses the Supervisor agent to route to a single target.
Run tests
Tests can be executed directly or through pytest:
# Direct execution (includes payload generation logs)
python scripts/test_workflow.py
# Using pytest
pytest scripts/test_workflow.py
The test suite covers:
- Base64 payload integrity (PNG, WAV, MP4)
- Real metadata extraction via processors
- Parallel transport through the workflow
- Partial payload handling
- Robust error handling for corrupted data
Programmatic use
from async_media_agents.graph.workflow import Workflow
wf = Workflow()
# Text-based — auto-routes to image/audio/video agent
result = await wf.run("Analyze this image")
# Parallel — feeds base64 to all three agents
result = await wf.run_parallel(
image_data="base64_encoded_png",
audio_data="base64_encoded_wav",
video_data="base64_encoded_mp4",
)
Processing Pipeline
| Media | Library | Extracted Metadata |
|---|---|---|
| Image | Pillow | width, height, format, mode, thumbnail |
| Audio | stdlib wave |
duration, sample rate, channels, sample width, frames |
| Video | opencv-python-headless | duration, fps, resolution, frame count, dimensions |
All processors return structured dicts: {"status": "success", "metadata": {...}} or {"status": "error", "error": "..."}.
Static Analysis
The project uses basedpyright for type checking:
pip install basedpyright
basedpyright .
Configuration lives in pyproject.toml under [tool.pyright].
State Management
AgentState extends MessagesState with custom fields. Fields written concurrently during parallel fan-out use Annotated reducers for safe merging:
results—_merge_resultsdict mergemetadata—_merge_resultsdict mergecurrent_agent—_last_winserror—_last_wins
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file async_media_agents-0.1.0.tar.gz.
File metadata
- Download URL: async_media_agents-0.1.0.tar.gz
- Upload date:
- Size: 17.4 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
b73ce20cb2860e45a6acd26f5eaf5c90a2761be333418acaafd44bc437e72396
|
|
| MD5 |
49cfe83b8328dd743376931f997d25cc
|
|
| BLAKE2b-256 |
257b364290c7b03a843382c3e37c3a97621c73222167edf8b29a54ea4aace48d
|
Provenance
The following attestation bundles were made for async_media_agents-0.1.0.tar.gz:
Publisher:
publish.yml on Abka012/async-media-agents
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
async_media_agents-0.1.0.tar.gz -
Subject digest:
b73ce20cb2860e45a6acd26f5eaf5c90a2761be333418acaafd44bc437e72396 - Sigstore transparency entry: 1757427635
- Sigstore integration time:
-
Permalink:
Abka012/async-media-agents@e8f723bd8f9d2db18bb59ea60e7bb4561e0cdd9f -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/Abka012
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@e8f723bd8f9d2db18bb59ea60e7bb4561e0cdd9f -
Trigger Event:
push
-
Statement type:
File details
Details for the file async_media_agents-0.1.0-py3-none-any.whl.
File metadata
- Download URL: async_media_agents-0.1.0-py3-none-any.whl
- Upload date:
- Size: 21.5 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
6a74f140b67e7e3ace1cc5dd51429696d7f84a54248cbcd0f0a44d2e98afa68a
|
|
| MD5 |
be8628d1e62de5e8c0caf8eb21e4d9ee
|
|
| BLAKE2b-256 |
2aab9425dff56cf2d1c6ccdb3c6a40f20f83063cca0c5252d32f7ca7b0dd188c
|
Provenance
The following attestation bundles were made for async_media_agents-0.1.0-py3-none-any.whl:
Publisher:
publish.yml on Abka012/async-media-agents
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
async_media_agents-0.1.0-py3-none-any.whl -
Subject digest:
6a74f140b67e7e3ace1cc5dd51429696d7f84a54248cbcd0f0a44d2e98afa68a - Sigstore transparency entry: 1757427805
- Sigstore integration time:
-
Permalink:
Abka012/async-media-agents@e8f723bd8f9d2db18bb59ea60e7bb4561e0cdd9f -
Branch / Tag:
refs/tags/v0.1.1 - Owner: https://github.com/Abka012
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@e8f723bd8f9d2db18bb59ea60e7bb4561e0cdd9f -
Trigger Event:
push
-
Statement type: