Skip to content

Commit df583f5

Browse files
committed
feat(examples): add AWS AgentCore zero-code OTLP example
1 parent da3ca5e commit df583f5

3 files changed

Lines changed: 63 additions & 1 deletion

File tree

examples/README.md

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,6 +30,7 @@ agentevals accepts OTLP/HTTP on port 4318 (`http/protobuf` and `http/json`) and
3030
| [zero-code-examples/strands/](./zero-code-examples/strands/) | Strands | OpenAI |
3131
| [zero-code-examples/adk/](./zero-code-examples/adk/) | Google ADK | Gemini |
3232
| [zero-code-examples/pydantic-ai/](./zero-code-examples/pydantic-ai/) | Pydantic AI | OpenAI |
33+
| [zero-code-examples/agentcore/](./zero-code-examples/agentcore/) | AWS AgentCore | Amazon Bedrock |
3334

3435
This approach works with any framework that has OTel instrumentation: LangChain, Strands, Google ADK, etc. If your framework already emits OTel spans, you only need to add `OTLPSpanExporter` (and `OTLPLogExporter` if it uses GenAI log-based content delivery).
3536

@@ -105,6 +106,7 @@ Detection checks for `gen_ai.request.model` / `gen_ai.input.messages` (GenAI sem
105106
| [zero-code-examples/strands/](./zero-code-examples/strands/) | Strands | OpenAI | GenAI semconv (events*) | Standard OTLP export |
106107
| [zero-code-examples/adk/](./zero-code-examples/adk/) | Google ADK | Gemini | ADK built-in | Standard OTLP export |
107108
| [zero-code-examples/pydantic-ai/](./zero-code-examples/pydantic-ai/) | Pydantic AI | OpenAI | GenAI semconv (span attrs) | Standard OTLP export |
109+
| [zero-code-examples/agentcore/](./zero-code-examples/agentcore/) | AWS AgentCore | Amazon Bedrock | GenAI semconv (events*) | Standard OTLP export |
108110
| [langchain_agent](./langchain_agent/) | LangChain | OpenAI | GenAI semconv (logs) | SDK WebSocket |
109111
| [strands_agent](./strands_agent/) | Strands | OpenAI | GenAI semconv (events*) | SDK WebSocket |
110112
| [dice_agent](./dice_agent/) | Google ADK | Gemini | ADK built-in | SDK WebSocket |
@@ -220,6 +222,7 @@ python examples/zero-code-examples/ollama/run.py
220222
python examples/zero-code-examples/strands/run.py
221223
python examples/zero-code-examples/adk/run.py
222224
python examples/zero-code-examples/pydantic-ai/run.py
225+
python examples/zero-code-examples/agentcore/run.py
223226

224227
# SDK examples:
225228
python examples/sdk_example/context_manager_example.py
@@ -235,7 +238,7 @@ python examples/strands_agent/main.py
235238
Traces stream to the dev server in real-time. Evaluation runs automatically when the session completes.
236239

237240
See each example's README for prerequisites and detailed instructions:
238-
- [zero-code-examples/](./zero-code-examples/) (LangChain, Strands, ADK, OpenAI Agents, Pydantic AI standard OTLP)
241+
- [zero-code-examples/](./zero-code-examples/) (LangChain, Strands, ADK, OpenAI Agents, Pydantic AI, AWS AgentCore, standard OTLP)
239242
- [dice_agent/README.md](./dice_agent/README.md) (Google ADK + Gemini)
240243
- [langchain_agent/README.md](./langchain_agent/README.md) (LangChain + OpenAI, SDK)
241244
- [strands_agent/](./strands_agent/) (Strands + OpenAI, SDK)
Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,5 @@
1+
strands-agents>=1.35.0
2+
boto3>=1.38.0
3+
opentelemetry-sdk>=1.36.0
4+
opentelemetry-exporter-otlp-proto-http>=1.36.0
5+
python-dotenv>=1.0.0
Lines changed: 54 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,54 @@
1+
"""AWS AgentCore zero-code OTLP example. Needs AWS credentials and Nova Pro model access.
2+
Run: python examples/zero-code-examples/agentcore/run.py
3+
"""
4+
5+
import os
6+
import random
7+
8+
from dotenv import load_dotenv
9+
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
10+
from opentelemetry.sdk.trace.export import BatchSpanProcessor
11+
from strands import Agent, tool
12+
from strands.models import BedrockModel
13+
from strands.telemetry import StrandsTelemetry
14+
15+
load_dotenv(override=True)
16+
os.environ.setdefault("OTEL_SEMCONV_STABILITY_OPT_IN", "gen_ai_latest_experimental")
17+
18+
19+
@tool
20+
def roll_die(sides: int = 6) -> dict:
21+
"""Roll a die with the given number of sides."""
22+
result = random.randint(1, sides)
23+
return {"sides": sides, "result": result, "message": f"Rolled a {sides}-sided die and got {result}"}
24+
25+
26+
@tool
27+
def check_prime(n: int) -> bool:
28+
"""Return True if number is prime."""
29+
return n >= 2 and all(n % i for i in range(2, int(n**0.5) + 1))
30+
31+
32+
def main():
33+
if not os.getenv("AWS_DEFAULT_REGION"):
34+
print("AWS_DEFAULT_REGION not set.")
35+
return
36+
os.environ.setdefault("OTEL_RESOURCE_ATTRIBUTES",
37+
"agentevals.eval_set_id=agentcore_eval,agentevals.session_name=agentcore-zero-code")
38+
telemetry = StrandsTelemetry()
39+
telemetry.tracer_provider.add_span_processor(BatchSpanProcessor(OTLPSpanExporter(), schedule_delay_millis=1000))
40+
agent = Agent(
41+
model=BedrockModel(model_id="us.amazon.nova-pro-v1:0"),
42+
tools=[roll_die, check_prime],
43+
system_prompt="You are a helpful assistant. Use roll_die when asked to roll dice. Use check_prime when asked about prime numbers.",
44+
name="dice_agent",
45+
)
46+
queries = ["Hi! Can you help me?", "Roll a 20-sided die for me", "Is the number you rolled prime?"]
47+
for i, query in enumerate(queries, 1):
48+
print(f"\n[{i}/{len(queries)}] User: {query}\n Agent: {agent(query)}")
49+
telemetry.tracer_provider.force_flush()
50+
print("All traces flushed.")
51+
52+
53+
if __name__ == "__main__":
54+
main()

0 commit comments

Comments
 (0)