gemini-agent-framework 0.1.1__tar.gz → 0.1.3__tar.gz
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.
- {gemini_agent_framework-0.1.1 → gemini_agent_framework-0.1.3}/.gitignore +1 -1
- {gemini_agent_framework-0.1.1 → gemini_agent_framework-0.1.3}/PKG-INFO +1 -1
- {gemini_agent_framework-0.1.1 → gemini_agent_framework-0.1.3}/pyproject.toml +1 -1
- {gemini_agent_framework-0.1.1 → gemini_agent_framework-0.1.3}/src/gemini_agent/agent.py +112 -8
- gemini_agent_framework-0.1.3/tests/__init__.py +3 -0
- gemini_agent_framework-0.1.3/tests/test_agent.py +66 -0
- gemini_agent_framework-0.1.3/tests/test_class_methods.py +67 -0
- gemini_agent_framework-0.1.3/tests/test_variables.py +133 -0
- gemini_agent_framework-0.1.1/tests/test_agent.py +0 -48
- {gemini_agent_framework-0.1.1 → gemini_agent_framework-0.1.3}/README.md +0 -0
- {gemini_agent_framework-0.1.1 → gemini_agent_framework-0.1.3}/requirements.txt +0 -0
- {gemini_agent_framework-0.1.1 → gemini_agent_framework-0.1.3}/src/gemini_agent/__init__.py +0 -0
@@ -1,6 +1,6 @@
|
|
1
1
|
Metadata-Version: 2.4
|
2
2
|
Name: gemini-agent-framework
|
3
|
-
Version: 0.1.
|
3
|
+
Version: 0.1.3
|
4
4
|
Summary: A framework for building agents that use Gemini's function calling capabilities
|
5
5
|
Project-URL: Homepage, https://github.com/m7mdony/gemini-agent-framework
|
6
6
|
Project-URL: Documentation, https://github.com/m7mdony/gemini-agent-framework#readme
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
4
4
|
|
5
5
|
[project]
|
6
6
|
name = "gemini-agent-framework"
|
7
|
-
version = "0.1.
|
7
|
+
version = "0.1.3"
|
8
8
|
description = "A framework for building agents that use Gemini's function calling capabilities"
|
9
9
|
readme = "README.md"
|
10
10
|
requires-python = ">=3.8"
|
@@ -4,6 +4,7 @@ import inspect
|
|
4
4
|
from functools import wraps
|
5
5
|
from typing import List, Callable, Dict, Any, Optional
|
6
6
|
from dotenv import load_dotenv
|
7
|
+
from datetime import datetime
|
7
8
|
|
8
9
|
load_dotenv()
|
9
10
|
|
@@ -31,6 +32,7 @@ class Agent:
|
|
31
32
|
Agent._tools_registry[func.__name__]['description'] = desc
|
32
33
|
Agent._tools_registry[func.__name__]['signature'] = inspect.signature(func)
|
33
34
|
Agent._tools_registry[func.__name__]['function_ref'] = func
|
35
|
+
Agent._tools_registry[func.__name__]['is_method'] = inspect.ismethod(func)
|
34
36
|
@wraps(func)
|
35
37
|
def wrapper(*args, **kwargs):
|
36
38
|
return func(*args, **kwargs)
|
@@ -48,6 +50,7 @@ class Agent:
|
|
48
50
|
Agent._tools_registry[func.__name__]['signature'] = inspect.signature(func)
|
49
51
|
if 'function_ref' not in Agent._tools_registry[func.__name__]:
|
50
52
|
Agent._tools_registry[func.__name__]['function_ref'] = func
|
53
|
+
Agent._tools_registry[func.__name__]['is_method'] = inspect.ismethod(func)
|
51
54
|
@wraps(func)
|
52
55
|
def wrapper(*args, **kwargs):
|
53
56
|
return func(*args, **kwargs)
|
@@ -60,7 +63,7 @@ class Agent:
|
|
60
63
|
|
61
64
|
Args:
|
62
65
|
api_key: Your Google Generative AI API key.
|
63
|
-
tools: A list of Python functions decorated as tools.
|
66
|
+
tools: A list of Python functions or class methods decorated as tools.
|
64
67
|
model_name: The name of the Gemini model to use.
|
65
68
|
"""
|
66
69
|
if not api_key:
|
@@ -72,7 +75,9 @@ class Agent:
|
|
72
75
|
|
73
76
|
self._registered_tools_json: List[Dict[str, Any]] = [] # Store JSON representation
|
74
77
|
self._tool_functions: Dict[str, Callable] = {} # Map name to actual function
|
78
|
+
self._tool_instances: Dict[str, Any] = {} # Store instances for class methods
|
75
79
|
self._intermediate_results: Dict[str, Any] = {} # Store intermediate results
|
80
|
+
self._stored_variables: Dict[str, Dict[str, Any]] = {} # Store variables with metadata
|
76
81
|
|
77
82
|
if tools:
|
78
83
|
self._process_tools(tools)
|
@@ -90,6 +95,12 @@ class Agent:
|
|
90
95
|
print(f"Warning: Function '{tool_name}' is missing @Agent.description. Skipping.")
|
91
96
|
continue
|
92
97
|
|
98
|
+
# Store the bound method directly if it's a class method
|
99
|
+
if inspect.ismethod(func):
|
100
|
+
self._tool_functions[tool_name] = func
|
101
|
+
else:
|
102
|
+
self._tool_functions[tool_name] = metadata['function_ref']
|
103
|
+
|
93
104
|
# Build the parameters schema JSON
|
94
105
|
gemini_params_schema = {
|
95
106
|
"type": "OBJECT",
|
@@ -102,6 +113,9 @@ class Agent:
|
|
102
113
|
if not params_def and signature:
|
103
114
|
params_def = {}
|
104
115
|
for name, param in signature.parameters.items():
|
116
|
+
# Skip 'self' parameter for class methods
|
117
|
+
if name == 'self' and inspect.ismethod(func):
|
118
|
+
continue
|
105
119
|
py_type = param.annotation if param.annotation != inspect.Parameter.empty else str
|
106
120
|
params_def[name] = {'type': py_type, 'description': f'Parameter {name}'}
|
107
121
|
|
@@ -125,10 +139,53 @@ class Agent:
|
|
125
139
|
del declaration_json["parameters"]
|
126
140
|
|
127
141
|
self._registered_tools_json.append(declaration_json)
|
128
|
-
|
142
|
+
|
143
|
+
def set_variable(self, name: str, value: Any, description: str = "", type_hint: type = None) -> None:
|
144
|
+
"""
|
145
|
+
Stores a variable in the agent's memory with metadata.
|
146
|
+
|
147
|
+
Args:
|
148
|
+
name: The name of the variable
|
149
|
+
value: The actual value to store
|
150
|
+
description: A description of what the variable represents
|
151
|
+
type_hint: Optional type hint for the variable
|
152
|
+
"""
|
153
|
+
self._stored_variables[name] = {
|
154
|
+
'value': value,
|
155
|
+
'description': description,
|
156
|
+
'type': type_hint or type(value).__name__,
|
157
|
+
'created_at': datetime.now().isoformat()
|
158
|
+
}
|
159
|
+
|
160
|
+
def get_variable(self, name: str) -> Any:
|
161
|
+
"""
|
162
|
+
Retrieves a stored variable's value.
|
163
|
+
|
164
|
+
Args:
|
165
|
+
name: The name of the variable to retrieve
|
166
|
+
|
167
|
+
Returns:
|
168
|
+
The stored value or None if not found
|
169
|
+
"""
|
170
|
+
return self._stored_variables.get(name, {}).get('value')
|
171
|
+
|
172
|
+
def list_variables(self) -> Dict[str, Dict[str, Any]]:
|
173
|
+
"""
|
174
|
+
Returns information about all stored variables.
|
175
|
+
|
176
|
+
Returns:
|
177
|
+
Dictionary of variable names to their metadata
|
178
|
+
"""
|
179
|
+
return {name: {k: v for k, v in data.items() if k != 'value'}
|
180
|
+
for name, data in self._stored_variables.items()}
|
129
181
|
|
130
182
|
def _get_system_prompt(self) -> str:
|
131
183
|
"""Returns a system prompt that guides the model in breaking down complex operations."""
|
184
|
+
variables_info = "\n".join([
|
185
|
+
f"- {name}: {data['description']} (Type: {data['type']})"
|
186
|
+
for name, data in self._stored_variables.items()
|
187
|
+
])
|
188
|
+
|
132
189
|
return """You are an AI assistant that can break down complex tasks into sequential steps using available tools.
|
133
190
|
When faced with a complex request:
|
134
191
|
1. Analyze the request to identify which tools can be used
|
@@ -141,13 +198,49 @@ class Agent:
|
|
141
198
|
Available tools:
|
142
199
|
{tools_list}
|
143
200
|
|
201
|
+
Available variables:
|
202
|
+
{variables_list}
|
203
|
+
|
204
|
+
IMPORTANT - Variable Usage:
|
205
|
+
When you need to use a stored variable in a function call, you MUST use the following syntax:
|
206
|
+
- For function arguments: {{"variable": "variable_name"}}
|
207
|
+
- For example, if you want to use the 'current_user' variable in a function call:
|
208
|
+
{{"user_id": {{"variable": "current_user"}}}}
|
209
|
+
|
144
210
|
Remember:
|
145
211
|
- Always perform one operation at a time
|
146
212
|
- Use intermediate results from previous steps
|
147
213
|
- If a step requires multiple tools, execute them sequentially
|
148
214
|
- If you're unsure about the next step, explain your reasoning
|
149
|
-
|
150
|
-
|
215
|
+
- You can use both stored variables and values from the prompt
|
216
|
+
- When using stored variables, ALWAYS use the {{"variable": "variable_name"}} syntax
|
217
|
+
""".format(
|
218
|
+
tools_list="\n".join([f"- {name}: {desc}" for name, desc in
|
219
|
+
[(tool['name'], tool['description']) for tool in self._registered_tools_json]]),
|
220
|
+
variables_list=variables_info
|
221
|
+
)
|
222
|
+
|
223
|
+
def _substitute_variables(self, args: Dict[str, Any]) -> Dict[str, Any]:
|
224
|
+
"""
|
225
|
+
Substitutes stored variable values in function arguments.
|
226
|
+
|
227
|
+
Args:
|
228
|
+
args: Dictionary of argument names to values
|
229
|
+
|
230
|
+
Returns:
|
231
|
+
Dictionary with variable values substituted where applicable
|
232
|
+
"""
|
233
|
+
substituted_args = {}
|
234
|
+
for name, value in args.items():
|
235
|
+
if isinstance(value, dict) and "variable" in value:
|
236
|
+
var_name = value["variable"]
|
237
|
+
if var_name in self._stored_variables:
|
238
|
+
substituted_args[name] = self._stored_variables[var_name]['value']
|
239
|
+
else:
|
240
|
+
substituted_args[name] = value
|
241
|
+
else:
|
242
|
+
substituted_args[name] = value
|
243
|
+
return substituted_args
|
151
244
|
|
152
245
|
def _call_gemini_api(self, payload: Dict[str, Any]) -> Dict[str, Any]:
|
153
246
|
"""Makes a POST request to the Gemini generateContent endpoint."""
|
@@ -192,14 +285,14 @@ class Agent:
|
|
192
285
|
self._intermediate_results = {}
|
193
286
|
|
194
287
|
if not system_prompt:
|
195
|
-
system_prompt = self._get_system_prompt() + system_prompt
|
196
|
-
else:
|
197
288
|
system_prompt = self._get_system_prompt()
|
289
|
+
else:
|
290
|
+
system_prompt = self._get_system_prompt() + system_prompt
|
198
291
|
|
199
292
|
current_contents = conversation_history if conversation_history else []
|
200
293
|
if system_prompt and not current_contents:
|
201
294
|
current_contents.append({'role': 'user', 'parts': [{'text': system_prompt}]})
|
202
|
-
current_contents.append({'role': 'model', 'parts': [{'text': "I understand I should break down complex tasks into sequential steps using the available tools."}]})
|
295
|
+
current_contents.append({'role': 'model', 'parts': [{'text': "I understand I should break down complex tasks into sequential steps using the available tools and variables."}]})
|
203
296
|
|
204
297
|
current_contents.append({'role': 'user', 'parts': [{'text': user_prompt}]})
|
205
298
|
payload: Dict[str, Any] = {"contents": current_contents}
|
@@ -214,6 +307,14 @@ class Agent:
|
|
214
307
|
|
215
308
|
if response_structure and not self._registered_tools_json:
|
216
309
|
apply_structure_later = False
|
310
|
+
# If response_structure is a string type, make it more flexible
|
311
|
+
if response_structure.get("type") == "string":
|
312
|
+
response_structure = {
|
313
|
+
"type": ["string", "object"],
|
314
|
+
"properties": {
|
315
|
+
"value": {"type": "string"}
|
316
|
+
}
|
317
|
+
}
|
217
318
|
payload["generationConfig"] = {
|
218
319
|
"response_mime_type": "application/json",
|
219
320
|
"response_schema": response_structure
|
@@ -223,7 +324,6 @@ class Agent:
|
|
223
324
|
|
224
325
|
while True:
|
225
326
|
response_data = self._call_gemini_api(payload)
|
226
|
-
|
227
327
|
if "error" in response_data:
|
228
328
|
print(f"API call failed: {response_data['error'].get('message', 'Unknown API error')}")
|
229
329
|
return response_data
|
@@ -266,13 +366,17 @@ class Agent:
|
|
266
366
|
tool_function = self._tool_functions[tool_name]
|
267
367
|
print(f"--- Calling Function: {tool_name}({args}) ---")
|
268
368
|
|
369
|
+
# Substitute both stored variables and intermediate results
|
370
|
+
args = self._substitute_variables(args)
|
269
371
|
for key, value in args.items():
|
270
372
|
if isinstance(value, str) and value.startswith('$'):
|
271
373
|
result_key = value[1:]
|
272
374
|
if result_key in self._intermediate_results:
|
273
375
|
args[key] = self._intermediate_results[result_key]
|
274
376
|
|
377
|
+
# Call the function directly - it's already bound if it's a method
|
275
378
|
function_result = tool_function(**args)
|
379
|
+
|
276
380
|
print(f"--- Function Result: {function_result} ---")
|
277
381
|
|
278
382
|
result_key = f"result_{len(self._intermediate_results)}"
|
@@ -0,0 +1,66 @@
|
|
1
|
+
import os
|
2
|
+
from dotenv import load_dotenv
|
3
|
+
from framework_agent import Agent
|
4
|
+
|
5
|
+
load_dotenv()
|
6
|
+
|
7
|
+
def test_basic_operations():
|
8
|
+
# Define some basic math operations
|
9
|
+
@Agent.description("Multiplies two numbers.")
|
10
|
+
@Agent.parameters({
|
11
|
+
'a': {'type': int, 'description': 'The first number'},
|
12
|
+
'b': {'type': int, 'description': 'The second number'}
|
13
|
+
})
|
14
|
+
def multiply(a: int, b: int) -> int:
|
15
|
+
return a * b
|
16
|
+
|
17
|
+
@Agent.description("Adds two numbers.")
|
18
|
+
@Agent.parameters({
|
19
|
+
'a': {'type': int, 'description': 'The first number'},
|
20
|
+
'b': {'type': int, 'description': 'The second number'}
|
21
|
+
})
|
22
|
+
def add(a: int, b: int) -> int:
|
23
|
+
return a + b
|
24
|
+
|
25
|
+
# Create an agent with the math tools
|
26
|
+
agent = Agent(
|
27
|
+
api_key=os.getenv("GEMINI_API_KEY"),
|
28
|
+
tools=[multiply, add]
|
29
|
+
)
|
30
|
+
|
31
|
+
# Test a simple multiplication
|
32
|
+
response = agent.prompt("Multiply 3 and 7")
|
33
|
+
print(f"Multiplication result: {response}") # Should be 21
|
34
|
+
|
35
|
+
# Use the agent
|
36
|
+
response = agent.prompt(user_prompt="multiply 3 and 7 then add 5 to the result" ,
|
37
|
+
system_prompt="You are a helpful assistant give your response always with ❤️ at the start of the line. in your response you should mention the function you used." ,
|
38
|
+
response_structure=
|
39
|
+
{
|
40
|
+
"type": "object",
|
41
|
+
"properties": {
|
42
|
+
"used_functions": {
|
43
|
+
"type": "array",
|
44
|
+
"items": {
|
45
|
+
"type": "object",
|
46
|
+
"properties": {
|
47
|
+
"function_name": {"type": "string"},
|
48
|
+
"parameters": {
|
49
|
+
"type": "object",
|
50
|
+
"properties": {
|
51
|
+
"a": {"type": "integer"},
|
52
|
+
"b": {"type": "integer"}
|
53
|
+
}
|
54
|
+
}
|
55
|
+
}
|
56
|
+
}
|
57
|
+
},
|
58
|
+
"answer": {"type": "string"}
|
59
|
+
|
60
|
+
}
|
61
|
+
}
|
62
|
+
)
|
63
|
+
print(response) # Should output 21
|
64
|
+
|
65
|
+
if __name__ == "__main__":
|
66
|
+
test_basic_operations()
|
@@ -0,0 +1,67 @@
|
|
1
|
+
import os
|
2
|
+
from dotenv import load_dotenv
|
3
|
+
from gemini_agent import Agent
|
4
|
+
|
5
|
+
load_dotenv()
|
6
|
+
|
7
|
+
class Calculator:
|
8
|
+
def __init__(self):
|
9
|
+
self.memory = 0
|
10
|
+
|
11
|
+
@Agent.description("Multiplies a number by the stored memory value.")
|
12
|
+
@Agent.parameters({
|
13
|
+
'number': {'type': int, 'description': 'The number to multiply with memory'}
|
14
|
+
})
|
15
|
+
def multiply_with_memory(self, number: int) -> int:
|
16
|
+
result = self.memory * number
|
17
|
+
self.memory = result
|
18
|
+
return result
|
19
|
+
|
20
|
+
@Agent.description("Adds a number to the stored memory value.")
|
21
|
+
@Agent.parameters({
|
22
|
+
'number': {'type': int, 'description': 'The number to add to memory'}
|
23
|
+
})
|
24
|
+
def add_to_memory(self, number: int) -> int:
|
25
|
+
result = self.memory + number
|
26
|
+
self.memory = result
|
27
|
+
return result
|
28
|
+
|
29
|
+
def test_class_methods():
|
30
|
+
# Create a calculator instance
|
31
|
+
calculator = Calculator()
|
32
|
+
|
33
|
+
# Create an agent with the calculator methods
|
34
|
+
agent = Agent(
|
35
|
+
api_key=os.getenv("GEMINI_API_KEY"),
|
36
|
+
tools=[calculator.multiply_with_memory, calculator.add_to_memory]
|
37
|
+
)
|
38
|
+
|
39
|
+
# Test using class methods
|
40
|
+
response = agent.prompt(
|
41
|
+
"Multiply 5 with memory (starting at 0), then add 10 to the result",
|
42
|
+
response_structure={
|
43
|
+
"type": "object",
|
44
|
+
"properties": {
|
45
|
+
"used_functions": {
|
46
|
+
"type": "array",
|
47
|
+
"items": {
|
48
|
+
"type": "object",
|
49
|
+
"properties": {
|
50
|
+
"function_name": {"type": "string"},
|
51
|
+
"parameters": {
|
52
|
+
"type": "object",
|
53
|
+
"properties": {
|
54
|
+
"number": {"type": "integer"}
|
55
|
+
}
|
56
|
+
}
|
57
|
+
}
|
58
|
+
}
|
59
|
+
},
|
60
|
+
"answer": {"type": "string"}
|
61
|
+
}
|
62
|
+
}
|
63
|
+
)
|
64
|
+
print(response)
|
65
|
+
|
66
|
+
if __name__ == "__main__":
|
67
|
+
test_class_methods()
|
@@ -0,0 +1,133 @@
|
|
1
|
+
from agent import Agent
|
2
|
+
import os
|
3
|
+
from dotenv import load_dotenv
|
4
|
+
import json
|
5
|
+
from bs4 import BeautifulSoup
|
6
|
+
|
7
|
+
load_dotenv()
|
8
|
+
|
9
|
+
class HTMLAnalyzer:
|
10
|
+
@Agent.description("Count the number of input tags in an HTML page")
|
11
|
+
@Agent.parameters({
|
12
|
+
'html_content': {'type': str, 'description': 'The HTML content to analyze'}
|
13
|
+
})
|
14
|
+
def count_inputs(self, html_content: str) -> dict:
|
15
|
+
soup = BeautifulSoup(html_content, 'html.parser')
|
16
|
+
input_tags = soup.find_all('input')
|
17
|
+
return {
|
18
|
+
"count": len(input_tags),
|
19
|
+
"input_types": [tag.get('type', 'unknown') for tag in input_tags]
|
20
|
+
}
|
21
|
+
|
22
|
+
# Create HTML pages
|
23
|
+
home_page = """
|
24
|
+
<!DOCTYPE html>
|
25
|
+
<html>
|
26
|
+
<head>
|
27
|
+
<title>Home Page</title>
|
28
|
+
</head>
|
29
|
+
<body>
|
30
|
+
<header>
|
31
|
+
<nav>
|
32
|
+
<a href="/">Home</a>
|
33
|
+
<a href="/about">About</a>
|
34
|
+
<a href="/contact">Contact</a>
|
35
|
+
</nav>
|
36
|
+
</header>
|
37
|
+
<main>
|
38
|
+
<h1>Welcome to Our Website</h1>
|
39
|
+
<p>This is a simple home page with no input fields.</p>
|
40
|
+
</main>
|
41
|
+
<footer>
|
42
|
+
<p>© 2024 Our Website</p>
|
43
|
+
</footer>
|
44
|
+
</body>
|
45
|
+
</html>
|
46
|
+
"""
|
47
|
+
|
48
|
+
login_page = """
|
49
|
+
<!DOCTYPE html>
|
50
|
+
<html>
|
51
|
+
<head>
|
52
|
+
<title>Login Page</title>
|
53
|
+
</head>
|
54
|
+
<body>
|
55
|
+
<header>
|
56
|
+
<nav>
|
57
|
+
<a href="/">Home</a>
|
58
|
+
<a href="/login">Login</a>
|
59
|
+
</nav>
|
60
|
+
</header>
|
61
|
+
<main>
|
62
|
+
<h1>Login</h1>
|
63
|
+
<form action="/login" method="POST">
|
64
|
+
<div>
|
65
|
+
<label for="username">Username:</label>
|
66
|
+
<input type="text" id="username" name="username" required>
|
67
|
+
</div>
|
68
|
+
<div>
|
69
|
+
<label for="password">Password:</label>
|
70
|
+
<input type="password" id="password" name="password" required>
|
71
|
+
</div>
|
72
|
+
<div>
|
73
|
+
<input type="checkbox" id="remember" name="remember">
|
74
|
+
<label for="remember">Remember me</label>
|
75
|
+
</div>
|
76
|
+
<button type="submit">Login</button>
|
77
|
+
</form>
|
78
|
+
</main>
|
79
|
+
<footer>
|
80
|
+
<p>© 2024 Our Website</p>
|
81
|
+
</footer>
|
82
|
+
</body>
|
83
|
+
</html>
|
84
|
+
"""
|
85
|
+
|
86
|
+
# Create the analyzer instance
|
87
|
+
html_analyzer = HTMLAnalyzer()
|
88
|
+
|
89
|
+
# Create the agent with our tool
|
90
|
+
agent = Agent(
|
91
|
+
api_key=os.getenv("GEMINI_API_KEY"),
|
92
|
+
tools=[html_analyzer.count_inputs]
|
93
|
+
)
|
94
|
+
|
95
|
+
# Store the HTML pages as variables
|
96
|
+
agent.set_variable(
|
97
|
+
name="home_page",
|
98
|
+
value=home_page,
|
99
|
+
description="The HTML content of the home page",
|
100
|
+
type_hint=str
|
101
|
+
)
|
102
|
+
|
103
|
+
|
104
|
+
|
105
|
+
# Example 1: Count inputs in home page
|
106
|
+
print("\nExample 1: Count inputs in home page")
|
107
|
+
response = agent.prompt(
|
108
|
+
"How many input tags are in the home page?",
|
109
|
+
response_structure={
|
110
|
+
"type": "object",
|
111
|
+
"properties": {
|
112
|
+
"count": {"type": "integer"},
|
113
|
+
"input_types": {"type": "array", "items": {"type": "string"}}
|
114
|
+
},
|
115
|
+
"required": ["count", "input_types"]
|
116
|
+
}
|
117
|
+
)
|
118
|
+
print(json.dumps(response, indent=2))
|
119
|
+
|
120
|
+
# Example 2: Count inputs in login page
|
121
|
+
print("\nExample 2: Count inputs in login page")
|
122
|
+
response = agent.prompt(
|
123
|
+
"How many input tags are in this page "+ login_page,
|
124
|
+
response_structure={
|
125
|
+
"type": "object",
|
126
|
+
"properties": {
|
127
|
+
"count": {"type": "integer"},
|
128
|
+
"input_types": {"type": "array", "items": {"type": "string"}}
|
129
|
+
},
|
130
|
+
"required": ["count", "input_types"]
|
131
|
+
}
|
132
|
+
)
|
133
|
+
print(json.dumps(response, indent=2))
|
@@ -1,48 +0,0 @@
|
|
1
|
-
import os
|
2
|
-
from dotenv import load_dotenv
|
3
|
-
from src.gemini_agent import Agent
|
4
|
-
|
5
|
-
load_dotenv()
|
6
|
-
|
7
|
-
def test_basic_operations():
|
8
|
-
# Define some basic math operations
|
9
|
-
@Agent.description("Multiplies two numbers.")
|
10
|
-
@Agent.parameters({
|
11
|
-
'a': {'type': int, 'description': 'The first number'},
|
12
|
-
'b': {'type': int, 'description': 'The second number'}
|
13
|
-
})
|
14
|
-
def multiply(a: int, b: int) -> int:
|
15
|
-
return a * b
|
16
|
-
|
17
|
-
@Agent.description("Adds two numbers.")
|
18
|
-
@Agent.parameters({
|
19
|
-
'a': {'type': int, 'description': 'The first number'},
|
20
|
-
'b': {'type': int, 'description': 'The second number'}
|
21
|
-
})
|
22
|
-
def add(a: int, b: int) -> int:
|
23
|
-
return a + b
|
24
|
-
|
25
|
-
# Create an agent with the math tools
|
26
|
-
agent = Agent(
|
27
|
-
api_key=os.getenv("GEMINI_API_KEY"),
|
28
|
-
tools=[multiply, add]
|
29
|
-
)
|
30
|
-
|
31
|
-
# Test a simple multiplication
|
32
|
-
response = agent.prompt("Multiply 3 and 7")
|
33
|
-
print(f"Multiplication result: {response}") # Should be 21
|
34
|
-
|
35
|
-
# Test a complex operation
|
36
|
-
response = agent.prompt(
|
37
|
-
"Multiply 3 and 7, then add 4 to the result",
|
38
|
-
response_structure={
|
39
|
-
"type": "object",
|
40
|
-
"properties": {
|
41
|
-
"result": {"type": "number"}
|
42
|
-
}
|
43
|
-
}
|
44
|
-
)
|
45
|
-
print(f"Complex operation result: {response}") # Should be {"result": 25}
|
46
|
-
|
47
|
-
if __name__ == "__main__":
|
48
|
-
test_basic_operations()
|
File without changes
|
File without changes
|
File without changes
|