mbxai 1.5.0__py3-none-any.whl → 2.0.0__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- mbxai/__init__.py +18 -1
- mbxai/agent/__init__.py +8 -0
- mbxai/agent/client.py +450 -0
- mbxai/agent/models.py +56 -0
- mbxai/examples/agent_example.py +152 -0
- mbxai/examples/agent_iterations_example.py +173 -0
- mbxai/examples/agent_tool_registration_example.py +247 -0
- mbxai/examples/agent_validation_example.py +123 -0
- mbxai/examples/auto_schema_example.py +228 -0
- mbxai/examples/simple_agent_test.py +168 -0
- mbxai/mcp/server.py +1 -1
- mbxai/tools/client.py +57 -5
- mbxai/tools/types.py +32 -7
- mbxai-2.0.0.dist-info/METADATA +346 -0
- {mbxai-1.5.0.dist-info → mbxai-2.0.0.dist-info}/RECORD +17 -8
- mbxai-1.5.0.dist-info/METADATA +0 -169
- {mbxai-1.5.0.dist-info → mbxai-2.0.0.dist-info}/WHEEL +0 -0
- {mbxai-1.5.0.dist-info → mbxai-2.0.0.dist-info}/licenses/LICENSE +0 -0
@@ -0,0 +1,173 @@
|
|
1
|
+
"""
|
2
|
+
Example demonstrating AgentClient max_iterations configuration.
|
3
|
+
"""
|
4
|
+
|
5
|
+
import os
|
6
|
+
from pydantic import BaseModel, Field
|
7
|
+
from mbxai import AgentClient, OpenRouterClient
|
8
|
+
|
9
|
+
|
10
|
+
class DetailedAnalysis(BaseModel):
|
11
|
+
"""A detailed analysis response."""
|
12
|
+
topic: str = Field(description="The topic being analyzed")
|
13
|
+
key_points: list[str] = Field(description="Key points of the analysis")
|
14
|
+
depth_score: int = Field(description="Depth score from 1-10")
|
15
|
+
recommendations: list[str] = Field(description="Recommendations based on analysis")
|
16
|
+
conclusion: str = Field(description="Overall conclusion")
|
17
|
+
|
18
|
+
|
19
|
+
def demo_different_iteration_settings():
|
20
|
+
"""Demonstrate how max_iterations affects response quality."""
|
21
|
+
|
22
|
+
print("=== AgentClient max_iterations Configuration Demo ===\n")
|
23
|
+
|
24
|
+
# Complex prompt that benefits from iteration
|
25
|
+
complex_prompt = """
|
26
|
+
Analyze the impact of artificial intelligence on modern education systems.
|
27
|
+
Consider both positive and negative aspects, provide specific examples,
|
28
|
+
and suggest practical implementation strategies for educational institutions.
|
29
|
+
"""
|
30
|
+
|
31
|
+
# Test with different iteration settings
|
32
|
+
iteration_configs = [
|
33
|
+
{"iterations": 0, "description": "No quality iterations (fastest)"},
|
34
|
+
{"iterations": 1, "description": "Single quality check"},
|
35
|
+
{"iterations": 2, "description": "Default - two quality iterations"},
|
36
|
+
{"iterations": 3, "description": "Enhanced quality with three iterations"},
|
37
|
+
]
|
38
|
+
|
39
|
+
for config in iteration_configs:
|
40
|
+
print(f"🔄 Testing with {config['iterations']} iterations - {config['description']}")
|
41
|
+
print("-" * 60)
|
42
|
+
|
43
|
+
try:
|
44
|
+
# Initialize client with specific iteration count
|
45
|
+
openrouter_client = OpenRouterClient(token=os.getenv("OPENROUTER_API_KEY", "test-token"))
|
46
|
+
agent = AgentClient(openrouter_client, max_iterations=config['iterations'])
|
47
|
+
|
48
|
+
print(f"Agent configured with max_iterations={config['iterations']}")
|
49
|
+
|
50
|
+
# Mock the response since we can't actually call the API
|
51
|
+
print("📝 Example response would be generated with this configuration:")
|
52
|
+
print(f" - Quality improvement cycles: {config['iterations']}")
|
53
|
+
print(f" - Expected processing time: {'Low' if config['iterations'] <= 1 else 'Medium' if config['iterations'] <= 2 else 'High'}")
|
54
|
+
print(f" - Expected response quality: {'Basic' if config['iterations'] == 0 else 'Good' if config['iterations'] <= 2 else 'Excellent'}")
|
55
|
+
|
56
|
+
# In real usage, you would call:
|
57
|
+
# response = agent.agent(complex_prompt, DetailedAnalysis, ask_questions=False)
|
58
|
+
|
59
|
+
except Exception as e:
|
60
|
+
print(f"❌ Error with {config['iterations']} iterations: {e}")
|
61
|
+
|
62
|
+
print()
|
63
|
+
|
64
|
+
|
65
|
+
def demo_iteration_validation():
|
66
|
+
"""Demonstrate validation of max_iterations parameter."""
|
67
|
+
|
68
|
+
print("=== max_iterations Validation ===\n")
|
69
|
+
|
70
|
+
test_cases = [
|
71
|
+
{"value": -1, "should_pass": False, "description": "Negative value"},
|
72
|
+
{"value": 0, "should_pass": True, "description": "Zero (no iterations)"},
|
73
|
+
{"value": 1, "should_pass": True, "description": "Single iteration"},
|
74
|
+
{"value": 5, "should_pass": True, "description": "High iteration count"},
|
75
|
+
]
|
76
|
+
|
77
|
+
openrouter_client = OpenRouterClient(token="test-token")
|
78
|
+
|
79
|
+
for test in test_cases:
|
80
|
+
try:
|
81
|
+
agent = AgentClient(openrouter_client, max_iterations=test["value"])
|
82
|
+
if test["should_pass"]:
|
83
|
+
print(f"✅ {test['description']}: max_iterations={test['value']} accepted")
|
84
|
+
else:
|
85
|
+
print(f"❌ {test['description']}: Should have failed but didn't")
|
86
|
+
except ValueError as e:
|
87
|
+
if not test["should_pass"]:
|
88
|
+
print(f"✅ {test['description']}: Correctly rejected - {e}")
|
89
|
+
else:
|
90
|
+
print(f"❌ {test['description']}: Unexpectedly rejected - {e}")
|
91
|
+
except Exception as e:
|
92
|
+
print(f"❌ {test['description']}: Unexpected error - {e}")
|
93
|
+
|
94
|
+
|
95
|
+
def demo_performance_considerations():
|
96
|
+
"""Show performance implications of different iteration settings."""
|
97
|
+
|
98
|
+
print("\n=== Performance Considerations ===\n")
|
99
|
+
|
100
|
+
print("max_iterations Impact Analysis:")
|
101
|
+
print("┌─────────────┬─────────────────┬─────────────────┬─────────────────┐")
|
102
|
+
print("│ Iterations │ API Calls │ Processing Time │ Quality Level │")
|
103
|
+
print("├─────────────┼─────────────────┼─────────────────┼─────────────────┤")
|
104
|
+
print("│ 0 │ 2 calls │ Fastest │ Basic │")
|
105
|
+
print("│ 1 │ 4 calls │ Fast │ Good │")
|
106
|
+
print("│ 2 (default) │ 6 calls │ Moderate │ Very Good │")
|
107
|
+
print("│ 3 │ 8 calls │ Slower │ Excellent │")
|
108
|
+
print("│ 4+ │ 10+ calls │ Slowest │ Diminishing │")
|
109
|
+
print("└─────────────┴─────────────────┴─────────────────┴─────────────────┘")
|
110
|
+
|
111
|
+
print("\nRecommendations:")
|
112
|
+
print("• Use max_iterations=0 for: Quick responses, simple queries, real-time applications")
|
113
|
+
print("• Use max_iterations=1 for: Balanced performance and quality")
|
114
|
+
print("• Use max_iterations=2 for: Default - good balance (recommended)")
|
115
|
+
print("• Use max_iterations=3+ for: Complex analysis, critical applications, maximum quality")
|
116
|
+
|
117
|
+
print("\nAPI Call Breakdown per agent() call:")
|
118
|
+
print("• Question generation: 1 call")
|
119
|
+
print("• Initial processing: 1 call")
|
120
|
+
print("• Quality check + improvement: 2 calls per iteration")
|
121
|
+
print("• Final formatting: 1 call")
|
122
|
+
print("• Total = 3 + (2 × max_iterations) calls")
|
123
|
+
|
124
|
+
|
125
|
+
def demo_use_cases():
|
126
|
+
"""Show appropriate use cases for different iteration settings."""
|
127
|
+
|
128
|
+
print("\n=== Use Case Examples ===\n")
|
129
|
+
|
130
|
+
use_cases = [
|
131
|
+
{
|
132
|
+
"scenario": "Chatbot Quick Responses",
|
133
|
+
"iterations": 0,
|
134
|
+
"reasoning": "Speed is critical, basic quality acceptable"
|
135
|
+
},
|
136
|
+
{
|
137
|
+
"scenario": "Content Summarization",
|
138
|
+
"iterations": 1,
|
139
|
+
"reasoning": "Some quality improvement needed, moderate speed"
|
140
|
+
},
|
141
|
+
{
|
142
|
+
"scenario": "Business Report Generation",
|
143
|
+
"iterations": 2,
|
144
|
+
"reasoning": "Default balanced approach for professional content"
|
145
|
+
},
|
146
|
+
{
|
147
|
+
"scenario": "Academic Research Analysis",
|
148
|
+
"iterations": 3,
|
149
|
+
"reasoning": "High quality required, processing time less critical"
|
150
|
+
},
|
151
|
+
{
|
152
|
+
"scenario": "Legal Document Review",
|
153
|
+
"iterations": 4,
|
154
|
+
"reasoning": "Maximum accuracy needed, time not a constraint"
|
155
|
+
}
|
156
|
+
]
|
157
|
+
|
158
|
+
for case in use_cases:
|
159
|
+
print(f"📋 {case['scenario']}")
|
160
|
+
print(f" Recommended max_iterations: {case['iterations']}")
|
161
|
+
print(f" Reasoning: {case['reasoning']}")
|
162
|
+
print(f" Example: agent = AgentClient(client, max_iterations={case['iterations']})")
|
163
|
+
print()
|
164
|
+
|
165
|
+
|
166
|
+
if __name__ == "__main__":
|
167
|
+
demo_different_iteration_settings()
|
168
|
+
demo_iteration_validation()
|
169
|
+
demo_performance_considerations()
|
170
|
+
demo_use_cases()
|
171
|
+
|
172
|
+
print("=" * 60)
|
173
|
+
print("max_iterations configuration demo completed! 🎉")
|
@@ -0,0 +1,247 @@
|
|
1
|
+
"""
|
2
|
+
Example demonstrating AgentClient tool registration proxy methods.
|
3
|
+
"""
|
4
|
+
|
5
|
+
import os
|
6
|
+
from pydantic import BaseModel, Field
|
7
|
+
from mbxai import AgentClient, OpenRouterClient, ToolClient
|
8
|
+
from mbxai.mcp import MCPClient
|
9
|
+
|
10
|
+
|
11
|
+
class WeatherResponse(BaseModel):
|
12
|
+
"""Response for weather queries."""
|
13
|
+
location: str = Field(description="The location")
|
14
|
+
temperature: str = Field(description="Current temperature")
|
15
|
+
conditions: str = Field(description="Weather conditions")
|
16
|
+
recommendations: list[str] = Field(description="Recommendations based on weather")
|
17
|
+
|
18
|
+
|
19
|
+
class CalculationResponse(BaseModel):
|
20
|
+
"""Response for calculations."""
|
21
|
+
operation: str = Field(description="The operation performed")
|
22
|
+
result: float = Field(description="The calculation result")
|
23
|
+
explanation: str = Field(description="Step-by-step explanation")
|
24
|
+
|
25
|
+
|
26
|
+
def get_weather(location: str) -> dict:
|
27
|
+
"""Get weather information for a location."""
|
28
|
+
# Mock weather service
|
29
|
+
weather_data = {
|
30
|
+
"New York": {"temp": "72°F", "conditions": "Sunny"},
|
31
|
+
"London": {"temp": "15°C", "conditions": "Cloudy"},
|
32
|
+
"Tokyo": {"temp": "25°C", "conditions": "Rainy"},
|
33
|
+
}
|
34
|
+
|
35
|
+
data = weather_data.get(location, {"temp": "20°C", "conditions": "Unknown"})
|
36
|
+
return {
|
37
|
+
"location": location,
|
38
|
+
"temperature": data["temp"],
|
39
|
+
"conditions": data["conditions"]
|
40
|
+
}
|
41
|
+
|
42
|
+
|
43
|
+
def calculate(operation: str, a: float, b: float) -> dict:
|
44
|
+
"""Perform mathematical calculations."""
|
45
|
+
operations = {
|
46
|
+
"add": a + b,
|
47
|
+
"subtract": a - b,
|
48
|
+
"multiply": a * b,
|
49
|
+
"divide": a / b if b != 0 else None
|
50
|
+
}
|
51
|
+
|
52
|
+
result = operations.get(operation.lower())
|
53
|
+
if result is None:
|
54
|
+
return {"error": "Invalid operation or division by zero"}
|
55
|
+
|
56
|
+
return {
|
57
|
+
"operation": f"{a} {operation} {b}",
|
58
|
+
"result": result,
|
59
|
+
"explanation": f"Calculated {a} {operation} {b} = {result}"
|
60
|
+
}
|
61
|
+
|
62
|
+
|
63
|
+
def demo_tool_registration_with_tool_client():
|
64
|
+
"""Demonstrate tool registration with ToolClient via AgentClient."""
|
65
|
+
print("=== Tool Registration with ToolClient ===")
|
66
|
+
|
67
|
+
# Initialize clients
|
68
|
+
openrouter_client = OpenRouterClient(token=os.getenv("OPENROUTER_API_KEY", "test-token"))
|
69
|
+
tool_client = ToolClient(openrouter_client)
|
70
|
+
agent = AgentClient(tool_client)
|
71
|
+
|
72
|
+
# Register tools through the agent proxy
|
73
|
+
try:
|
74
|
+
agent.register_tool(
|
75
|
+
name="get_weather",
|
76
|
+
description="Get current weather for a location",
|
77
|
+
function=get_weather,
|
78
|
+
schema={
|
79
|
+
"type": "object",
|
80
|
+
"properties": {
|
81
|
+
"location": {
|
82
|
+
"type": "string",
|
83
|
+
"description": "The location to get weather for"
|
84
|
+
}
|
85
|
+
},
|
86
|
+
"required": ["location"]
|
87
|
+
}
|
88
|
+
)
|
89
|
+
print("✅ Successfully registered weather tool via AgentClient")
|
90
|
+
|
91
|
+
agent.register_tool(
|
92
|
+
name="calculate",
|
93
|
+
description="Perform mathematical calculations",
|
94
|
+
function=calculate,
|
95
|
+
schema={
|
96
|
+
"type": "object",
|
97
|
+
"properties": {
|
98
|
+
"operation": {
|
99
|
+
"type": "string",
|
100
|
+
"enum": ["add", "subtract", "multiply", "divide"],
|
101
|
+
"description": "The mathematical operation to perform"
|
102
|
+
},
|
103
|
+
"a": {
|
104
|
+
"type": "number",
|
105
|
+
"description": "First number"
|
106
|
+
},
|
107
|
+
"b": {
|
108
|
+
"type": "number",
|
109
|
+
"description": "Second number"
|
110
|
+
}
|
111
|
+
},
|
112
|
+
"required": ["operation", "a", "b"]
|
113
|
+
}
|
114
|
+
)
|
115
|
+
print("✅ Successfully registered calculator tool via AgentClient")
|
116
|
+
|
117
|
+
except Exception as e:
|
118
|
+
print(f"❌ Tool registration failed: {e}")
|
119
|
+
|
120
|
+
# Test agent with tools (mock example)
|
121
|
+
print("\n📝 Example usage:")
|
122
|
+
print('agent.agent("What\'s the weather in New York?", WeatherResponse)')
|
123
|
+
print('agent.agent("Calculate 15 + 25", CalculationResponse)')
|
124
|
+
|
125
|
+
|
126
|
+
def demo_tool_registration_with_mcp_client():
|
127
|
+
"""Demonstrate tool registration with MCPClient via AgentClient."""
|
128
|
+
print("\n=== Tool Registration with MCPClient ===")
|
129
|
+
|
130
|
+
# Initialize clients
|
131
|
+
openrouter_client = OpenRouterClient(token=os.getenv("OPENROUTER_API_KEY", "test-token"))
|
132
|
+
mcp_client = MCPClient(openrouter_client)
|
133
|
+
agent = AgentClient(mcp_client)
|
134
|
+
|
135
|
+
# Register individual tools
|
136
|
+
try:
|
137
|
+
agent.register_tool(
|
138
|
+
name="get_weather",
|
139
|
+
description="Get current weather for a location",
|
140
|
+
function=get_weather,
|
141
|
+
schema={
|
142
|
+
"type": "object",
|
143
|
+
"properties": {
|
144
|
+
"location": {
|
145
|
+
"type": "string",
|
146
|
+
"description": "The location to get weather for"
|
147
|
+
}
|
148
|
+
},
|
149
|
+
"required": ["location"]
|
150
|
+
}
|
151
|
+
)
|
152
|
+
print("✅ Successfully registered tool with MCPClient via AgentClient")
|
153
|
+
|
154
|
+
except Exception as e:
|
155
|
+
print(f"❌ Tool registration failed: {e}")
|
156
|
+
|
157
|
+
# Register MCP server (mock - would normally connect to real server)
|
158
|
+
try:
|
159
|
+
# Note: This would fail in real usage without a running MCP server
|
160
|
+
# agent.register_mcp_server("example_server", "http://localhost:8000")
|
161
|
+
print("📝 MCP server registration available via: agent.register_mcp_server(name, url)")
|
162
|
+
|
163
|
+
except Exception as e:
|
164
|
+
print(f"⚠️ MCP server registration example: {e}")
|
165
|
+
|
166
|
+
|
167
|
+
def demo_tool_registration_errors():
|
168
|
+
"""Demonstrate error handling when trying to register tools with unsupported clients."""
|
169
|
+
print("\n=== Error Handling for Unsupported Clients ===")
|
170
|
+
|
171
|
+
# Try with OpenRouterClient (doesn't support tool registration)
|
172
|
+
try:
|
173
|
+
openrouter_client = OpenRouterClient(token="test-token")
|
174
|
+
agent = AgentClient(openrouter_client)
|
175
|
+
|
176
|
+
agent.register_tool(
|
177
|
+
name="test_tool",
|
178
|
+
description="A test tool",
|
179
|
+
function=lambda x: x,
|
180
|
+
schema={"type": "object", "properties": {}}
|
181
|
+
)
|
182
|
+
print("❌ This should not be reached - OpenRouterClient doesn't support tools")
|
183
|
+
|
184
|
+
except AttributeError as e:
|
185
|
+
print(f"✅ Correctly handled unsupported client: {e}")
|
186
|
+
except Exception as e:
|
187
|
+
print(f"❌ Unexpected error: {e}")
|
188
|
+
|
189
|
+
# Try MCP server registration with non-MCP client
|
190
|
+
try:
|
191
|
+
openrouter_client = OpenRouterClient(token="test-token")
|
192
|
+
tool_client = ToolClient(openrouter_client)
|
193
|
+
agent = AgentClient(tool_client)
|
194
|
+
|
195
|
+
agent.register_mcp_server("test_server", "http://localhost:8000")
|
196
|
+
print("❌ This should not be reached - ToolClient doesn't support MCP servers")
|
197
|
+
|
198
|
+
except AttributeError as e:
|
199
|
+
print(f"✅ Correctly handled unsupported MCP registration: {e}")
|
200
|
+
except Exception as e:
|
201
|
+
print(f"❌ Unexpected error: {e}")
|
202
|
+
|
203
|
+
|
204
|
+
def demo_client_capabilities():
|
205
|
+
"""Show which clients support which registration methods."""
|
206
|
+
print("\n=== Client Capabilities Summary ===")
|
207
|
+
|
208
|
+
capabilities = {
|
209
|
+
"OpenRouterClient": {
|
210
|
+
"parse": "✅",
|
211
|
+
"register_tool": "❌",
|
212
|
+
"register_mcp_server": "❌"
|
213
|
+
},
|
214
|
+
"ToolClient": {
|
215
|
+
"parse": "✅",
|
216
|
+
"register_tool": "✅",
|
217
|
+
"register_mcp_server": "❌"
|
218
|
+
},
|
219
|
+
"MCPClient": {
|
220
|
+
"parse": "✅",
|
221
|
+
"register_tool": "✅",
|
222
|
+
"register_mcp_server": "✅"
|
223
|
+
}
|
224
|
+
}
|
225
|
+
|
226
|
+
print("Client capabilities for AgentClient:")
|
227
|
+
print("┌─────────────────┬───────┬──────────────┬─────────────────────┐")
|
228
|
+
print("│ Client │ parse │ register_tool│ register_mcp_server │")
|
229
|
+
print("├─────────────────┼───────┼──────────────┼─────────────────────┤")
|
230
|
+
|
231
|
+
for client, caps in capabilities.items():
|
232
|
+
print(f"│ {client:<15} │ {caps['parse']:>5} │ {caps['register_tool']:>12} │ {caps['register_mcp_server']:>19} │")
|
233
|
+
|
234
|
+
print("└─────────────────┴───────┴──────────────┴─────────────────────┘")
|
235
|
+
|
236
|
+
|
237
|
+
if __name__ == "__main__":
|
238
|
+
print("AgentClient Tool Registration Examples\n")
|
239
|
+
print("=" * 60)
|
240
|
+
|
241
|
+
demo_tool_registration_with_tool_client()
|
242
|
+
demo_tool_registration_with_mcp_client()
|
243
|
+
demo_tool_registration_errors()
|
244
|
+
demo_client_capabilities()
|
245
|
+
|
246
|
+
print("\n" + "=" * 60)
|
247
|
+
print("All examples completed! 🎉")
|
@@ -0,0 +1,123 @@
|
|
1
|
+
"""
|
2
|
+
Example demonstrating AgentClient validation and error handling.
|
3
|
+
"""
|
4
|
+
|
5
|
+
import os
|
6
|
+
from pydantic import BaseModel, Field
|
7
|
+
from mbxai import AgentClient, OpenRouterClient, ToolClient
|
8
|
+
from mbxai.mcp import MCPClient
|
9
|
+
|
10
|
+
|
11
|
+
class SimpleResponse(BaseModel):
|
12
|
+
"""A simple response for testing."""
|
13
|
+
message: str = Field(description="The response message")
|
14
|
+
|
15
|
+
|
16
|
+
class MockClientWithoutParse:
|
17
|
+
"""Mock client that doesn't have a parse method."""
|
18
|
+
def create(self, messages, **kwargs):
|
19
|
+
return "This client doesn't support structured responses"
|
20
|
+
|
21
|
+
|
22
|
+
def demo_client_validation():
|
23
|
+
"""Demonstrate AgentClient validation of client capabilities."""
|
24
|
+
|
25
|
+
print("=== AgentClient Validation Examples ===\n")
|
26
|
+
|
27
|
+
# Example 1: Valid clients
|
28
|
+
print("1. Testing valid clients with parse method:")
|
29
|
+
|
30
|
+
try:
|
31
|
+
# OpenRouterClient - has parse method
|
32
|
+
openrouter_client = OpenRouterClient(token="test-token")
|
33
|
+
agent1 = AgentClient(openrouter_client)
|
34
|
+
print("✅ OpenRouterClient: Successfully created AgentClient")
|
35
|
+
except Exception as e:
|
36
|
+
print(f"❌ OpenRouterClient: {e}")
|
37
|
+
|
38
|
+
try:
|
39
|
+
# ToolClient - has parse method (inherits from OpenRouterClient functionality)
|
40
|
+
openrouter_client = OpenRouterClient(token="test-token")
|
41
|
+
tool_client = ToolClient(openrouter_client)
|
42
|
+
agent2 = AgentClient(tool_client)
|
43
|
+
print("✅ ToolClient: Successfully created AgentClient")
|
44
|
+
except Exception as e:
|
45
|
+
print(f"❌ ToolClient: {e}")
|
46
|
+
|
47
|
+
try:
|
48
|
+
# MCPClient - has parse method (inherits from ToolClient)
|
49
|
+
openrouter_client = OpenRouterClient(token="test-token")
|
50
|
+
mcp_client = MCPClient(openrouter_client)
|
51
|
+
agent3 = AgentClient(mcp_client)
|
52
|
+
print("✅ MCPClient: Successfully created AgentClient")
|
53
|
+
except Exception as e:
|
54
|
+
print(f"❌ MCPClient: {e}")
|
55
|
+
|
56
|
+
print("\n" + "="*50 + "\n")
|
57
|
+
|
58
|
+
# Example 2: Invalid client
|
59
|
+
print("2. Testing invalid client without parse method:")
|
60
|
+
|
61
|
+
try:
|
62
|
+
mock_client = MockClientWithoutParse()
|
63
|
+
agent_invalid = AgentClient(mock_client)
|
64
|
+
print("❌ This should not be reached - validation failed!")
|
65
|
+
except ValueError as e:
|
66
|
+
print(f"✅ Correctly rejected invalid client: {e}")
|
67
|
+
except Exception as e:
|
68
|
+
print(f"❌ Unexpected error: {e}")
|
69
|
+
|
70
|
+
print("\n" + "="*50 + "\n")
|
71
|
+
|
72
|
+
# Example 3: Demonstrate why parse method is required
|
73
|
+
print("3. Why structured responses are essential for AgentClient:")
|
74
|
+
print("""
|
75
|
+
The AgentClient requires structured responses because it:
|
76
|
+
- Generates questions as QuestionList objects
|
77
|
+
- Performs quality checks as QualityCheck objects
|
78
|
+
- Processes intermediate results as Result objects
|
79
|
+
- Returns final responses as user-defined Pydantic models
|
80
|
+
|
81
|
+
Without structured parsing, the agent cannot reliably:
|
82
|
+
- Extract questions to ask users
|
83
|
+
- Determine if results need improvement
|
84
|
+
- Format final responses correctly
|
85
|
+
- Handle the multi-step thinking process
|
86
|
+
""")
|
87
|
+
|
88
|
+
|
89
|
+
def demo_agent_workflow():
|
90
|
+
"""Demonstrate the complete agent workflow."""
|
91
|
+
print("4. Complete AgentClient workflow example:")
|
92
|
+
|
93
|
+
# Note: This would require a real API token to run
|
94
|
+
api_key = os.getenv("OPENROUTER_API_KEY")
|
95
|
+
if not api_key:
|
96
|
+
print("⚠️ Set OPENROUTER_API_KEY environment variable to run live examples")
|
97
|
+
return
|
98
|
+
|
99
|
+
try:
|
100
|
+
# Initialize with real client
|
101
|
+
openrouter_client = OpenRouterClient(token=api_key)
|
102
|
+
agent = AgentClient(openrouter_client)
|
103
|
+
|
104
|
+
# Test without questions
|
105
|
+
response = agent.agent(
|
106
|
+
prompt="Explain the benefits of structured AI responses",
|
107
|
+
final_response_structure=SimpleResponse,
|
108
|
+
ask_questions=False
|
109
|
+
)
|
110
|
+
|
111
|
+
if response.is_complete():
|
112
|
+
print(f"✅ Agent response: {response.final_response.message}")
|
113
|
+
else:
|
114
|
+
print("❌ Expected complete response but got questions")
|
115
|
+
|
116
|
+
except Exception as e:
|
117
|
+
print(f"❌ Agent workflow error: {e}")
|
118
|
+
|
119
|
+
|
120
|
+
if __name__ == "__main__":
|
121
|
+
demo_client_validation()
|
122
|
+
print("\n" + "="*70 + "\n")
|
123
|
+
demo_agent_workflow()
|