Agent Observability Python Framework Module: Strands Agents
agento11y-strands provides a Strands HookProvider bridge that maps agent, model, and tool lifecycle events into agento11y generation and tool recording.
Installation
pip install agento11y agento11y-strands
pip install strands-agents
Requires strands-agents>=1.36.0. That is the first release to attach token usage to the assistant message, which is the only place AfterModelCallEvent exposes it. On older versions generations are still recorded, but always without token counts or cost.
Quickstart
from agento11y import Client
from agento11y_strands import with_agento11y_strands_hooks
from strands import Agent
# Client() exports generations. Configure an OTel MeterProvider as shown below
# when you also want Usage/Cost and latency metrics.
client = Client()
agent_config = with_agento11y_strands_hooks(
{"name": "support-agent"},
client=client,
provider_resolver="auto",
)
agent = Agent(**agent_config)
agent(
"Explain what LLM observability is in one sentence.",
invocation_state={"conversation_id": "demo-strands"},
)
client.shutdown()
Generation Export vs. OTLP Metrics
Generation export and OpenTelemetry metrics are separate paths. Generation export
makes conversations and generations visible; OTLP metrics power token usage, cost,
latency, and related dashboards. Register a MeterProvider and pass its meter to
the client:
from agento11y import ClientConfig
from opentelemetry import metrics
from opentelemetry.exporter.otlp.proto.http.metric_exporter import OTLPMetricExporter
from opentelemetry.sdk.metrics import MeterProvider
from opentelemetry.sdk.metrics.export import PeriodicExportingMetricReader
from opentelemetry.sdk.resources import Resource
meter_provider = MeterProvider(
resource=Resource.create({"service.name": "my-strands-agent"}),
metric_readers=[
PeriodicExportingMetricReader(
OTLPMetricExporter(
endpoint="https://otlp-gateway-prod-<region>.grafana.net/otlp/v1/metrics",
# Copy the complete Authorization header from the Cloud setup page.
headers={"Authorization": "Basic <base64(instance-id:otlp-token)>"},
)
)
],
)
metrics.set_meter_provider(meter_provider)
client = Client(ClientConfig(meter=meter_provider.get_meter("my-strands-agent")))
try:
# Create and run the instrumented Strands agent here.
pass
finally:
client.shutdown()
meter_provider.shutdown()
Client() now warns when no meter provider is registered and no meter is passed.
This is not fatal because generation export can still be useful, but metrics will
otherwise be lost to OpenTelemetry's no-op provider.
Existing Agents
from agento11y import Client
from agento11y_strands import with_agento11y_strands_hooks
client = Client()
with_agento11y_strands_hooks(agent, client=client, provider_resolver="auto")
Conversation Mapping
Conversation ID precedence:
conversation_id/session_id/group_idfrom Strandsinvocation_statethread_idfrom Strandsinvocation_state- deterministic fallback
agento11y:framework:strands:<run_id>
Pass a stable value per user conversation:
agent("Remember my timezone is UTC+1.", invocation_state={"conversation_id": "customer-42"})
agent("What timezone did I give you?", invocation_state={"conversation_id": "customer-42"})
Metadata and Lineage
Required framework tags:
agento11y.framework.name=strandsagento11y.framework.source=hooksagento11y.framework.language=python
Metadata includes:
- required:
agento11y.framework.run_type - optional:
agento11y.framework.run_id,agento11y.framework.thread_id,agento11y.framework.parent_run_id,agento11y.framework.component_name,agento11y.framework.event_id
Streaming Mode
Generations are recorded as STREAM or SYNC from the model's own configuration. Strands spells the flag three ways, and all of them are read:
params={"stream": False}for OpenAI, LiteLLM, Anthropic and Writer modelsstream=Falsefor Mistral and SageMaker modelsstreaming=Falsefor Bedrock models
Strands defaults every provider to streaming, so a model that sets none of these is recorded as STREAM.
Provider Resolver
Resolver order: explicit provider option -> Strands model config metadata -> model prefix inference -> custom.
BedrockModel exposes the model ID but usually does not expose a provider field. For
standard Bedrock model IDs and inference-profile ARNs, the adapter infers the
underlying vendor (anthropic, meta, mistral, etc.) from the ID. This preserves
model-catalog and cost lookup when the backend has pricing for that model. The exact
model ID and token usage must still be present in the generation.
For custom aliases or IDs that do not contain a recognizable vendor, pass an explicit
provider when creating the hook provider, for example
provider="anthropic". Use the underlying model vendor rather than provider="bedrock"
when you want vendor model-catalog matching.
Multi-agent Runs
The adapter registers Strands multi-agent and node lifecycle hooks. Model calls made
inside an active node are linked beneath that node, while all generations from the
same invocation can be grouped with a shared conversation_id:
state = {"conversation_id": "customer-42"}
root_agent("Delegate this request", invocation_state=state)
This requires Strands' multi-agent APIs to emit their standard node hooks. Agents invoked as ordinary application code or tools need to be instrumented separately.
Troubleshooting
- If conversations are fragmented, pass stable
conversation_idorsession_idininvocation_state. - If generations carry no token usage or cost, check the installed
strands-agentsversion. Usage is only reachable from the model hook on 1.36.0 and later. - If provider is inferred as
custom, setprovider="openai"/provider="anthropic"/provider="gemini"on hook creation. - If cost is zero, verify the exact model ID, underlying vendor provider, and input/output token usage in the generation.
- Always call
client.shutdown()during teardown.
Metadata
Release files for agento11y-strands 0.18.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| agento11y_strands-0.18.0.tar.gz | 19.6 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| agento11y_strands-0.18.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 34.4 kB
Release files / agento11y_strands-0.18.0.tar.gz
| Download URL | agento11y_strands-0.18.0.tar.gz |
|---|---|
| Size | 19.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
e62ea122e1201ab0153964905e86c36891426eed8e0d3e1b6932f1b4e046e872
|
|
BLAKE2b-256 checksum How to use checksums |
6199e28eb3e558fde50b21652b3a8368e402e1f5bb671a73216f8cb884c70fe7
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.13
|
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 Sep 30, 2026.
Transparency logRelease files / agento11y_strands-0.18.0-py3-none-any.whl
| Download URL | agento11y_strands-0.18.0-py3-none-any.whl |
|---|---|
| Size | 14.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
0d06a5bcce4bd2ae76055f6bcbb5d8a692cd4f8283e45fc34c89a0f1a3bf2fd3
|
|
BLAKE2b-256 checksum How to use checksums |
0451a3ee71f6abbaaf1d9bcf823821789ca229277f41f11dc96ae63c86aa8728
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
Yes |
| Uploaded via |
twine/6.1.0 CPython/3.13.13
|
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 Sep 30, 2026.
Transparency log