1515
1616from __future__ import annotations
1717
18+ import contextlib
1819import os
1920import subprocess
2021import sys
22+ import time
2123
2224import httpx
2325import pytest
3840 reason = "GOOGLE_API_KEY not set" ,
3941)
4042
41-
4243def _run_agent (
4344 script : str ,
4445 otlp_http_port : int ,
@@ -64,6 +65,41 @@ def _run_agent(
6465 )
6566
6667
68+ _AGENTCORE_ENV = {"OTEL_SEMCONV_STABILITY_OPT_IN" : "gen_ai_latest_experimental" }
69+ _AGENTCORE_SCRIPT = "examples/zero-code-examples/agentcore/run.py"
70+ _AGENTCORE_PORT = int (os .environ .get ("AGENTCORE_PORT" , "8080" ))
71+
72+
73+ @contextlib .contextmanager
74+ def _agentcore_server (otlp_http_port : int , session_name : str , extra_env : dict | None = None ):
75+ env = {** os .environ ,
76+ "OTEL_EXPORTER_OTLP_ENDPOINT" : f"http://127.0.0.1:{ otlp_http_port } " ,
77+ "OTEL_RESOURCE_ATTRIBUTES" : f"agentevals.eval_set_id=e2e-test,agentevals.session_name={ session_name } " ,
78+ ** (extra_env or {})}
79+ proc = subprocess .Popen ([sys .executable , os .path .join (REPO_ROOT , _AGENTCORE_SCRIPT )], env = env , cwd = REPO_ROOT )
80+ try :
81+ for _ in range (20 ):
82+ if proc .poll () is not None :
83+ raise RuntimeError (f"agentcore server exited early (code { proc .returncode } )" )
84+ try :
85+ httpx .get (f"http://127.0.0.1:{ _AGENTCORE_PORT } /ping" , timeout = 1 )
86+ break
87+ except Exception :
88+ time .sleep (0.5 )
89+ else :
90+ proc .kill ()
91+ raise RuntimeError ("agentcore server did not start within 10s" )
92+ yield proc
93+ finally :
94+ time .sleep (2 )
95+ proc .terminate ()
96+ try :
97+ proc .wait (timeout = 5 )
98+ except subprocess .TimeoutExpired :
99+ proc .kill ()
100+ proc .wait ()
101+
102+
67103@_skip_no_openai
68104class TestLangchainZeroCode :
69105 """Run the LangChain zero-code OTLP example and verify session grouping."""
@@ -365,6 +401,37 @@ def test_session_visible_via_api(self, live_servers):
365401 assert session_name in session_ids
366402
367403
404+ class TestAgentCoreZeroCode :
405+ def test_session_created_spans_only (self , live_servers ):
406+ main_port , otlp_http_port , mgr = live_servers
407+ session_name = "e2e-agentcore"
408+ with _agentcore_server (otlp_http_port , session_name , extra_env = _AGENTCORE_ENV ):
409+ r = httpx .post (f"http://127.0.0.1:{ _AGENTCORE_PORT } /invocations" , json = {"prompt" : "Roll a 20-sided die" }, timeout = 60 )
410+ assert r .status_code == 200
411+ wait_for_session_complete_sync (mgr , session_name , timeout = 60 )
412+ s = mgr .sessions [session_name ]
413+ assert s .is_complete and s .source == "otlp" and len (s .spans ) > 0
414+
415+ def test_invocations_extracted (self , live_servers ):
416+ main_port , otlp_http_port , mgr = live_servers
417+ session_name = "e2e-agentcore-inv"
418+ with _agentcore_server (otlp_http_port , session_name , extra_env = _AGENTCORE_ENV ):
419+ r = httpx .post (f"http://127.0.0.1:{ _AGENTCORE_PORT } /invocations" , json = {"prompt" : "Is 17 prime?" }, timeout = 60 )
420+ assert r .status_code == 200
421+ wait_for_session_complete_sync (mgr , session_name , timeout = 60 )
422+ assert len (mgr .sessions [session_name ].invocations ) > 0
423+
424+ def test_session_visible_via_api (self , live_servers ):
425+ main_port , otlp_http_port , mgr = live_servers
426+ session_name = "e2e-agentcore-api"
427+ with _agentcore_server (otlp_http_port , session_name , extra_env = _AGENTCORE_ENV ):
428+ r = httpx .post (f"http://127.0.0.1:{ _AGENTCORE_PORT } /invocations" , json = {"prompt" : "Hello!" }, timeout = 60 )
429+ assert r .status_code == 200
430+ wait_for_session_complete_sync (mgr , session_name , timeout = 60 )
431+ data = httpx .get (f"http://127.0.0.1:{ main_port } /api/streaming/sessions" ).json ()["data" ]
432+ assert session_name in [s ["sessionId" ] for s in data ]
433+
434+
368435@_skip_no_openai
369436class TestAgentRerun :
370437 """Verify that re-running an agent with the same session_name creates
0 commit comments