Files
mai-bot/agentlite/tests/integration/test_with_api.py
2026-04-03 22:15:53 +08:00

349 lines
9.7 KiB
Python

"""Integration tests for AgentLite with real API.
This script runs comprehensive tests against the real OpenAI API.
Requires OPENAI_API_KEY environment variable to be set.
Usage:
export OPENAI_API_KEY="sk-..."
python tests/integration/test_with_api.py
"""
import asyncio
import os
import sys
from pathlib import Path
import pytest
# Add src to path
sys.path.insert(0, str(Path(__file__).parent.parent.parent / "src"))
from agentlite import Agent, OpenAIProvider, LLMClient, llm_complete
from agentlite.skills import discover_skills, SkillTool, index_skills_by_name
from agentlite.tools import ConfigurableToolset
# Test configuration
TEST_MODEL = "gpt-4o-mini" # Use mini for cost efficiency
HAS_OPENAI_API_KEY = bool(os.environ.get("OPENAI_API_KEY"))
pytestmark = pytest.mark.skipif(
not HAS_OPENAI_API_KEY, reason="OPENAI_API_KEY is required to run integration tests"
)
def get_provider():
"""Get OpenAI provider with API key."""
api_key = os.environ.get("OPENAI_API_KEY")
if not api_key:
print("❌ OPENAI_API_KEY not set!")
print("Please set your OpenAI API key:")
print(" export OPENAI_API_KEY='sk-...'")
sys.exit(1)
return OpenAIProvider(api_key=api_key, model=TEST_MODEL)
async def test_basic_agent():
"""Test 1: Basic Agent functionality."""
print("\n" + "=" * 60)
print("Test 1: Basic Agent Functionality")
print("=" * 60)
try:
provider = get_provider()
agent = Agent(
provider=provider,
system_prompt="You are a helpful assistant. Be concise.",
)
response = await agent.run("What is 2+2?")
print(f"✅ Agent responded: {response[:100]}...")
assert "4" in response, "Expected '4' in response"
print("✅ Basic Agent test PASSED")
return True
except Exception as e:
print(f"❌ Basic Agent test FAILED: {e}")
return False
async def test_agent_with_tools():
"""Test 2: Agent with tool suite."""
print("\n" + "=" * 60)
print("Test 2: Agent with Tool Suite")
print("=" * 60)
try:
from agentlite.tools import ToolSuiteConfig, ReadFile, Glob
provider = get_provider()
# Create toolset with file tools
config = ToolSuiteConfig()
toolset = ConfigurableToolset(config, work_dir=Path.cwd())
agent = Agent(
provider=provider,
system_prompt="You are a helpful assistant with file access.",
tools=toolset.tools,
)
print(f"✅ Agent created with {len(agent.tools.tools)} tools")
# Test simple query (without requiring file access)
response = await agent.run("List the Python files in the current directory")
print(f"✅ Agent with tools responded: {response[:100]}...")
print("✅ Agent with Tools test PASSED")
return True
except Exception as e:
print(f"❌ Agent with Tools test FAILED: {e}")
import traceback
traceback.print_exc()
return False
async def test_llm_client():
"""Test 3: LLMClient functionality."""
print("\n" + "=" * 60)
print("Test 3: LLMClient Functionality")
print("=" * 60)
try:
provider = get_provider()
client = LLMClient(provider=provider)
response = await client.complete(
user_prompt="What is the capital of France?",
system_prompt="You are a helpful assistant. Be concise.",
)
print(f"✅ LLMClient responded: {response.content[:100]}...")
assert "Paris" in response.content, "Expected 'Paris' in response"
print("✅ LLMClient test PASSED")
return True
except Exception as e:
print(f"❌ LLMClient test FAILED: {e}")
import traceback
traceback.print_exc()
return False
async def test_llm_streaming():
"""Test 4: LLM streaming."""
print("\n" + "=" * 60)
print("Test 4: LLM Streaming")
print("=" * 60)
try:
provider = get_provider()
client = LLMClient(provider=provider)
chunks = []
async for chunk in client.stream(
user_prompt="Count from 1 to 3",
system_prompt="You are a helpful assistant.",
):
chunks.append(chunk)
print(f" Chunk: {chunk[:20]}...")
full_response = "".join(chunks)
print(f"✅ Streamed response: {full_response[:100]}...")
print("✅ LLM Streaming test PASSED")
return True
except Exception as e:
print(f"❌ LLM Streaming test FAILED: {e}")
import traceback
traceback.print_exc()
return False
async def test_subagents():
"""Test 5: Subagent functionality."""
print("\n" + "=" * 60)
print("Test 5: Subagent Functionality")
print("=" * 60)
try:
from agentlite.labor_market import LaborMarket
from agentlite.tools.multiagent.task import Task
provider = get_provider()
# Create parent agent
parent = Agent(
provider=provider,
system_prompt="You are a coordinator agent.",
name="coordinator",
)
# Create subagent
coder = Agent(
provider=provider,
system_prompt="You are a coding specialist. Write clean, simple code.",
name="coder",
)
# Add subagent to parent
parent.add_subagent("coder", coder, "Writes code")
# Add Task tool
parent.tools.add(Task(labor_market=parent.labor_market))
print(f"✅ Created parent with {len(parent.labor_market)} subagent(s)")
print(f" Subagents: {parent.labor_market.list_subagents()}")
print("✅ Subagent test PASSED")
return True
except Exception as e:
print(f"❌ Subagent test FAILED: {e}")
import traceback
traceback.print_exc()
return False
async def test_skills():
"""Test 6: Skills functionality."""
print("\n" + "=" * 60)
print("Test 6: Skills Functionality")
print("=" * 60)
try:
# Discover example skills
skills_dir = Path(__file__).parent.parent.parent / "examples" / "skills"
if not skills_dir.exists():
print("⚠️ Skills directory not found, skipping")
return True
skills = discover_skills(skills_dir)
print(f"✅ Discovered {len(skills)} skill(s)")
for skill in skills:
print(f" - {skill.name} ({skill.type})")
if len(skills) == 0:
print("⚠️ No skills found, skipping further tests")
return True
# Test with agent
provider = get_provider()
agent = Agent(
provider=provider,
system_prompt="You are a helpful assistant.",
)
skill_index = index_skills_by_name(skills)
skill_tool = SkillTool(skill_index, parent_agent=agent)
agent.tools.add(skill_tool)
print(f"✅ Added SkillTool to agent")
print("✅ Skills test PASSED")
return True
except Exception as e:
print(f"❌ Skills test FAILED: {e}")
import traceback
traceback.print_exc()
return False
async def test_conversation_history():
"""Test 7: Conversation history."""
print("\n" + "=" * 60)
print("Test 7: Conversation History")
print("=" * 60)
try:
provider = get_provider()
agent = Agent(
provider=provider,
system_prompt="You are a helpful assistant.",
)
# First message
response1 = await agent.run("My name is Alice")
print(f"✅ Response 1: {response1[:50]}...")
# Second message (should remember context)
response2 = await agent.run("What is my name?")
print(f"✅ Response 2: {response2[:50]}...")
assert "Alice" in response2, "Expected agent to remember name"
print("✅ Conversation History test PASSED")
return True
except Exception as e:
print(f"❌ Conversation History test FAILED: {e}")
import traceback
traceback.print_exc()
return False
async def run_all_tests():
"""Run all integration tests."""
print("\n" + "=" * 60)
print("AgentLite Integration Tests with Real API")
print("=" * 60)
print(f"Model: {TEST_MODEL}")
# Check API key
if not os.environ.get("OPENAI_API_KEY"):
print("\n❌ OPENAI_API_KEY not set!")
print("\nTo run these tests, set your OpenAI API key:")
print(" export OPENAI_API_KEY='sk-...'")
print("\nGet your API key from: https://platform.openai.com/api-keys")
return []
results = []
# Run all tests
results.append(("Basic Agent", await test_basic_agent()))
results.append(("Agent with Tools", await test_agent_with_tools()))
results.append(("LLMClient", await test_llm_client()))
results.append(("LLM Streaming", await test_llm_streaming()))
results.append(("Subagents", await test_subagents()))
results.append(("Skills", await test_skills()))
results.append(("Conversation History", await test_conversation_history()))
# Print summary
print("\n" + "=" * 60)
print("Test Summary")
print("=" * 60)
passed = sum(1 for _, result in results if result)
total = len(results)
for name, result in results:
status = "✅ PASSED" if result else "❌ FAILED"
print(f"{status}: {name}")
print(f"\n{passed}/{total} tests passed")
if passed == total:
print("\n🎉 All tests passed!")
else:
print(f"\n⚠️ {total - passed} test(s) failed")
return results
if __name__ == "__main__":
results = asyncio.run(run_all_tests())
# Exit with error code if any tests failed
if results and not all(r for _, r in results):
sys.exit(1)