omarequalmars
commited on
Commit
·
bd27766
1
Parent(s):
7319d31
Fixed agent
Browse files- app.py +1 -1
- example_usage.py +0 -14
- local_test.py +0 -17
- nodes/__pycache__/core.cpython-313.pyc +0 -0
- nodes/core.py +1 -1
- test_agent.py +0 -50
- test_all_tools.py +0 -63
- test_math_tools.py +0 -78
- test_multimodal_tools.py +0 -145
- test_search_tools.py +0 -96
- test_youtube_tools.py +0 -111
- tools/__pycache__/multimodal_tools.cpython-313.pyc +0 -0
- tools/multimodal_tools.py +2 -2
app.py
CHANGED
@@ -256,4 +256,4 @@ if __name__ == "__main__":
|
|
256 |
print("-"*(60 + len(" App Starting ")) + "\n")
|
257 |
|
258 |
print("Launching Gradio Interface for LangGraph Agent Evaluation...")
|
259 |
-
demo.launch(debug=True, share=
|
|
|
256 |
print("-"*(60 + len(" App Starting ")) + "\n")
|
257 |
|
258 |
print("Launching Gradio Interface for LangGraph Agent Evaluation...")
|
259 |
+
demo.launch(debug=True, share=True)
|
example_usage.py
DELETED
@@ -1,14 +0,0 @@
|
|
1 |
-
# example_usage.py
|
2 |
-
from graph.graph_builder import graph
|
3 |
-
from langchain_core.messages import HumanMessage
|
4 |
-
|
5 |
-
# Simple example
|
6 |
-
def ask_agent(question: str):
|
7 |
-
initial_state = {"messages": [HumanMessage(content=question)]}
|
8 |
-
result = graph.invoke(initial_state)
|
9 |
-
return result["messages"][-1].content
|
10 |
-
|
11 |
-
# Usage
|
12 |
-
if __name__ == "__main__":
|
13 |
-
response = ask_agent("How many albums did Michael Jackson release in his lifetime?")
|
14 |
-
print(f"Agent: {response}")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
local_test.py
DELETED
@@ -1,17 +0,0 @@
|
|
1 |
-
# local_test.py
|
2 |
-
from app import BasicAgent
|
3 |
-
|
4 |
-
agent = BasicAgent()
|
5 |
-
|
6 |
-
# Test questions
|
7 |
-
test_questions = [
|
8 |
-
"What is 15 + 27?",
|
9 |
-
"Calculate the square root of 144",
|
10 |
-
"What is 25% of 200?"
|
11 |
-
]
|
12 |
-
|
13 |
-
for q in test_questions:
|
14 |
-
answer = agent(q)
|
15 |
-
print(f"Q: {q}")
|
16 |
-
print(f"A: {answer}")
|
17 |
-
print("-" * 30)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
nodes/__pycache__/core.cpython-313.pyc
CHANGED
Binary files a/nodes/__pycache__/core.cpython-313.pyc and b/nodes/__pycache__/core.cpython-313.pyc differ
|
|
nodes/core.py
CHANGED
@@ -31,7 +31,7 @@ if not openrouter_api_key:
|
|
31 |
|
32 |
# Initialize OpenRouter ChatOpenAI with OpenRouter-specific configuration
|
33 |
chat = ChatOpenAI(
|
34 |
-
model="google/gemini-2.5-
|
35 |
# Alternative models you can use:
|
36 |
# model="mistralai/mistral-7b-instruct:free", # Fast, free text model
|
37 |
# model="google/gemma-2-9b-it:free", # Google's free model
|
|
|
31 |
|
32 |
# Initialize OpenRouter ChatOpenAI with OpenRouter-specific configuration
|
33 |
chat = ChatOpenAI(
|
34 |
+
model="google/gemini-2.5-pro-preview", # Free multimodal model
|
35 |
# Alternative models you can use:
|
36 |
# model="mistralai/mistral-7b-instruct:free", # Fast, free text model
|
37 |
# model="google/gemma-2-9b-it:free", # Google's free model
|
test_agent.py
DELETED
@@ -1,50 +0,0 @@
|
|
1 |
-
# test_agent.py
|
2 |
-
import os
|
3 |
-
from dotenv import load_dotenv
|
4 |
-
from graph.graph_builder import graph
|
5 |
-
from langchain_core.messages import HumanMessage
|
6 |
-
|
7 |
-
load_dotenv()
|
8 |
-
|
9 |
-
def test_agent():
|
10 |
-
"""Test the LangGraph agent with various queries"""
|
11 |
-
|
12 |
-
# Check if OpenRouter API key is available
|
13 |
-
if not os.getenv("OPENROUTER_API_KEY"):
|
14 |
-
print("❌ OPENROUTER_API_KEY not found in environment")
|
15 |
-
return
|
16 |
-
|
17 |
-
print("🤖 Testing LangGraph Agent with OpenRouter")
|
18 |
-
print("=" * 50)
|
19 |
-
|
20 |
-
# Test cases
|
21 |
-
test_queries = [
|
22 |
-
"What is 15 + 27?",
|
23 |
-
"Calculate the square root of 144",
|
24 |
-
"Search for information about artificial intelligence",
|
25 |
-
"What is 25% of 200?"
|
26 |
-
]
|
27 |
-
|
28 |
-
for i, query in enumerate(test_queries, 1):
|
29 |
-
print(f"\n🧪 Test {i}: {query}")
|
30 |
-
print("-" * 30)
|
31 |
-
|
32 |
-
try:
|
33 |
-
# Create initial state
|
34 |
-
initial_state = {"messages": [HumanMessage(content=query)]}
|
35 |
-
|
36 |
-
# Run the agent
|
37 |
-
result = graph.invoke(initial_state)
|
38 |
-
|
39 |
-
# Get the final message
|
40 |
-
final_message = result["messages"][-1]
|
41 |
-
print(f"🤖 Response: {final_message.content}")
|
42 |
-
|
43 |
-
except Exception as e:
|
44 |
-
print(f"❌ Error: {str(e)}")
|
45 |
-
|
46 |
-
print("\n" + "=" * 50)
|
47 |
-
print("✅ Agent testing completed!")
|
48 |
-
|
49 |
-
if __name__ == "__main__":
|
50 |
-
test_agent()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
test_all_tools.py
DELETED
@@ -1,63 +0,0 @@
|
|
1 |
-
# test_all_tools.py
|
2 |
-
import os
|
3 |
-
import sys
|
4 |
-
from dotenv import load_dotenv
|
5 |
-
from pathlib import Path
|
6 |
-
|
7 |
-
# Load environment variables
|
8 |
-
load_dotenv()
|
9 |
-
|
10 |
-
# Add tools directory to path
|
11 |
-
sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
|
12 |
-
|
13 |
-
def main():
|
14 |
-
"""Run all tool tests"""
|
15 |
-
print("=" * 60)
|
16 |
-
print("🧪 TESTING ALL TOOLS")
|
17 |
-
print("=" * 60)
|
18 |
-
|
19 |
-
# Check if OpenRouter API key is loaded
|
20 |
-
openrouter_key = os.getenv("OPENROUTER_API_KEY")
|
21 |
-
if openrouter_key:
|
22 |
-
print(f"✅ OpenRouter API Key loaded: {openrouter_key[:8]}...")
|
23 |
-
else:
|
24 |
-
print("❌ OpenRouter API Key not found in environment")
|
25 |
-
print("Please add OPENROUTER_API_KEY to your .env file")
|
26 |
-
|
27 |
-
# Import and run individual test modules
|
28 |
-
try:
|
29 |
-
print("\n🔧 Testing Math Tools...")
|
30 |
-
from test_math_tools import test_math_tools
|
31 |
-
test_math_tools()
|
32 |
-
|
33 |
-
print("\n🔍 Testing Search Tools...")
|
34 |
-
from test_search_tools import test_search_tools
|
35 |
-
test_search_tools()
|
36 |
-
|
37 |
-
print("\n🎨 Testing Multimodal Tools...")
|
38 |
-
from test_multimodal_tools import test_multimodal_tools
|
39 |
-
test_multimodal_tools()
|
40 |
-
|
41 |
-
print("\n📺 Testing YouTube Tools...")
|
42 |
-
from test_youtube_tools import test_youtube_tools
|
43 |
-
test_youtube_tools()
|
44 |
-
|
45 |
-
print("\n" + "=" * 60)
|
46 |
-
print("✅ ALL TESTS COMPLETED SUCCESSFULLY!")
|
47 |
-
print("=" * 60)
|
48 |
-
|
49 |
-
# Usage examples
|
50 |
-
print("\n📚 Quick Usage Examples:")
|
51 |
-
print("from tools import get_video_info, search_web, add, analyze_image")
|
52 |
-
print("video_info = get_video_info('https://youtube.com/watch?v=...')")
|
53 |
-
print("search_results = search_web('Python programming')")
|
54 |
-
print("result = add(10, 5)")
|
55 |
-
print("image_desc = analyze_image('photo.jpg', 'What is in this image?')")
|
56 |
-
|
57 |
-
except Exception as e:
|
58 |
-
print(f"\n❌ Error running tests: {str(e)}")
|
59 |
-
import traceback
|
60 |
-
traceback.print_exc()
|
61 |
-
|
62 |
-
if __name__ == "__main__":
|
63 |
-
main()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
test_math_tools.py
DELETED
@@ -1,78 +0,0 @@
|
|
1 |
-
# test_math_tools.py
|
2 |
-
import sys
|
3 |
-
import os
|
4 |
-
from dotenv import load_dotenv
|
5 |
-
|
6 |
-
# Load environment variables
|
7 |
-
load_dotenv()
|
8 |
-
|
9 |
-
# Add tools to path
|
10 |
-
sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
|
11 |
-
|
12 |
-
def test_math_tools():
|
13 |
-
"""Test all math tool functions"""
|
14 |
-
try:
|
15 |
-
from tools.math_tools import MathTools, add, subtract, multiply, divide, factorial, square_root, average, calculate_expression
|
16 |
-
|
17 |
-
print(" 📊 Testing basic arithmetic...")
|
18 |
-
|
19 |
-
# Test basic operations
|
20 |
-
assert add(5, 3) == 8, "Addition failed"
|
21 |
-
assert subtract(10, 4) == 6, "Subtraction failed"
|
22 |
-
assert multiply(6, 7) == 42, "Multiplication failed"
|
23 |
-
assert divide(15, 3) == 5, "Division failed"
|
24 |
-
print(" ✅ Basic arithmetic: PASSED")
|
25 |
-
|
26 |
-
# Test advanced operations
|
27 |
-
print(" 🧮 Testing advanced operations...")
|
28 |
-
assert factorial(5) == 120, "Factorial failed"
|
29 |
-
assert square_root(16) == 4.0, "Square root failed"
|
30 |
-
assert average([1, 2, 3, 4, 5]) == 3.0, "Average failed"
|
31 |
-
print(" ✅ Advanced operations: PASSED")
|
32 |
-
|
33 |
-
# Test error handling
|
34 |
-
print(" 🚨 Testing error handling...")
|
35 |
-
assert "Error" in str(divide(5, 0)), "Division by zero should return error"
|
36 |
-
assert "Error" in str(factorial(-1)), "Negative factorial should return error"
|
37 |
-
assert "Error" in str(square_root(-1)), "Negative square root should return error"
|
38 |
-
print(" ✅ Error handling: PASSED")
|
39 |
-
|
40 |
-
# Test expression calculator
|
41 |
-
print(" 🧠 Testing expression calculator...")
|
42 |
-
assert calculate_expression("2 + 3 * 4") == 14, "Expression calculation failed"
|
43 |
-
assert calculate_expression("2^3") == 8, "Power expression failed"
|
44 |
-
print(" ✅ Expression calculator: PASSED")
|
45 |
-
|
46 |
-
# Test quadratic solver
|
47 |
-
print(" 📐 Testing quadratic solver...")
|
48 |
-
solutions = MathTools.solve_quadratic(1, -5, 6)
|
49 |
-
assert isinstance(solutions, tuple) and len(solutions) == 2, "Quadratic solver failed"
|
50 |
-
print(" ✅ Quadratic solver: PASSED")
|
51 |
-
|
52 |
-
# Test practical examples
|
53 |
-
print(" 💰 Testing practical calculations...")
|
54 |
-
compound_interest = MathTools.calculate_compound_interest(1000, 0.05, 2)
|
55 |
-
assert compound_interest > 1000, "Compound interest should be greater than principal"
|
56 |
-
|
57 |
-
percentage_result = MathTools.percentage(25, 100)
|
58 |
-
assert percentage_result == 25.0, "Percentage calculation failed"
|
59 |
-
print(" ✅ Practical calculations: PASSED")
|
60 |
-
|
61 |
-
print(" ✅ ALL MATH TESTS PASSED!")
|
62 |
-
|
63 |
-
# Demo output
|
64 |
-
print("\n 📋 Math Tools Demo:")
|
65 |
-
print(f" 5 + 3 = {add(5, 3)}")
|
66 |
-
print(f" 10! = {factorial(10)}")
|
67 |
-
print(f" √144 = {square_root(144)}")
|
68 |
-
print(f" Average of [10,20,30] = {average([10,20,30])}")
|
69 |
-
print(f" Expression '2^3 + 4*5' = {calculate_expression('2^3 + 4*5')}")
|
70 |
-
|
71 |
-
except ImportError as e:
|
72 |
-
print(f" ❌ Import error: {e}")
|
73 |
-
except Exception as e:
|
74 |
-
print(f" ❌ Test failed: {e}")
|
75 |
-
raise
|
76 |
-
|
77 |
-
if __name__ == "__main__":
|
78 |
-
test_math_tools()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
test_multimodal_tools.py
DELETED
@@ -1,145 +0,0 @@
|
|
1 |
-
# test_multimodal_tools.py
|
2 |
-
import sys
|
3 |
-
import os
|
4 |
-
from dotenv import load_dotenv
|
5 |
-
import tempfile
|
6 |
-
import base64
|
7 |
-
|
8 |
-
# Load environment variables
|
9 |
-
load_dotenv()
|
10 |
-
|
11 |
-
# Add tools to path
|
12 |
-
sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
|
13 |
-
|
14 |
-
def create_test_image():
|
15 |
-
"""Create a simple test image for testing"""
|
16 |
-
try:
|
17 |
-
from PIL import Image, ImageDraw
|
18 |
-
|
19 |
-
# Create a simple test image
|
20 |
-
img = Image.new('RGB', (200, 100), color='white')
|
21 |
-
draw = ImageDraw.Draw(img)
|
22 |
-
draw.text((10, 40), "Test Image", fill='black')
|
23 |
-
|
24 |
-
# Save to temporary file
|
25 |
-
temp_file = tempfile.NamedTemporaryFile(delete=False, suffix='.png')
|
26 |
-
img.save(temp_file.name)
|
27 |
-
return temp_file.name
|
28 |
-
except ImportError:
|
29 |
-
print(" ⚠️ PIL not available, creating mock image file")
|
30 |
-
# Create a mock image file for testing
|
31 |
-
temp_file = tempfile.NamedTemporaryFile(delete=False, suffix='.txt')
|
32 |
-
temp_file.write(b"This is a mock image file for testing")
|
33 |
-
temp_file.close()
|
34 |
-
return temp_file.name
|
35 |
-
|
36 |
-
def test_multimodal_tools():
|
37 |
-
"""Test multimodal tool functions"""
|
38 |
-
try:
|
39 |
-
from tools.multimodal_tools import MultimodalTools, analyze_image, extract_text, analyze_transcript
|
40 |
-
|
41 |
-
# Check OpenRouter API key
|
42 |
-
openrouter_key = os.getenv("OPENROUTER_API_KEY")
|
43 |
-
if not openrouter_key:
|
44 |
-
print(" ❌ OpenRouter API key not found!")
|
45 |
-
print(" Please add OPENROUTER_API_KEY to your .env file")
|
46 |
-
return
|
47 |
-
|
48 |
-
print(" 🎨 Initializing multimodal tools...")
|
49 |
-
multimodal_tools = MultimodalTools()
|
50 |
-
print(f" ✅ API key loaded: {openrouter_key[:8]}...")
|
51 |
-
|
52 |
-
# Test with transcript (doesn't require image)
|
53 |
-
print(" 🎙️ Testing audio transcript analysis...")
|
54 |
-
test_transcript = "Hello, this is a test transcript. We're discussing artificial intelligence and machine learning technologies."
|
55 |
-
|
56 |
-
transcript_result = multimodal_tools.analyze_audio_transcript(
|
57 |
-
test_transcript,
|
58 |
-
"What is the main topic of this transcript?"
|
59 |
-
)
|
60 |
-
|
61 |
-
if transcript_result and "Error" not in transcript_result:
|
62 |
-
print(" ✅ Transcript analysis: PASSED")
|
63 |
-
print(f" Result: {transcript_result[:100]}...")
|
64 |
-
else:
|
65 |
-
print(f" ❌ Transcript analysis failed: {transcript_result}")
|
66 |
-
|
67 |
-
# Test convenience function
|
68 |
-
print(" 🔧 Testing convenience functions...")
|
69 |
-
convenience_result = analyze_transcript(
|
70 |
-
"This is a test about Python programming and software development.",
|
71 |
-
"Summarize the main topics"
|
72 |
-
)
|
73 |
-
|
74 |
-
if convenience_result and "Error" not in convenience_result:
|
75 |
-
print(" ✅ Convenience function: PASSED")
|
76 |
-
else:
|
77 |
-
print(f" ⚠️ Convenience function result: {convenience_result}")
|
78 |
-
|
79 |
-
# Test image analysis (if we can create a test image)
|
80 |
-
print(" 🖼️ Testing image analysis...")
|
81 |
-
try:
|
82 |
-
test_image_path = create_test_image()
|
83 |
-
|
84 |
-
# Test image description
|
85 |
-
image_result = multimodal_tools.analyze_image(
|
86 |
-
test_image_path,
|
87 |
-
"Describe what you see in this image"
|
88 |
-
)
|
89 |
-
|
90 |
-
if image_result and "Error" not in image_result:
|
91 |
-
print(" ✅ Image analysis: PASSED")
|
92 |
-
print(f" Result: {image_result[:100]}...")
|
93 |
-
else:
|
94 |
-
print(f" ⚠️ Image analysis result: {image_result}")
|
95 |
-
|
96 |
-
# Test OCR functionality
|
97 |
-
ocr_result = multimodal_tools.extract_text_from_image(test_image_path)
|
98 |
-
if ocr_result and "Error" not in ocr_result:
|
99 |
-
print(" ✅ OCR extraction: PASSED")
|
100 |
-
print(f" Extracted: {ocr_result[:50]}...")
|
101 |
-
else:
|
102 |
-
print(f" ⚠️ OCR result: {ocr_result}")
|
103 |
-
|
104 |
-
# Clean up test image
|
105 |
-
os.unlink(test_image_path)
|
106 |
-
|
107 |
-
except Exception as e:
|
108 |
-
print(f" ⚠️ Image testing skipped: {str(e)}")
|
109 |
-
|
110 |
-
# Test error handling
|
111 |
-
print(" 🚨 Testing error handling...")
|
112 |
-
error_result = multimodal_tools.analyze_image(
|
113 |
-
"nonexistent_file.jpg",
|
114 |
-
"This should fail"
|
115 |
-
)
|
116 |
-
|
117 |
-
if "Error" in error_result:
|
118 |
-
print(" ✅ Error handling: PASSED")
|
119 |
-
else:
|
120 |
-
print(" ⚠️ Error handling unexpected result")
|
121 |
-
|
122 |
-
# Test empty transcript
|
123 |
-
empty_result = multimodal_tools.analyze_audio_transcript("", "Question")
|
124 |
-
if "Error" in empty_result:
|
125 |
-
print(" ✅ Empty input handling: PASSED")
|
126 |
-
|
127 |
-
print(" ✅ MULTIMODAL TESTS COMPLETED!")
|
128 |
-
|
129 |
-
# Demo output
|
130 |
-
print("\n ���� Multimodal Tools Demo:")
|
131 |
-
demo_transcript = "We discussed the implementation of AI agents using CrewAI framework for automated workflows."
|
132 |
-
demo_result = analyze_transcript(demo_transcript, "What framework was mentioned?")
|
133 |
-
print(f" Question: What framework was mentioned?")
|
134 |
-
print(f" Answer: {demo_result[:150]}...")
|
135 |
-
|
136 |
-
except ImportError as e:
|
137 |
-
print(f" ❌ Import error: {e}")
|
138 |
-
print(" Make sure all dependencies are installed")
|
139 |
-
except Exception as e:
|
140 |
-
print(f" ❌ Test failed: {e}")
|
141 |
-
import traceback
|
142 |
-
traceback.print_exc()
|
143 |
-
|
144 |
-
if __name__ == "__main__":
|
145 |
-
test_multimodal_tools()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
test_search_tools.py
DELETED
@@ -1,96 +0,0 @@
|
|
1 |
-
# test_search_tools.py
|
2 |
-
import sys
|
3 |
-
import os
|
4 |
-
from dotenv import load_dotenv
|
5 |
-
|
6 |
-
# Load environment variables
|
7 |
-
load_dotenv()
|
8 |
-
|
9 |
-
# Add tools to path
|
10 |
-
sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
|
11 |
-
|
12 |
-
def test_search_tools():
|
13 |
-
"""Test search tool functions"""
|
14 |
-
try:
|
15 |
-
from tools.search_tools import SearchTools, search_web, search_news
|
16 |
-
|
17 |
-
print(" 🔍 Initializing search tools...")
|
18 |
-
search_tools = SearchTools()
|
19 |
-
|
20 |
-
# Test DuckDuckGo search (free)
|
21 |
-
print(" 🦆 Testing DuckDuckGo search...")
|
22 |
-
ddg_results = search_tools.search_duckduckgo("Python programming", max_results=3)
|
23 |
-
if ddg_results:
|
24 |
-
print(f" ✅ DuckDuckGo returned {len(ddg_results)} results")
|
25 |
-
for i, result in enumerate(ddg_results[:2]):
|
26 |
-
print(f" {i+1}. {result.get('title', 'No title')[:50]}...")
|
27 |
-
else:
|
28 |
-
print(" ⚠️ DuckDuckGo returned no results")
|
29 |
-
|
30 |
-
# Test Tavily search (if API key available)
|
31 |
-
tavily_key = os.getenv("TAVILY_API_KEY")
|
32 |
-
if tavily_key:
|
33 |
-
print(" 🔎 Testing Tavily search...")
|
34 |
-
tavily_results = search_tools.search_tavily("AI news 2025", max_results=3)
|
35 |
-
if tavily_results:
|
36 |
-
print(f" ✅ Tavily returned {len(tavily_results)} results")
|
37 |
-
else:
|
38 |
-
print(" ⚠️ Tavily returned no results")
|
39 |
-
else:
|
40 |
-
print(" ⚠️ Tavily API key not found, skipping Tavily tests")
|
41 |
-
|
42 |
-
# Test SerpAPI search (if API key available)
|
43 |
-
serpapi_key = os.getenv("SERPAPI_KEY")
|
44 |
-
if serpapi_key:
|
45 |
-
print(" 🐍 Testing SerpAPI search...")
|
46 |
-
serp_results = search_tools.search_serpapi("machine learning", max_results=2)
|
47 |
-
if serp_results:
|
48 |
-
print(f" ✅ SerpAPI returned {len(serp_results)} results")
|
49 |
-
else:
|
50 |
-
print(" ⚠️ SerpAPI returned no results")
|
51 |
-
else:
|
52 |
-
print(" ⚠️ SerpAPI key not found, skipping SerpAPI tests")
|
53 |
-
|
54 |
-
# Test main search function (with fallback)
|
55 |
-
print(" 🎯 Testing main search function...")
|
56 |
-
main_results = search_tools.search("CrewAI framework", max_results=3)
|
57 |
-
if main_results:
|
58 |
-
print(f" ✅ Main search returned {len(main_results)} results")
|
59 |
-
print(f" Provider used: {main_results[0].get('source', 'Unknown')}")
|
60 |
-
else:
|
61 |
-
print(" ❌ Main search failed")
|
62 |
-
|
63 |
-
# Test convenience functions
|
64 |
-
print(" 🚀 Testing convenience functions...")
|
65 |
-
web_results = search_web("OpenRouter API", max_results=2)
|
66 |
-
news_results = search_news("artificial intelligence", max_results=2)
|
67 |
-
|
68 |
-
if web_results:
|
69 |
-
print(f" ✅ Web search returned {len(web_results)} results")
|
70 |
-
if news_results:
|
71 |
-
print(f" ✅ News search returned {len(news_results)} results")
|
72 |
-
|
73 |
-
# Test specialized searches
|
74 |
-
print(" 🎓 Testing specialized searches...")
|
75 |
-
academic_results = search_tools.search_academic("machine learning algorithms", max_results=2)
|
76 |
-
if academic_results:
|
77 |
-
print(f" ✅ Academic search returned {len(academic_results)} results")
|
78 |
-
|
79 |
-
print(" ✅ ALL SEARCH TESTS COMPLETED!")
|
80 |
-
|
81 |
-
# Demo output
|
82 |
-
if main_results:
|
83 |
-
print("\n 📋 Search Results Demo:")
|
84 |
-
for i, result in enumerate(main_results[:2]):
|
85 |
-
title = result.get('title', 'No title')[:60]
|
86 |
-
source = result.get('source', 'Unknown')
|
87 |
-
print(f" {i+1}. [{source}] {title}...")
|
88 |
-
|
89 |
-
except ImportError as e:
|
90 |
-
print(f" ❌ Import error: {e}")
|
91 |
-
except Exception as e:
|
92 |
-
print(f" ❌ Test failed: {e}")
|
93 |
-
print(f" Error details: {str(e)}")
|
94 |
-
|
95 |
-
if __name__ == "__main__":
|
96 |
-
test_search_tools()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
test_youtube_tools.py
DELETED
@@ -1,111 +0,0 @@
|
|
1 |
-
# test_youtube_tools.py (Updated with working test URLs)
|
2 |
-
import sys
|
3 |
-
import os
|
4 |
-
import tempfile
|
5 |
-
import shutil
|
6 |
-
from dotenv import load_dotenv
|
7 |
-
|
8 |
-
load_dotenv()
|
9 |
-
sys.path.append(os.path.join(os.path.dirname(__file__), '..'))
|
10 |
-
|
11 |
-
def test_youtube_tools():
|
12 |
-
"""Test YouTube tool functions with reliable test URLs"""
|
13 |
-
|
14 |
-
# Updated test URLs - using more reliable, public content
|
15 |
-
test_video_url = "https://www.youtube.com/watch?v=dQw4w9WgXcQ" # Rick Roll
|
16 |
-
# Use a known public playlist
|
17 |
-
test_playlist_url = "https://www.youtube.com/playlist?list=PLNVhQQnz1F5f11NXuOKF0oULKWWM2HfZS" # Small public playlist
|
18 |
-
|
19 |
-
try:
|
20 |
-
from tools.youtube_tools import YouTubeTools, get_video_info, download_video, get_captions
|
21 |
-
|
22 |
-
print(" 📺 Initializing YouTube tools...")
|
23 |
-
youtube_tools = YouTubeTools(max_retries=2, retry_delay=1.0) # Configure retry settings
|
24 |
-
|
25 |
-
# Test video info retrieval
|
26 |
-
print(" 📋 Testing video info retrieval...")
|
27 |
-
video_info = youtube_tools.get_video_info(test_video_url)
|
28 |
-
|
29 |
-
if video_info:
|
30 |
-
print(" ✅ Video info retrieval: PASSED")
|
31 |
-
print(f" Title: {video_info.get('title', 'Unknown')[:50]}...")
|
32 |
-
print(f" Author: {video_info.get('author', 'Unknown')}")
|
33 |
-
print(f" Duration: {video_info.get('length', 0)} seconds")
|
34 |
-
print(f" Views: {video_info.get('views', 0):,}")
|
35 |
-
print(f" Available captions: {video_info.get('captions_available', [])}")
|
36 |
-
else:
|
37 |
-
print(" ❌ Video info retrieval failed")
|
38 |
-
|
39 |
-
# Test available qualities with retry
|
40 |
-
print(" 🎥 Testing available qualities...")
|
41 |
-
qualities = youtube_tools.get_available_qualities(test_video_url)
|
42 |
-
|
43 |
-
if qualities:
|
44 |
-
print(" ✅ Quality detection: PASSED")
|
45 |
-
resolutions = [q['resolution'] for q in qualities if q['resolution'] != 'unknown'][:3]
|
46 |
-
print(f" Available resolutions: {resolutions}")
|
47 |
-
else:
|
48 |
-
print(" ⚠️ Quality detection failed (network issue)")
|
49 |
-
|
50 |
-
# Test captions (should work without deprecation warning)
|
51 |
-
print(" 📝 Testing caption retrieval...")
|
52 |
-
captions = youtube_tools.get_captions(test_video_url, 'en')
|
53 |
-
|
54 |
-
if captions:
|
55 |
-
print(" ✅ Caption retrieval: PASSED")
|
56 |
-
print(f" Caption preview: {captions[:100]}...")
|
57 |
-
elif captions is None:
|
58 |
-
print(" ⚠️ No captions available for this video")
|
59 |
-
else:
|
60 |
-
print(" ❌ Caption retrieval failed")
|
61 |
-
|
62 |
-
# Test playlist info with better URL
|
63 |
-
print(" 📂 Testing playlist info...")
|
64 |
-
try:
|
65 |
-
playlist_info = youtube_tools.get_playlist_info(test_playlist_url)
|
66 |
-
|
67 |
-
if playlist_info:
|
68 |
-
print(" ✅ Playlist info: PASSED")
|
69 |
-
print(f" Playlist: {playlist_info.get('title', 'Unknown')[:50]}...")
|
70 |
-
print(f" Videos: {playlist_info.get('video_count', 0)}")
|
71 |
-
else:
|
72 |
-
print(" ⚠️ Playlist info failed")
|
73 |
-
except Exception as e:
|
74 |
-
print(f" ⚠️ Playlist test error: {str(e)}")
|
75 |
-
|
76 |
-
# Test convenience functions
|
77 |
-
print(" 🔧 Testing convenience functions...")
|
78 |
-
convenience_info = get_video_info(test_video_url)
|
79 |
-
if convenience_info:
|
80 |
-
print(" ✅ Convenience functions: PASSED")
|
81 |
-
|
82 |
-
# Test error handling
|
83 |
-
print(" 🚨 Testing error handling...")
|
84 |
-
invalid_info = youtube_tools.get_video_info("https://invalid-url")
|
85 |
-
if invalid_info is None:
|
86 |
-
print(" ✅ Error handling: PASSED")
|
87 |
-
|
88 |
-
print(" ✅ YOUTUBE TOOLS TESTS COMPLETED!")
|
89 |
-
|
90 |
-
# Demo output
|
91 |
-
if video_info:
|
92 |
-
print("\n 📋 YouTube Tools Demo:")
|
93 |
-
print(f" Video: {video_info.get('title', 'Unknown')}")
|
94 |
-
print(f" Channel: {video_info.get('author', 'Unknown')}")
|
95 |
-
print(f" Published: {video_info.get('publish_date', 'Unknown')}")
|
96 |
-
print(f" Length: {video_info.get('length', 0)} seconds")
|
97 |
-
|
98 |
-
if qualities:
|
99 |
-
best_quality = qualities[0] if qualities else {}
|
100 |
-
print(f" Best quality: {best_quality.get('resolution', 'unknown')}")
|
101 |
-
|
102 |
-
except ImportError as e:
|
103 |
-
print(f" ❌ Import error: {e}")
|
104 |
-
print(" Make sure pytubefix is installed: pip install pytubefix")
|
105 |
-
except Exception as e:
|
106 |
-
print(f" ❌ Test failed: {e}")
|
107 |
-
import traceback
|
108 |
-
traceback.print_exc()
|
109 |
-
|
110 |
-
if __name__ == "__main__":
|
111 |
-
test_youtube_tools()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
tools/__pycache__/multimodal_tools.cpython-313.pyc
CHANGED
Binary files a/tools/__pycache__/multimodal_tools.cpython-313.pyc and b/tools/__pycache__/multimodal_tools.cpython-313.pyc differ
|
|
tools/multimodal_tools.py
CHANGED
@@ -18,8 +18,8 @@ class MultimodalTools:
|
|
18 |
}
|
19 |
|
20 |
# Available free multimodal models
|
21 |
-
self.vision_model = "
|
22 |
-
self.text_model = "
|
23 |
|
24 |
def _make_openrouter_request(self, payload: Dict[str, Any]) -> str:
|
25 |
"""Make request to OpenRouter API with error handling"""
|
|
|
18 |
}
|
19 |
|
20 |
# Available free multimodal models
|
21 |
+
self.vision_model = "google/gemini-2.5-flash-preview-05-20"
|
22 |
+
self.text_model = "google/gemini-2.5-flash-preview-05-20"
|
23 |
|
24 |
def _make_openrouter_request(self, payload: Dict[str, Any]) -> str:
|
25 |
"""Make request to OpenRouter API with error handling"""
|