Skip to main content

astropods-adapter-core

Framework-agnostic bridge between Python agents and the Astropods messaging service.

Installation

pip install astropods-adapter-core

Requires Python 3.10+.

Usage

If you're using a supported framework, use the pre-built adapter package instead (e.g. astropods-adapter-langchain). Use this package directly to connect a custom or unsupported framework.

Create a class with name, stream, and get_config, then call serve():

from astropods_adapter_core import StreamHooks, StreamOptions, serve

class MyAdapter:
    name = "My Agent"

    async def stream(self, prompt: str, hooks: StreamHooks, options: StreamOptions) -> None:
        try:
            hooks.on_chunk("Hello!")
            hooks.on_finish()
        except Exception as e:
            hooks.on_error(e)

    def get_config(self) -> dict:
        return {"system_prompt": "You are a helpful assistant.", "tools": []}

serve(MyAdapter())

serve() blocks until SIGINT or SIGTERM. Under ast dev, GRPC_SERVER_ADDR is injected automatically.

API

AgentAdapter protocol

Member Description
name: str Display name used in logs and registration
async stream(prompt, hooks, options) Stream a response, invoking hooks as the agent progresses
get_config() -> dict Return {"system_prompt": str, "tools": [...]} for playground display

StreamHooks

Call these inside stream() as the agent produces output:

Method When to call
on_chunk(text) Each text token or fragment from the LLM
on_status_update({"status": "..."}) Agent state change — valid values: THINKING, SEARCHING, GENERATING, PROCESSING, ANALYZING, CUSTOM
on_finish() Response complete — call exactly once per request
on_error(exception) Error occurred — call instead of on_finish

on_trace_context(trace_context) is optional; call it with getattr when a turn has W3C trace context.

For CUSTOM status, include "custom_message" in the dict:

hooks.on_status_update({"status": "CUSTOM", "custom_message": "Fetching data..."})

create_traceparent(*, trace_id, span_id, trace_flags="01")

Formats a native trace/span ID pair into a W3C traceparent string to hand to on_trace_context. Returns "" for invalid or all-zero IDs, so it's safe to pass raw OpenTelemetry span context. trace_flags accepts an int or hex string and defaults to "01" (sampled).

from astropods_messaging import TraceContext
from astropods_adapter_core import create_traceparent

ctx = span.get_span_context()
traceparent = create_traceparent(
    trace_id=f"{ctx.trace_id:032x}",
    span_id=f"{ctx.span_id:016x}",
    trace_flags=int(ctx.trace_flags),
)
if traceparent:
    on_trace_context = getattr(hooks, "on_trace_context", None)
    if on_trace_context is not None:
        on_trace_context(TraceContext(traceparent=traceparent))

StreamOptions

Per-request context passed to stream():

Field Description
conversation_id Stable ID for the conversation thread
user_id ID of the user who sent the message
user_name The sender's name on the source platform, such as their full name in Slack. Empty when the platform sent none.
platform_context Optional[PlatformContext] — platform-specific fields (channel, thread, workspace, event kind). None for messages from non-platform sources (playground, direct gRPC).
history Optional[HistoryInput]: the turns before this message, set only when they differ from what the agent last answered. Replace what you store for conversation_id with history.messages, then handle the prompt. Report "supports_history": True from get_config(); the chat offers message editing only then.

Using platform_context

PlatformContext exposes the source-event fields adapters often need to branch on — the channel and thread to reply into, the workspace, the bot's own user ID, and an event_kind enum that distinguishes a DM from an @-mention from a thread reply without having to inspect message content.

from astropods_adapter_core import PlatformContext, StreamHooks, StreamOptions

async def stream(self, prompt, hooks: StreamHooks, options: StreamOptions) -> None:
    pc = options.platform_context
    if pc and pc.event_kind == PlatformContext.EVENT_KIND_APP_MENTION:
        hooks.on_chunk(f"You @-mentioned me in {pc.channel_name or pc.channel_id}.")
    else:
        hooks.on_chunk("Hello!")
    hooks.on_finish()

Always null-check first — platform_context is None for messages from the playground or direct gRPC clients. See PlatformContext for the full field list.

serve(adapter, options?)

Connects the adapter to the messaging service and blocks until shutdown.

from astropods_adapter_core import ServeOptions, serve

# Override the gRPC address (default: GRPC_SERVER_ADDR env var or localhost:9090)
serve(adapter, ServeOptions(server_address="astro-messaging:9090"))

MessagingBridge

serve() is a thin wrapper around MessagingBridge. Use it directly if you need lifecycle control:

import asyncio
from astropods_adapter_core import MessagingBridge

bridge = MessagingBridge(adapter)
asyncio.run(bridge.start())

Connections

A connection is a third-party account, such as GitHub, that the chatting user lets the agent use as them. Install the connections extra:

pip install "astropods-adapter-core[connections]"
from astropods_adapter_core.connections import ConnectionClient, ConnectionTokenError

connections = ConnectionClient()

token = connections.get_token("github", user_id)
token = await connections.get_token_async("github", user_id)

ConnectionClient() reads ASTRO_AUTHZ_TOKEN and takes the server URL from it. The server returns a token only for a user who allowed this agent and has messaged it in web chat in the last 15 minutes. A refusal raises ConnectionTokenError with code set to not_consented, not_active, not_connected, needs_reauthorization, or unavailable.

Metadata

Release files for astropods-adapter-core 0.10.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for astropods-adapter-core 0.10.0
File Size Uploaded Provenance Actions
astropods_adapter_core-0.10.0.tar.gz 37.1 kB With provenance Details for astropods_adapter_core-0.10.0.tar.gz

Built distribution (wheel)

Table of built distributions (wheels) for astropods-adapter-core 0.10.0
File Interpreter ABI Platform Actions
astropods_adapter_core-0.10.0-py3-none-any.whl Python 3 none any Details for astropods_adapter_core-0.10.0-py3-none-any.whl

Total release size: 66.3 kB

Release files / astropods_adapter_core-0.10.0.tar.gz

Download URL astropods_adapter_core-0.10.0.tar.gz
Size 37.1 kB
Tags Source
SHA-256 checksum
How to use checksums
9c161ec0ec2009595c0b0cd447be702330d3e2b9ca60c37f96fd4d71cdb9addb
BLAKE2b-256 checksum
How to use checksums
ef6ee5b85733fb46b71dce19c19e970207a3258b899c8c16840f88d37375f939
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 15, 2026.

Transparency log

Release files / astropods_adapter_core-0.10.0-py3-none-any.whl

Download URL astropods_adapter_core-0.10.0-py3-none-any.whl
Size 29.2 kB
Tags Python 3
SHA-256 checksum
How to use checksums
d3a7d4afc4c5ecd0b1f6f9f8e8591120ce6e6a2ed7e09715aff630b71fbe61c5
BLAKE2b-256 checksum
How to use checksums
5bfe3cde4ac3ad664e2b267c1d698c460767f3157a32a2a7afa274a876d25616
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 15, 2026.

Transparency log

Security for astropods-adapter-core 0.10.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Full provenance

All 2 files in this release have been uploaded with provenance metadata.

Select from 2 files

Attestation for astropods_adapter_core-0.10.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 15, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page