diff --git a/examples/haystack_example.py b/examples/haystack_example.py new file mode 100644 index 0000000..eb43cb0 --- /dev/null +++ b/examples/haystack_example.py @@ -0,0 +1,151 @@ +""" +Haystack Basic Example + +Tests: Whether Aden's existing instrumentation captures Haystack's LLM calls. + +Haystack uses actual provider SDKs internally: +- OpenAI: built-in (openai>=1.99.2) +- Anthropic: anthropic-haystack package +- Gemini: google-ai-haystack package + +This example tests if existing aden instrumentation catches the calls. + +Prerequisites: + pip install haystack-ai anthropic-haystack google-ai-haystack + +Run: uv run python examples/haystack_example.py +""" + +import asyncio +import os +import sys + +# Add parent directory to path for local development +sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "src")) + +# Load environment variables from .env file +try: + from dotenv import load_dotenv + load_dotenv() +except ImportError: + pass # dotenv not installed, use shell environment + +from aden import ( + instrument_async, + uninstrument_async, + create_console_emitter, + MeterOptions, +) + + +def test_haystack_openai(): + """Test Haystack with OpenAI (built-in).""" + print("\n=== Haystack + OpenAI ===") + + if not os.environ.get("OPENAI_API_KEY"): + print("Skipped: OPENAI_API_KEY not set") + return + + try: + from haystack.components.generators import OpenAIGenerator + except ImportError as e: + print(f"Not installed: {e}") + return + + # Create generator + generator = OpenAIGenerator(model="gpt-4o-mini") + + # Run generation + result = generator.run(prompt="Say hello in exactly 3 words.") + response = result["replies"][0] + print(f"Response: {response}") + + +def test_haystack_anthropic(): + """Test Haystack with Anthropic.""" + print("\n=== Haystack + Anthropic ===") + + if not os.environ.get("ANTHROPIC_API_KEY"): + print("Skipped: ANTHROPIC_API_KEY not set") + return + + try: + from haystack_integrations.components.generators.anthropic import AnthropicGenerator + except ImportError as e: + print(f"Not installed: {e}") + print("Install with: pip install anthropic-haystack") + return + + # Create generator + generator = AnthropicGenerator(model="claude-3-5-haiku-latest") + + # Run generation + result = generator.run(prompt="Say hello in exactly 3 words.") + response = result["replies"][0] + print(f"Response: {response}") + + +def test_haystack_gemini(): + """Test Haystack with Gemini.""" + print("\n=== Haystack + Gemini ===") + + if not os.environ.get("GOOGLE_API_KEY"): + print("Skipped: GOOGLE_API_KEY not set") + return + + try: + from haystack_integrations.components.generators.google_ai import GoogleAIGeminiGenerator + except ImportError as e: + print(f"Not installed: {e}") + print("Install with: pip install google-ai-haystack") + return + + # Create generator + generator = GoogleAIGeminiGenerator(model="gemini-2.0-flash") + + # Run generation (Gemini uses 'parts' instead of 'prompt') + result = generator.run(parts=["Say hello in exactly 3 words."]) + response = result["replies"][0] + print(f"Response: {response}") + + +async def main(): + """Run all Haystack tests.""" + print("Starting Haystack tests...") + print("Testing if existing Aden instrumentation captures Haystack calls...") + print("(Haystack uses actual provider SDKs internally)\n") + + # Initialize instrumentation BEFORE importing/using Haystack + result = await instrument_async( + MeterOptions( + api_key=os.environ.get("ADEN_API_KEY"), + server_url=os.environ.get("ADEN_API_URL"), + emit_metric=create_console_emitter(pretty=True), + ) + ) + print(f"Instrumented: openai={result.openai}, anthropic={result.anthropic}, gemini={result.gemini}") + + try: + test_haystack_openai() + except Exception as e: + print(f"OpenAI Error: {e}") + + try: + test_haystack_anthropic() + except Exception as e: + print(f"Anthropic Error: {e}") + + try: + test_haystack_gemini() + except Exception as e: + print(f"Gemini Error: {e}") + + await uninstrument_async() + + print("\n=== Haystack tests complete ===") + print("\nCheck which providers showed metric events above.") + print("If a provider didn't show metrics, we may need dedicated instrumentation.") + + +if __name__ == "__main__": + asyncio.run(main()) diff --git a/examples/swarm_example.py b/examples/swarm_example.py new file mode 100644 index 0000000..87f0e82 --- /dev/null +++ b/examples/swarm_example.py @@ -0,0 +1,185 @@ +""" +OpenAI Swarm Basic Example + +Tests: Whether Aden's existing instrumentation captures OpenAI Swarm's LLM calls. + +OpenAI Swarm internally uses the OpenAI Python SDK directly: +"internally just instantiates an OpenAI client" + +Note: Swarm only supports OpenAI (no Anthropic, Gemini). +Note: Swarm is experimental/educational. OpenAI recommends using Agents SDK for production. + +Prerequisites: + pip install git+https://github.com/openai/swarm.git + +Run: uv run python examples/swarm_example.py +""" + +import asyncio +import os +import sys + +# Add parent directory to path for local development +sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..", "src")) + +# Load environment variables from .env file +try: + from dotenv import load_dotenv + load_dotenv() +except ImportError: + pass # dotenv not installed, use shell environment + +from aden import ( + instrument_async, + uninstrument_async, + create_console_emitter, + MeterOptions, +) + + +def test_swarm_basic(): + """Test basic Swarm agent.""" + print("\n=== Swarm Basic Agent ===") + + if not os.environ.get("OPENAI_API_KEY"): + print("Skipped: OPENAI_API_KEY not set") + return + + try: + from swarm import Swarm, Agent + except ImportError as e: + print(f"Not installed: {e}") + print("Install with: pip install git+https://github.com/openai/swarm.git") + return + + # Create a simple agent + agent = Agent( + name="Greeter", + instructions="You are a friendly greeter. Keep responses very short (3 words max).", + ) + + # Create Swarm client and run + client = Swarm() + response = client.run( + agent=agent, + messages=[{"role": "user", "content": "Say hello"}], + ) + + print(f"Response: {response.messages[-1]['content']}") + + +def test_swarm_with_function(): + """Test Swarm agent with function calling.""" + print("\n=== Swarm Agent with Function ===") + + if not os.environ.get("OPENAI_API_KEY"): + print("Skipped: OPENAI_API_KEY not set") + return + + try: + from swarm import Swarm, Agent + except ImportError as e: + print(f"Not installed: {e}") + return + + def get_weather(location: str) -> str: + """Get weather for a location.""" + return f"The weather in {location} is sunny, 25°C." + + # Create agent with function + agent = Agent( + name="WeatherBot", + instructions="You help users check the weather. Use the get_weather function.", + functions=[get_weather], + ) + + client = Swarm() + response = client.run( + agent=agent, + messages=[{"role": "user", "content": "What's the weather in Tokyo?"}], + ) + + print(f"Response: {response.messages[-1]['content']}") + + +def test_swarm_handoff(): + """Test Swarm agent handoff.""" + print("\n=== Swarm Agent Handoff ===") + + if not os.environ.get("OPENAI_API_KEY"): + print("Skipped: OPENAI_API_KEY not set") + return + + try: + from swarm import Swarm, Agent + except ImportError as e: + print(f"Not installed: {e}") + return + + # Create two agents + sales_agent = Agent( + name="Sales", + instructions="You are a sales agent. Keep responses brief.", + ) + + def transfer_to_sales(): + """Transfer to sales agent.""" + return sales_agent + + triage_agent = Agent( + name="Triage", + instructions="You route users. If they want to buy something, transfer to sales.", + functions=[transfer_to_sales], + ) + + client = Swarm() + response = client.run( + agent=triage_agent, + messages=[{"role": "user", "content": "I want to buy a product"}], + ) + + print(f"Final Agent: {response.agent.name}") + print(f"Response: {response.messages[-1]['content']}") + + +async def main(): + """Run all Swarm tests.""" + print("Starting OpenAI Swarm tests...") + print("Testing if existing Aden instrumentation captures Swarm calls...") + print("(Swarm uses OpenAI SDK directly)") + print("(Note: Swarm only supports OpenAI, no Anthropic/Gemini)\n") + + # Initialize instrumentation BEFORE using Swarm + result = await instrument_async( + MeterOptions( + api_key=os.environ.get("ADEN_API_KEY"), + server_url=os.environ.get("ADEN_API_URL"), + emit_metric=create_console_emitter(pretty=True), + ) + ) + print(f"Instrumented: openai={result.openai}, anthropic={result.anthropic}, gemini={result.gemini}") + + try: + test_swarm_basic() + except Exception as e: + print(f"Basic Error: {e}") + + try: + test_swarm_with_function() + except Exception as e: + print(f"Function Error: {e}") + + try: + test_swarm_handoff() + except Exception as e: + print(f"Handoff Error: {e}") + + await uninstrument_async() + + print("\n=== Swarm tests complete ===") + print("\nCheck if OpenAI metric events appeared above.") + print("If metrics appeared, existing instrumentation works for Swarm.") + + +if __name__ == "__main__": + asyncio.run(main()) diff --git a/pyproject.toml b/pyproject.toml index e35abf3..ebe3100 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -117,3 +117,14 @@ warn_unused_ignores = true [tool.pytest.ini_options] asyncio_mode = "auto" testpaths = ["tests"] + +[tool.uv.sources] +swarm = { git = "https://github.com/openai/swarm.git" } + +[dependency-groups] +dev = [ + "anthropic-haystack>=5.1.0", + "google-ai-haystack>=5.4.0.post1", + "haystack-ai>=2.22.0", + "swarm", +]