Skip to main content

Wrap any agent function in a production-ready A2A server

Project description

pgns-agent

Express.js for A2A agents.

PyPI Python License

Wrap any agent function in a production-ready A2A-compatible server, powered by pgns.

from pgns_agent import AgentServer

agent = AgentServer("my-agent", "Echoes input")

@agent.on_task
async def handle(task):
    return {"echo": task.input}

agent.listen(3000)

Quickstart

Install:

pip install pgns-agent

Configure (optional — omit for local dev mode):

export PGNS_API_KEY="your-api-key"

Run:

python agent.py

Your agent is now live. Verify the agent card at http://localhost:3000/.well-known/agent.json.

Features

  • A2A protocol compliance — serves the standard Agent Card at /.well-known/agent.json
  • Auto-provisioning — registers an agent card and roost on the pgns relay at startup
  • Sync + async modes — handlers are always async, but the server can run standalone or embedded
  • SSE streaming — stream task progress updates to callers via Server-Sent Events
  • Task lifecyclesubmitted → working → completed/failed with full status tracking
  • Input-required flow — suspend a handler and request additional input from the caller
  • Pipeline observability — AgentServer records execution stages automatically across every agent in a pipeline
  • Local dev mode — run without a pgns API key for local development and testing

Three entry points

Standalone server — start a self-contained HTTP server:

agent.listen(3000)

Mount into an existing app — get a Starlette/ASGI application to compose with FastAPI, Starlette, or any ASGI framework:

app = agent.app()

Serverless handler — get the raw ASGI callable for Lambda, Cloud Functions, etc.:

handler = agent.handler()

Framework adapters

Adapters let you wire existing agent frameworks into pgns-agent with zero glue code.

LangChain / LangGraph

pip install pgns-agent-langchain
from pgns_agent import AgentServer
from pgns_agent.adapters import LangChainAdapter

agent = AgentServer("my-langchain-agent", "Runs a LangChain chain")
agent.use(LangChainAdapter(my_runnable))
agent.listen(3000)

OpenAI Agents SDK

pip install pgns-agent-openai

Claude Agent SDK

pip install pgns-agent-claude

CrewAI

pip install pgns-agent-crewai

Pipeline observability

AgentServer records execution stages automatically. No instrumentation code required.

Every handler invocation produces a trace stage: agent name, start time, duration, and success or failure. When one agent calls another via agent.send(), the trace propagates automatically through the pipeline. By the time the final agent completes, the trace contains the full execution history — which agents ran, in what order, how long each took, and where failures occurred.

The trace is visible in the pgns dashboard Pipeline Trace Viewer, linked to the correlation ID for the pipeline run.

Annotate stages for richer traces (optional):

@agent.on_task
async def handle(task):
    result = run_my_model(task.input)

    # Optional: annotate the trace stage with output context
    task.trace.annotate(
        output_summary=f"Generated {len(result['text'])} chars",
        metadata={"model": "gpt-4o", "tokens": result["usage"]["total_tokens"]},
    )

    return result

Without annotation, the trace records timing and status. Annotation adds context — useful for debugging latency or inspecting intermediate outputs across a multi-agent pipeline.

Before (manual trace management):

# ~200 lines of boilerplate across a 5-agent pipeline:
# begin_trace, begin_stage, complete_stage, fail_stage,
# append_stage, inject_trace, extract_trace — in every handler
stage = begin_stage("writer")
try:
    result = run_writer(task.input)
    stage = complete_stage(stage, output_summary=result["summary"])
except Exception as e:
    stage = fail_stage(stage, error=str(e))
    raise
finally:
    trace = append_stage(trace, stage)
    payload = inject_trace({"result": result}, trace)

After:

@agent.on_task
async def handle(task):
    return run_writer(task.input)  # trace recorded automatically

Testing

Use the built-in test client for unit testing — no server required:

client = agent.test_client()
resp = client.send_task({"text": "hello"})
assert resp.status == "completed"
assert resp.result == {"echo": {"text": "hello"}}

Documentation

Full documentation is available at docs.pgns.io/libraries/pgns-agent.

License

Apache 2.0

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

pgns_agent-0.2.0.tar.gz (66.2 kB view details)

Uploaded Source

Built Distribution

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

pgns_agent-0.2.0-py3-none-any.whl (42.6 kB view details)

Uploaded Python 3

File details

Details for the file pgns_agent-0.2.0.tar.gz.

File metadata

  • Download URL: pgns_agent-0.2.0.tar.gz
  • Upload date:
  • Size: 66.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for pgns_agent-0.2.0.tar.gz
Algorithm Hash digest
SHA256 c8c70e332924b7aaafe2c7aa0593bdcda69cc3af2ade048e42625a12a33821f4
MD5 7432a86938d0b3b87acaec2b2a19fc89
BLAKE2b-256 e8b35b60cc1109f7484ca6f75fba0f59290b8d755082bbf1da3b47011cc5c235

See more details on using hashes here.

File details

Details for the file pgns_agent-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: pgns_agent-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 42.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for pgns_agent-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 e297b141b3bb011c1de8c63747655dea2687b54449bda35e8dffb14d99ac5c33
MD5 87f72e45653d957b1f36c419dd66b338
BLAKE2b-256 94fef0aa5230a40f69213049ab6bcbd310c4d4b168e2504ee8ca3108d7d2ff68

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