update
Browse files- __init__.py +0 -1
- bak/get_weather/.env.example +0 -4
- bak/get_weather/__init__.py +0 -1
- bak/get_weather/agent.py +0 -53
- bak/get_weather/readme.md +0 -19
- bak/get_weather/team.py +0 -33
- bak/get_weather/tool.py.copy +0 -23
- bak/get_weather/tools/__init__.py +0 -0
- bak/get_weather/tools/get_current_time.py +0 -28
- bak/get_weather/tools/get_weather.py +0 -22
- read.me.md +11 -5
- requirements.txt +1 -0
- team_framework/__init__.py +0 -1
- bak/get_weather/cache.py → team_framework/api_key_manager.py +7 -15
- team_framework/init.py +5 -0
- team_framework/load_agents.py +0 -32
- team_framework/load_team_config.py +0 -93
- team_framework/load_tools.py +0 -30
- team_framework/store.py +8 -0
- teams/ai_quant/agent.py +108 -145
- teams/ai_quant/tools/__init__.py +0 -0
- teams/ai_quant/tools/get_current_time.py +0 -28
- teams/ai_quant/tools/get_weather.py +0 -22
- test.py +0 -5
- utils.py.willdel +0 -122
__init__.py
CHANGED
|
@@ -1 +0,0 @@
|
|
| 1 |
-
print('\n\n\n\n\n\n\n\n\n&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&')
|
|
|
|
|
|
bak/get_weather/.env.example
DELETED
|
@@ -1,4 +0,0 @@
|
|
| 1 |
-
SUPABASE_URL=https://bbvyxjvleoizsipxydsm.supabase.co
|
| 2 |
-
SUPABASE_KEY=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImJidnl4anZsZW9penNpcHh5ZHNtIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NDQ1MzkwNjIsImV4cCI6MjA2MDExNTA2Mn0.cbUNhiCHXqIaW4leU_vGTKVI51gLVvsFOVWYS_vJrA4
|
| 3 |
-
GOOGLE_GENAI_USE_VERTEXAI=FALSE
|
| 4 |
-
GOOGLE_API_KEY=AIzaSyBYPwMLibOIoM-SQHuWjZ-V4LLmmMxqhm8
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bak/get_weather/__init__.py
DELETED
|
@@ -1 +0,0 @@
|
|
| 1 |
-
from . import agent
|
|
|
|
|
|
bak/get_weather/agent.py
DELETED
|
@@ -1,53 +0,0 @@
|
|
| 1 |
-
### adk web ./teams
|
| 2 |
-
from google.adk.agents import Agent
|
| 3 |
-
from .tools.get_current_time import get_current_time
|
| 4 |
-
from .tools.get_weather import get_weather
|
| 5 |
-
from .cache import get_api_key
|
| 6 |
-
# from .team import init_team, get_team
|
| 7 |
-
import os
|
| 8 |
-
|
| 9 |
-
def my_before_model_callback(callback_context, **kwargs):
|
| 10 |
-
os.environ["GOOGLE_API_KEY"] = get_api_key() # 直接设置环境变量
|
| 11 |
-
print('888888888888888888888888888888888888888888888')
|
| 12 |
-
|
| 13 |
-
greeting_agent = Agent(
|
| 14 |
-
name="greeting_agent",
|
| 15 |
-
model="gemini-2.5-flash-preview-04-17",
|
| 16 |
-
instruction="You are the Greeting Agent. Your ONLY task is to provide a friendly greeting to the user. "
|
| 17 |
-
"Do not engage in any other conversation or tasks."
|
| 18 |
-
"before you answer, you should say your name: 'I am greeting_agent'",
|
| 19 |
-
description="Handles simple greetings and hellos",
|
| 20 |
-
before_model_callback=my_before_model_callback
|
| 21 |
-
)
|
| 22 |
-
|
| 23 |
-
farewell_agent = Agent(
|
| 24 |
-
name="farewell_agent",
|
| 25 |
-
model="gemini-2.5-flash-preview-04-17",
|
| 26 |
-
instruction="You are the Farewell Agent. Your ONLY task is to provide a polite goodbye message. "
|
| 27 |
-
"If not about goodbye, just transfer to weather_time_agent"
|
| 28 |
-
"Do not perform any other actions."
|
| 29 |
-
"before you answer, you should say your name: 'I am farewell_agent'",
|
| 30 |
-
before_model_callback=my_before_model_callback,
|
| 31 |
-
description="Handles simple farewells and goodbyes",
|
| 32 |
-
)
|
| 33 |
-
|
| 34 |
-
print("\n\n\n\n\n\n\n\n&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&&\nroot_agent init")
|
| 35 |
-
root_agent=Agent(
|
| 36 |
-
name="weather_time_agent",
|
| 37 |
-
model="gemini-2.5-flash-preview-04-17",
|
| 38 |
-
description=(
|
| 39 |
-
"Agent to answer questions about the time and weather in a city."
|
| 40 |
-
),
|
| 41 |
-
instruction=(
|
| 42 |
-
"You are a helpful agent who can answer user questions about the time and weather in a city."
|
| 43 |
-
"before you answer, you should say your name: 'I am weather_time_agent'"
|
| 44 |
-
),
|
| 45 |
-
# global_instruction = '请在每一句回答里都加上:“我的主人”',
|
| 46 |
-
tools=[get_weather, get_current_time],
|
| 47 |
-
sub_agents=[greeting_agent, farewell_agent],
|
| 48 |
-
before_model_callback=my_before_model_callback
|
| 49 |
-
)
|
| 50 |
-
|
| 51 |
-
import pprint
|
| 52 |
-
print('\n\n\n\n*************************************\n\nroot_agent dict: \n')
|
| 53 |
-
pprint.pprint(root_agent.__dict__) # 尝试打印对象的字典表示
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bak/get_weather/readme.md
DELETED
|
@@ -1,19 +0,0 @@
|
|
| 1 |
-
## 默认约定
|
| 2 |
-
|
| 3 |
-
### 目录结构
|
| 4 |
-
|
| 5 |
-
ADK-TEAMS # 项目根目录
|
| 6 |
-
|- teams # 包含多个团队的目录代码,每一个子目录为一个团队
|
| 7 |
-
| |- get_weather # 团队目录。示例:获取天气信息团队
|
| 8 |
-
| |- agents # agents 目录。处理从数据库加载 agents 的代码
|
| 9 |
-
| |- tools # tools 目录。处理从数据库加载 tools 的代码
|
| 10 |
-
| |- __init__.py # 初始化代码
|
| 11 |
-
| |- .env # 环境变量文件
|
| 12 |
-
| |- agent.py # 团队的 agent 入口代码
|
| 13 |
-
| |- readme.md # 团队的 README 文件(当前文件)
|
| 14 |
-
| |- tools.py # 团队的 tools 入口代码
|
| 15 |
-
|- .gitattributes # Git 属性文件
|
| 16 |
-
|- .gitignore # Git 忽略文件
|
| 17 |
-
|- Dockerfile # Dockerfile 文件
|
| 18 |
-
|- README.md # 项目的 README 文件
|
| 19 |
-
|- requirements.txt # 项目的依赖文件
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bak/get_weather/team.py
DELETED
|
@@ -1,33 +0,0 @@
|
|
| 1 |
-
import sys, os
|
| 2 |
-
sys.path.append(os.path.abspath(os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', '..')))
|
| 3 |
-
from team_framework.load_team_config import load_team_config
|
| 4 |
-
from team_framework.load_tools import load_tools
|
| 5 |
-
from team_framework.load_agents import load_agents, load_root_agent
|
| 6 |
-
from google.adk.agents import Agent
|
| 7 |
-
|
| 8 |
-
_team = {}
|
| 9 |
-
|
| 10 |
-
def init_team():
|
| 11 |
-
global _team
|
| 12 |
-
_team= {}
|
| 13 |
-
_team_config = load_team_config()
|
| 14 |
-
print('\n\n\n\n\n***************************\n_team_config')
|
| 15 |
-
print(_team_config)
|
| 16 |
-
_team["tools"] = load_tools(_team_config['tools'])
|
| 17 |
-
_team["agents"] = load_agents(_team_config['agents'])
|
| 18 |
-
|
| 19 |
-
_team["root_agent"] = load_root_agent(_team_config['root_agent'])
|
| 20 |
-
_team["root_agent"].tools = [] ## 为 root_agent 添加工具
|
| 21 |
-
for item in _team_config['root_agent']['tools']:
|
| 22 |
-
# print('\n\n\n\n|||||||||||||||||| item',item)
|
| 23 |
-
_team["root_agent"].tools.append(_team['tools'][item])
|
| 24 |
-
_team["root_agent"].sub_agents=[]
|
| 25 |
-
for item in _team_config['root_agent']['sub_agents']:
|
| 26 |
-
print('\n\n\n\n|||||||||||||||||||||||||||||||||||||||||||||||||||||||||||| \nitem',item)
|
| 27 |
-
print(_team['agents'][item])
|
| 28 |
-
_team["root_agent"].sub_agents.append(_team['agents'][item])
|
| 29 |
-
# _team["root_agent"].agents.append(_team['agents'][item])
|
| 30 |
-
|
| 31 |
-
def get_team():
|
| 32 |
-
global _team
|
| 33 |
-
return _team
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bak/get_weather/tool.py.copy
DELETED
|
@@ -1,23 +0,0 @@
|
|
| 1 |
-
import importlib
|
| 2 |
-
|
| 3 |
-
def load_tools_from_array(arr:list):
|
| 4 |
-
ret = {}
|
| 5 |
-
for item in arr:
|
| 6 |
-
# 构建正确的模块路径,使用 __name__ 动态获取当前模块的父路径(此处正好为团队名称),并加上 .tools 子目录和工具名称
|
| 7 |
-
parent_module_path = '.'.join(__name__.split('.')[:-1])
|
| 8 |
-
module_path = f'{parent_module_path}.tools.{item}'
|
| 9 |
-
try:
|
| 10 |
-
module = importlib.import_module(module_path)
|
| 11 |
-
# 函数名预期与工具名称相同
|
| 12 |
-
func = getattr(module, item)
|
| 13 |
-
ret[item] = func
|
| 14 |
-
print(f"成功从模块 '{module_path}' 导入函数 '{item}'")
|
| 15 |
-
except ImportError as e:
|
| 16 |
-
print(f"导入模块 {module_path} 时出错: {e}")
|
| 17 |
-
except AttributeError as e:
|
| 18 |
-
print(f"在模块 {module_path} 中找不到函数 '{item}': {e}")
|
| 19 |
-
return ret
|
| 20 |
-
|
| 21 |
-
def load_tools_from_db():
|
| 22 |
-
tool_arr = ["get_weather", "get_current_time"]
|
| 23 |
-
return load_tools_from_array(tool_arr)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bak/get_weather/tools/__init__.py
DELETED
|
File without changes
|
bak/get_weather/tools/get_current_time.py
DELETED
|
@@ -1,28 +0,0 @@
|
|
| 1 |
-
import datetime
|
| 2 |
-
from zoneinfo import ZoneInfo
|
| 3 |
-
def get_current_time(city: str) -> dict:
|
| 4 |
-
"""Returns the current time in a specified city.
|
| 5 |
-
|
| 6 |
-
Args:
|
| 7 |
-
city (str): The name of the city for which to retrieve the current time.
|
| 8 |
-
|
| 9 |
-
Returns:
|
| 10 |
-
dict: status and result or error msg.
|
| 11 |
-
"""
|
| 12 |
-
|
| 13 |
-
if city.lower() == "new york":
|
| 14 |
-
tz_identifier = "America/New_York"
|
| 15 |
-
else:
|
| 16 |
-
return {
|
| 17 |
-
"status": "error",
|
| 18 |
-
"error_message": (
|
| 19 |
-
f"Sorry, I don't have timezone information for {city}."
|
| 20 |
-
),
|
| 21 |
-
}
|
| 22 |
-
|
| 23 |
-
tz = ZoneInfo(tz_identifier)
|
| 24 |
-
now = datetime.datetime.now(tz)
|
| 25 |
-
report = (
|
| 26 |
-
f'The current time in {city} is {now.strftime("%Y-%m-%d %H:%M:%S %Z%z")}'
|
| 27 |
-
)
|
| 28 |
-
return {"status": "success", "report": report}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
bak/get_weather/tools/get_weather.py
DELETED
|
@@ -1,22 +0,0 @@
|
|
| 1 |
-
def get_weather(city: str) -> dict:
|
| 2 |
-
"""Retrieves the current weather report for a specified city.
|
| 3 |
-
|
| 4 |
-
Args:
|
| 5 |
-
city (str): The name of the city for which to retrieve the weather report.
|
| 6 |
-
|
| 7 |
-
Returns:
|
| 8 |
-
dict: status and result or error msg.
|
| 9 |
-
"""
|
| 10 |
-
if city.lower() == "new york":
|
| 11 |
-
return {
|
| 12 |
-
"status": "success",
|
| 13 |
-
"report": (
|
| 14 |
-
"The weather in New York is sunny with a temperature of 25 degrees"
|
| 15 |
-
" Celsius (77 degrees Fahrenheit)."
|
| 16 |
-
),
|
| 17 |
-
}
|
| 18 |
-
else:
|
| 19 |
-
return {
|
| 20 |
-
"status": "error",
|
| 21 |
-
"error_message": f"Weather information for '{city}' is not available.",
|
| 22 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
read.me.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
| 1 |
-
|
| 2 |
-
|
| 3 |
-
|
| 4 |
-
|
| 5 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
环境:
|
| 2 |
+
conda: google-adk
|
| 3 |
+
hugging-face: tanbushi
|
| 4 |
+
|
| 5 |
+
数据库:
|
| 6 |
+
supabase
|
| 7 |
+
site: http://supabase.com
|
| 8 |
+
username: tanbushi@qq.com
|
| 9 |
+
project: rzwl2024
|
| 10 |
+
|
| 11 |
+
运行:adk web ./teams
|
requirements.txt
CHANGED
|
@@ -1,3 +1,4 @@
|
|
| 1 |
google-adk
|
| 2 |
supabase
|
| 3 |
litellm
|
|
|
|
|
|
| 1 |
google-adk
|
| 2 |
supabase
|
| 3 |
litellm
|
| 4 |
+
python-dotenv
|
team_framework/__init__.py
CHANGED
|
@@ -1 +0,0 @@
|
|
| 1 |
-
# from . import load_team_config
|
|
|
|
|
|
bak/get_weather/cache.py → team_framework/api_key_manager.py
RENAMED
|
@@ -1,27 +1,21 @@
|
|
| 1 |
import os
|
| 2 |
-
from supabase import create_client, Client
|
| 3 |
import time
|
|
|
|
|
|
|
|
|
|
|
|
|
| 4 |
|
| 5 |
# Simple in-memory cache
|
| 6 |
api_key_cache = {}
|
| 7 |
last_loaded_time = 0
|
| 8 |
CACHE_TTL = 300 # Cache time-to-live in seconds (5 minutes)
|
| 9 |
|
| 10 |
-
def get_supabase_client() -> Client:
|
| 11 |
-
"""Initializes and returns a Supabase client."""
|
| 12 |
-
url: str = os.environ.get("SUPABASE_URL")
|
| 13 |
-
key: str = os.environ.get("SUPABASE_KEY")
|
| 14 |
-
if not url or not key:
|
| 15 |
-
print("Supabase URL or Key not found in environment variables.")
|
| 16 |
-
return None
|
| 17 |
-
return create_client(url, key)
|
| 18 |
-
|
| 19 |
def load_api_keys_from_db():
|
| 20 |
"""Loads API keys from the database into the cache."""
|
| 21 |
global api_key_cache
|
| 22 |
|
| 23 |
print("Loading API keys from database...")
|
| 24 |
-
supabase
|
| 25 |
if not supabase:
|
| 26 |
return {}
|
| 27 |
|
|
@@ -31,7 +25,7 @@ def load_api_keys_from_db():
|
|
| 31 |
# {
|
| 32 |
# 'config': {
|
| 33 |
# 'api_keys': [
|
| 34 |
-
# {'api_key': 'xxxxx', 'can_use_at': 0},
|
| 35 |
# {'api_key': 'yyyyy', 'can_use_at': 0}
|
| 36 |
# ]
|
| 37 |
# }
|
|
@@ -56,7 +50,6 @@ def load_api_keys_from_db():
|
|
| 56 |
except Exception as e:
|
| 57 |
print(f"Error loading API keys from database: {e}")
|
| 58 |
api_key_cache = {} # Clear cache on error
|
| 59 |
-
|
| 60 |
return api_key_cache
|
| 61 |
|
| 62 |
def get_api_key():
|
|
@@ -70,10 +63,9 @@ def get_api_key():
|
|
| 70 |
load_api_keys_from_db()
|
| 71 |
# api_key_cache={'xxxxx': 1, 'yyyyy': 0}
|
| 72 |
# print('api_key_cache',api_key_cache)
|
| 73 |
-
|
| 74 |
# Sort available keys by their 'can_use_at' timestamp in ascending order
|
| 75 |
sorted_key_cache = sorted(api_key_cache, key=lambda key: api_key_cache.get(key, float('inf')))
|
| 76 |
-
# print('\n\n\n\n\n\n\n\n\nsorted_key_cache',sorted_key_cache)
|
| 77 |
|
| 78 |
# Select the key with the smallest 'can_use_at' value
|
| 79 |
selected_key = sorted_key_cache[0]
|
|
|
|
| 1 |
import os
|
|
|
|
| 2 |
import time
|
| 3 |
+
from dotenv import load_dotenv
|
| 4 |
+
from .supabase_cli import get_supabase_client # Import from the existing supabase_cli
|
| 5 |
+
|
| 6 |
+
load_dotenv()
|
| 7 |
|
| 8 |
# Simple in-memory cache
|
| 9 |
api_key_cache = {}
|
| 10 |
last_loaded_time = 0
|
| 11 |
CACHE_TTL = 300 # Cache time-to-live in seconds (5 minutes)
|
| 12 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 13 |
def load_api_keys_from_db():
|
| 14 |
"""Loads API keys from the database into the cache."""
|
| 15 |
global api_key_cache
|
| 16 |
|
| 17 |
print("Loading API keys from database...")
|
| 18 |
+
supabase = get_supabase_client() # Use the imported function
|
| 19 |
if not supabase:
|
| 20 |
return {}
|
| 21 |
|
|
|
|
| 25 |
# {
|
| 26 |
# 'config': {
|
| 27 |
# 'api_keys': [
|
| 28 |
+
# {'api_key': 'xxxxx', 'can_use_at': 0},
|
| 29 |
# {'api_key': 'yyyyy', 'can_use_at': 0}
|
| 30 |
# ]
|
| 31 |
# }
|
|
|
|
| 50 |
except Exception as e:
|
| 51 |
print(f"Error loading API keys from database: {e}")
|
| 52 |
api_key_cache = {} # Clear cache on error
|
|
|
|
| 53 |
return api_key_cache
|
| 54 |
|
| 55 |
def get_api_key():
|
|
|
|
| 63 |
load_api_keys_from_db()
|
| 64 |
# api_key_cache={'xxxxx': 1, 'yyyyy': 0}
|
| 65 |
# print('api_key_cache',api_key_cache)
|
| 66 |
+
|
| 67 |
# Sort available keys by their 'can_use_at' timestamp in ascending order
|
| 68 |
sorted_key_cache = sorted(api_key_cache, key=lambda key: api_key_cache.get(key, float('inf')))
|
|
|
|
| 69 |
|
| 70 |
# Select the key with the smallest 'can_use_at' value
|
| 71 |
selected_key = sorted_key_cache[0]
|
team_framework/init.py
ADDED
|
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
from . import store
|
| 2 |
+
import os
|
| 3 |
+
|
| 4 |
+
def init(PROJECT_ROOT):
|
| 5 |
+
store.PROJECT_ROOT = PROJECT_ROOT
|
team_framework/load_agents.py
DELETED
|
@@ -1,32 +0,0 @@
|
|
| 1 |
-
from google.adk.agents import Agent
|
| 2 |
-
import os
|
| 3 |
-
|
| 4 |
-
def my_before_model_callback(callback_context, **kwargs):
|
| 5 |
-
os.environ["GOOGLE_API_KEY"]='AIzaSyBYPwMLibOIoM-SQHuWjZ-V4LLmmMxqhm8'
|
| 6 |
-
# os.environ["GOOGLE_API_KEY"] = get_api_key() # 直接设置环境变量
|
| 7 |
-
|
| 8 |
-
def load_agent(item):
|
| 9 |
-
print(f"\nload_agent item: {item['name']}", item)
|
| 10 |
-
_agent = Agent(
|
| 11 |
-
name = item['name'],
|
| 12 |
-
model = item['model'],
|
| 13 |
-
instruction = item['instruction'],
|
| 14 |
-
description = item['description'],
|
| 15 |
-
before_model_callback=my_before_model_callback
|
| 16 |
-
)
|
| 17 |
-
return _agent
|
| 18 |
-
|
| 19 |
-
def load_agents(agents_dict:dict):
|
| 20 |
-
print("\n\n\n######## load_agents\nagents_dict: ", agents_dict)
|
| 21 |
-
ret_agents = {}
|
| 22 |
-
for item in agents_dict:
|
| 23 |
-
ret_agents[item['name']] = load_agent(item)
|
| 24 |
-
# ret_agents.append(load_agent(item))
|
| 25 |
-
print("\n\n\n@@@@@@@@@@@@@@@@@@@@@\nload_agents\nret_agents.greeting_agent: ", ret_agents['greeting_agent'])
|
| 26 |
-
print("\n\n\n@@@@@@@@@@@@@@@@@@@@@\nload_agents\nret_agents[farewell_agent]: ", ret_agents['farewell_agent'])
|
| 27 |
-
return ret_agents
|
| 28 |
-
|
| 29 |
-
def load_root_agent(_root_agent):
|
| 30 |
-
ret_agent = load_agent(_root_agent)
|
| 31 |
-
print("\n\n\n######## load_root_agent\nret_agent: ", ret_agent)
|
| 32 |
-
return ret_agent
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
team_framework/load_team_config.py
DELETED
|
@@ -1,93 +0,0 @@
|
|
| 1 |
-
from .supabase_cli import get_supabase_client
|
| 2 |
-
from supabase import Client
|
| 3 |
-
from google.adk.agents import Agent
|
| 4 |
-
|
| 5 |
-
def load_agent_config(db_item):
|
| 6 |
-
# print('\nload_agent_config...')
|
| 7 |
-
# print('\n\n\n\n\n***************************\ndb_item',db_item)
|
| 8 |
-
agent_config={
|
| 9 |
-
"name": db_item['name'],
|
| 10 |
-
"model": db_item['model'],
|
| 11 |
-
"instruction": db_item['instruction'],
|
| 12 |
-
"tools": db_item['tools'],
|
| 13 |
-
"sub_agents": db_item['sub_agents'],
|
| 14 |
-
"description": db_item['description']
|
| 15 |
-
}
|
| 16 |
-
tools_config=[]
|
| 17 |
-
if db_item['tools']:
|
| 18 |
-
agent_config['tools'] = db_item['tools']
|
| 19 |
-
tools_config = list(set(tools_config + db_item['tools']))
|
| 20 |
-
return { 'agent_config': agent_config, 'tools_config': tools_config}
|
| 21 |
-
|
| 22 |
-
def creat_agent() -> Agent:
|
| 23 |
-
pass
|
| 24 |
-
def load_team_config():
|
| 25 |
-
a_team_config = {
|
| 26 |
-
"agents":[],
|
| 27 |
-
"root_agent": None,
|
| 28 |
-
"tools":[]
|
| 29 |
-
}
|
| 30 |
-
|
| 31 |
-
print("Loading team_config from database...")
|
| 32 |
-
supabase: Client = get_supabase_client()
|
| 33 |
-
if not supabase:
|
| 34 |
-
return {}
|
| 35 |
-
try:
|
| 36 |
-
response = supabase.from_("team_get_weather").select("*").order("sort_id").execute()
|
| 37 |
-
for item in response.data:
|
| 38 |
-
if item['is_root']:
|
| 39 |
-
_agent_config = load_agent_config(item)
|
| 40 |
-
print('_agent_config',_agent_config)
|
| 41 |
-
a_team_config['root_agent'] = _agent_config['agent_config']
|
| 42 |
-
a_team_config['tools'] = list(set(a_team_config['tools'] + _agent_config['tools_config']))
|
| 43 |
-
else:
|
| 44 |
-
_agent_config = load_agent_config(item)
|
| 45 |
-
a_team_config['agents'].append(_agent_config['agent_config'])
|
| 46 |
-
a_team_config['tools'] = list(set(a_team_config['tools'] + _agent_config['tools_config']))
|
| 47 |
-
# print('\n\na_team_config',a_team_config)
|
| 48 |
-
except Exception as e:
|
| 49 |
-
print(f"Error loading API keys from database: {e}")
|
| 50 |
-
a_team_config = {} # Clear cache on error
|
| 51 |
-
return a_team_config
|
| 52 |
-
|
| 53 |
-
"""
|
| 54 |
-
a_team_config
|
| 55 |
-
{
|
| 56 |
-
'agents': [
|
| 57 |
-
{
|
| 58 |
-
'name': 'farewell_agent',
|
| 59 |
-
'model': 'gemini-2.5-flash-preview-04-17',
|
| 60 |
-
'instruction': "You are the Farewell Agent. Your ONLY task is to provide a polite goodbye message.\nIf not about goodbye, just transfer to weather_time_agent.\nDo not perform any other actions.\nBefore you answer, you should say your name: 'I am farewell_agent'",
|
| 61 |
-
'tools': None,
|
| 62 |
-
'sub_agents': None,
|
| 63 |
-
'description': 'Handles simple farewells and goodbyes'
|
| 64 |
-
},
|
| 65 |
-
{
|
| 66 |
-
'name': 'greeting_agent',
|
| 67 |
-
'model': 'gemini-2.5-flash-preview-04-17',
|
| 68 |
-
'instruction': "You are the Greeting Agent. Your ONLY task is to provide a friendly greeting to the user. \nDo not engage in any other conversation or tasks.\nBefore you answer, you should say your name: 'I am greeting_agent'",
|
| 69 |
-
'tools': None,
|
| 70 |
-
'sub_agents': None,
|
| 71 |
-
'description': 'Handles simple greetings and hellos'
|
| 72 |
-
}
|
| 73 |
-
],
|
| 74 |
-
'root_agent': {
|
| 75 |
-
'name': 'weather_time_agent',
|
| 76 |
-
'model': 'gemini-2.5-flash-preview-04-17', '
|
| 77 |
-
instruction': "You are a helpful agent who can answer user questions about the time and weather in a city.\nBefore you answer, you should say your name: 'I am weather_time_agent'",
|
| 78 |
-
'tools': [
|
| 79 |
-
'get_weather',
|
| 80 |
-
'get_current_time'
|
| 81 |
-
],
|
| 82 |
-
'sub_agents': [
|
| 83 |
-
'greeting_agent',
|
| 84 |
-
'farewell_agent'
|
| 85 |
-
],
|
| 86 |
-
'description': 'Agent to answer questions about the time and weather in a city.'
|
| 87 |
-
},
|
| 88 |
-
'tools': [
|
| 89 |
-
'get_weather',
|
| 90 |
-
'get_current_time'
|
| 91 |
-
]
|
| 92 |
-
}
|
| 93 |
-
"""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
team_framework/load_tools.py
DELETED
|
@@ -1,30 +0,0 @@
|
|
| 1 |
-
import importlib
|
| 2 |
-
|
| 3 |
-
def load_tools_from_array(arr:list):
|
| 4 |
-
ret = {}
|
| 5 |
-
for item in arr:
|
| 6 |
-
# 构建正确的模块路径,使用 __name__ 动态获取当前模块的父路径(此处正好为团队名称),并加上 .tools 子目录和工具名称
|
| 7 |
-
# parent_module_path = '.'.join(__name__.split('.')[:-1])
|
| 8 |
-
# module_path = f'{parent_module_path}.tools.{item}'
|
| 9 |
-
module_path = f'teams.get_weather.tools.{item}'
|
| 10 |
-
try:
|
| 11 |
-
module = importlib.import_module(module_path)
|
| 12 |
-
# 函数名预期与工具名称相同
|
| 13 |
-
func = getattr(module, item)
|
| 14 |
-
ret[item] = func
|
| 15 |
-
print(f"成功从模块 '{module_path}' 导入函数 '{item}'")
|
| 16 |
-
except ImportError as e:
|
| 17 |
-
print(f"导入模块 {module_path} 时出错: {e}")
|
| 18 |
-
except AttributeError as e:
|
| 19 |
-
print(f"在模块 {module_path} 中找不到函数 '{item}': {e}")
|
| 20 |
-
return ret
|
| 21 |
-
|
| 22 |
-
# def load_tools_from_db():
|
| 23 |
-
# tool_arr = ["get_weather", "get_current_time"]
|
| 24 |
-
# return load_tools_from_array(tool_arr)
|
| 25 |
-
|
| 26 |
-
def load_tools(tools_dict:dict):
|
| 27 |
-
print("\n\n\n######## load_tools\ntools_dict: ", tools_dict)
|
| 28 |
-
# load_tools_from_array(tools_dict)
|
| 29 |
-
return load_tools_from_array(tools_dict)
|
| 30 |
-
return tools_dict
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
team_framework/store.py
ADDED
|
@@ -0,0 +1,8 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
global _store
|
| 2 |
+
_store = {}
|
| 3 |
+
|
| 4 |
+
def get_store(key:str):
|
| 5 |
+
return _store.get(key)
|
| 6 |
+
|
| 7 |
+
def set_store(key:str, value) -> None:
|
| 8 |
+
_store[key] = value
|
teams/ai_quant/agent.py
CHANGED
|
@@ -1,148 +1,111 @@
|
|
| 1 |
-
|
| 2 |
-
|
| 3 |
-
from
|
| 4 |
-
from .tools.
|
| 5 |
-
from .
|
| 6 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 7 |
def my_before_model_callback(callback_context, **kwargs):
|
| 8 |
os.environ["GOOGLE_API_KEY"] = get_api_key() # 直接设置环境变量
|
| 9 |
|
| 10 |
-
|
| 11 |
-
|
| 12 |
-
|
| 13 |
-
|
| 14 |
-
|
| 15 |
-
|
| 16 |
-
|
| 17 |
-
|
| 18 |
-
|
| 19 |
-
|
| 20 |
-
|
| 21 |
-
|
| 22 |
-
|
| 23 |
-
|
| 24 |
-
|
| 25 |
-
|
| 26 |
-
|
| 27 |
-
|
| 28 |
-
|
| 29 |
-
|
| 30 |
-
|
| 31 |
-
|
| 32 |
-
|
| 33 |
-
|
| 34 |
-
|
| 35 |
-
|
| 36 |
-
|
| 37 |
-
|
| 38 |
-
|
| 39 |
-
|
| 40 |
-
|
| 41 |
-
|
| 42 |
-
|
| 43 |
-
|
| 44 |
-
|
| 45 |
-
|
| 46 |
-
|
| 47 |
-
|
| 48 |
-
|
| 49 |
-
|
| 50 |
-
|
| 51 |
-
|
| 52 |
-
|
| 53 |
-
|
| 54 |
-
|
| 55 |
-
|
| 56 |
-
|
| 57 |
-
|
| 58 |
-
|
| 59 |
-
|
| 60 |
-
|
| 61 |
-
|
| 62 |
-
|
| 63 |
-
|
| 64 |
-
|
| 65 |
-
|
| 66 |
-
|
| 67 |
-
|
| 68 |
-
|
| 69 |
-
|
| 70 |
-
|
| 71 |
-
|
| 72 |
-
|
| 73 |
-
|
| 74 |
-
|
| 75 |
-
|
| 76 |
-
|
| 77 |
-
|
| 78 |
-
|
| 79 |
-
|
| 80 |
-
|
| 81 |
-
|
| 82 |
-
|
| 83 |
-
|
| 84 |
-
|
| 85 |
-
|
| 86 |
-
|
| 87 |
-
|
| 88 |
-
|
| 89 |
-
|
| 90 |
-
|
| 91 |
-
|
| 92 |
-
|
| 93 |
-
|
| 94 |
-
|
| 95 |
-
|
| 96 |
-
|
| 97 |
-
|
| 98 |
-
|
| 99 |
-
for agent_data in agent_records:
|
| 100 |
-
agent_name = agent_data.get("name", f"agent_{agent_data.get('id', 'unknown')}")
|
| 101 |
-
current_agent = agents_by_name.get(agent_name)
|
| 102 |
-
if current_agent and "sub_agents" in agent_data and isinstance(agent_data["sub_agents"], list):
|
| 103 |
-
current_agent.sub_agents = []
|
| 104 |
-
for sub_agent_name in agent_data["sub_agents"]:
|
| 105 |
-
sub_agent = agents_by_name.get(sub_agent_name)
|
| 106 |
-
if sub_agent:
|
| 107 |
-
current_agent.sub_agents.append(sub_agent)
|
| 108 |
-
print(f"为 agent '{current_agent.name}' 添加 sub-agent: '{sub_agent.name}'")
|
| 109 |
-
else:
|
| 110 |
-
print(f"警告: 未找到 sub-agent '{sub_agent_name}' (被 agent '{current_agent.name}' 引用)")
|
| 111 |
-
|
| 112 |
-
print(f"总共加载并关联了 {len(agents_by_name)} 个 agents。")
|
| 113 |
-
|
| 114 |
-
# 您现在可以使用 agents_by_name 字典或 loaded_agents_list 列表中的 Agent 对象
|
| 115 |
-
# 例如,如果您需要一个列表:
|
| 116 |
-
loaded_agents = loaded_agents_list
|
| 117 |
-
|
| 118 |
-
# 根据找到的索引设置 root_agent
|
| 119 |
-
root_agent = None
|
| 120 |
-
if 0 <= root_ageint_idx < len(loaded_agents_list):
|
| 121 |
-
root_agent = loaded_agents_list[root_ageint_idx]
|
| 122 |
-
# root_agent.before_model_callback=my_before_model_callback
|
| 123 |
-
# print(f"\n\n\n\n\n已设置 root_agent 为: {root_agent.name}")
|
| 124 |
-
else:
|
| 125 |
-
print("警告: 未找到 root agent 或索引无效,使用默认 root_agent。")
|
| 126 |
-
# 如果没有找到 root agent,可以考虑使用一个默认的 root_agent 或者抛出错误
|
| 127 |
-
root_agent = Agent(
|
| 128 |
-
name="default_root_agent",
|
| 129 |
-
model="gemini-2.0-flash-exp",
|
| 130 |
-
instruction="You are a helpful assistant.",
|
| 131 |
-
description="You are a helpful assistant.",
|
| 132 |
-
# before_model_callback=my_before_model_callback,
|
| 133 |
-
tools=[]
|
| 134 |
-
)
|
| 135 |
-
|
| 136 |
-
# 轮询 loaded_agents_list
|
| 137 |
-
for agent in loaded_agents_list:
|
| 138 |
-
agent.before_model_callback=my_before_model_callback
|
| 139 |
-
if agent.sub_agents:
|
| 140 |
-
for sub_agent in agent.sub_agents:
|
| 141 |
-
sub_agent.parent_agent = agent
|
| 142 |
-
|
| 143 |
-
# import pprint
|
| 144 |
-
# print('\n\n\n\n*************************************\n\nroot_agent dict: \n')
|
| 145 |
-
# pprint.pprint(root_agent.__dict__) # 尝试打印对象的字典表示
|
| 146 |
-
|
| 147 |
-
|
| 148 |
-
|
|
|
|
| 1 |
+
# 多MCP示例,参考:https://google.github.io/adk-docs/tools/mcp-tools/#step-1-attach-the-mcp-server-to-your-adk-agent-via-mcptoolset
|
| 2 |
+
# # ./adk_agent_samples/mcp_agent/agent.py
|
| 3 |
+
from google.adk.agents.llm_agent import LlmAgent
|
| 4 |
+
from google.adk.tools.mcp_tool.mcp_toolset import MCPToolset, StdioServerParameters
|
| 5 |
+
from google.adk.tools import google_search
|
| 6 |
+
import importlib,pprint
|
| 7 |
+
import os, sys
|
| 8 |
+
from contextlib import ExitStack, AsyncExitStack
|
| 9 |
+
PROJECT_ROOT = os.path.abspath(os.path.join(os.path.dirname(os.path.abspath(__file__)), '..', '..'))
|
| 10 |
+
if not PROJECT_ROOT in sys.path:
|
| 11 |
+
sys.path.append(PROJECT_ROOT)
|
| 12 |
+
from team_framework.init import init
|
| 13 |
+
init(PROJECT_ROOT)
|
| 14 |
+
from dotenv import load_dotenv
|
| 15 |
+
load_dotenv()
|
| 16 |
+
from google.adk.tools.agent_tool import AgentTool
|
| 17 |
+
from team_framework.api_key_manager import get_api_key
|
| 18 |
+
|
| 19 |
+
# 定义 before_model_callback 函数
|
| 20 |
def my_before_model_callback(callback_context, **kwargs):
|
| 21 |
os.environ["GOOGLE_API_KEY"] = get_api_key() # 直接设置环境变量
|
| 22 |
|
| 23 |
+
agents_config={}
|
| 24 |
+
|
| 25 |
+
ai_quant_researcher = LlmAgent(
|
| 26 |
+
name = "ai_quant_researcher",
|
| 27 |
+
description = "AI金融量化研究员/分析师 (AI Quantitative Researcher/Analyst)",
|
| 28 |
+
model = "gemini-2.5-flash-preview-04-17",
|
| 29 |
+
instruction = """你是AI金融量化研究员/分析师 (AI Quantitative Researcher/Analyst): 这是核心角色。
|
| 30 |
+
负责:
|
| 31 |
+
- 开发和测试股票分析模型,例如价值投资模型、动量模型、技术分析模型等。
|
| 32 |
+
- 利用统计学、计量经济学等方法分析股票数据,发现投资机会。
|
| 33 |
+
- 对股票进行估值分析,评估其投资价值。
|
| 34 |
+
- 监控市场风险,提出风险控制建议。""",
|
| 35 |
+
before_model_callback=my_before_model_callback
|
| 36 |
+
)
|
| 37 |
+
|
| 38 |
+
ai_quant_developer = LlmAgent(
|
| 39 |
+
name = "ai_quant_developer",
|
| 40 |
+
description = "AI金融量化开发工程师(AI Quantitative Developer/Engineer)",
|
| 41 |
+
model = "gemini-2.5-flash-preview-04-17",
|
| 42 |
+
instruction = """你是AI金融量化开发工程师 (AI Quantitative Developer/Engineer):负责将研究成果转化为可执行的代码和系统。
|
| 43 |
+
职责:
|
| 44 |
+
- 将量化研究员开发的策略模型转化为程序代码实现。
|
| 45 |
+
- 构建和维护策略回测平台。
|
| 46 |
+
- 开发和维护自动化交易执行系统。
|
| 47 |
+
- 处理和管理交易所需的数据(数据清洗、存储、获取)。
|
| 48 |
+
- 负责交易系统的日常运行和维护。
|
| 49 |
+
- 协助实现风险控制的技术逻辑。""",
|
| 50 |
+
before_model_callback=my_before_model_callback
|
| 51 |
+
)
|
| 52 |
+
|
| 53 |
+
ai_quant_trader = LlmAgent(
|
| 54 |
+
name = "ai_quant_trader",
|
| 55 |
+
description = "AI金融量化交易员(AI Quantitative Trader)",
|
| 56 |
+
model = "gemini-2.5-flash-preview-04-17",
|
| 57 |
+
instruction = """你是AI金融量化交易员 (AI Quantitative Trader) 或 交易执行/监控专员: 负责交易策略的实际执行、监控和管理。
|
| 58 |
+
在自动化量化交易中,这个角色的职责通常包括:
|
| 59 |
+
- 启动和监控自动化交易系统。
|
| 60 |
+
- 管理交易头寸和资金分配。
|
| 61 |
+
- 实时监控市场和系统运行状态。
|
| 62 |
+
- 处理交易中的异常情况和错误。
|
| 63 |
+
- 执行实时的风险控制措施。
|
| 64 |
+
- 与研究员和开发工程师沟通系统表现和市场反馈。""",
|
| 65 |
+
before_model_callback=my_before_model_callback
|
| 66 |
+
)
|
| 67 |
+
|
| 68 |
+
ai_data_scientist = LlmAgent(
|
| 69 |
+
name = "ai_data_scientist",
|
| 70 |
+
description = "AI金融量化数据科学家(AI Data Scientist)",
|
| 71 |
+
model = "gemini-2.5-flash-preview-04-17",
|
| 72 |
+
instruction = """你是AI金融量化数据科学家 (AI Data Scientist): 专注于数据基础设施、数据处理和高级数据分析。
|
| 73 |
+
职责:
|
| 74 |
+
- 负责更复杂、更多样化数据源的收集、清洗、转换和管理(包括非结构化数据、另类数据等)。
|
| 75 |
+
- 构建高效的数据管道和数据湖/仓库。
|
| 76 |
+
- 应用机器学习、深度学习等高级统计和建模技术来发现数据中的模式和信号。
|
| 77 |
+
- 支持量化研究员进行更深入的数据探索和特征工程。
|
| 78 |
+
- 可能负责数据质量监控和数据治理。""",
|
| 79 |
+
before_model_callback=my_before_model_callback
|
| 80 |
+
)
|
| 81 |
+
|
| 82 |
+
agent_tool_google_search = LlmAgent(
|
| 83 |
+
name = "agent_tool_google_search",
|
| 84 |
+
description = "Google搜索代理工具",
|
| 85 |
+
model = "gemini-2.5-flash-preview-04-17",
|
| 86 |
+
instruction = """你是一个Google搜索代理工具,你的主要工作是搜索互联网上的信息,并返回搜索结果。""",
|
| 87 |
+
tools = [google_search],
|
| 88 |
+
before_model_callback=my_before_model_callback
|
| 89 |
+
)
|
| 90 |
+
|
| 91 |
+
google_search_agent = LlmAgent(
|
| 92 |
+
name = "google_search_agent",
|
| 93 |
+
description = "具有 Google 搜索能力的代理",
|
| 94 |
+
model = "gemini-2.5-flash-preview-04-17",
|
| 95 |
+
instruction = """你是一个Google搜索代理,专门负责处理其他代理发来的搜索请求。当你收到一个搜索请求时,你将使用你的内置工具 `agent_tool_google_search` 来执行网络搜索。完成搜索后,你必须将获取到的搜索结果准确地传递回发起请求的代理。""",
|
| 96 |
+
tools = [AgentTool(agent_tool_google_search)],
|
| 97 |
+
before_model_callback=my_before_model_callback
|
| 98 |
+
)
|
| 99 |
+
|
| 100 |
+
root_agent = LlmAgent(
|
| 101 |
+
name = "ai_dispatcher",
|
| 102 |
+
description = "AI金融量化交易团队的调度员(AI Dispatcher)",
|
| 103 |
+
model = "gemini-2.5-flash-preview-04-17",
|
| 104 |
+
instruction="""你是AI金融量化交易团队的调度员(AI Dispatcher)
|
| 105 |
+
- 你的主要工作是调配好整个金融量化交易团队的分工协作
|
| 106 |
+
- 除了分配调度不要做其他具体工作
|
| 107 |
+
- 如果你的团队成员都无法进行的工作,你就委婉告诉用户说你无法解答""",
|
| 108 |
+
global_instruction = """AI金融量化交易团队有个响亮的名字:“AI金融量化梦之队”,你是该团队的成员,当agent回答时,请带上你的角色名,比如:我是xxx(角色名),当用户问起你是谁,你就说出你的角色名称,比如我是:量化研究员""",
|
| 109 |
+
sub_agents = [ai_quant_researcher, ai_quant_developer, ai_quant_trader, ai_data_scientist, google_search_agent],
|
| 110 |
+
before_model_callback=my_before_model_callback
|
| 111 |
+
)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
teams/ai_quant/tools/__init__.py
DELETED
|
File without changes
|
teams/ai_quant/tools/get_current_time.py
DELETED
|
@@ -1,28 +0,0 @@
|
|
| 1 |
-
import datetime
|
| 2 |
-
from zoneinfo import ZoneInfo
|
| 3 |
-
def get_current_time(city: str) -> dict:
|
| 4 |
-
"""Returns the current time in a specified city.
|
| 5 |
-
|
| 6 |
-
Args:
|
| 7 |
-
city (str): The name of the city for which to retrieve the current time.
|
| 8 |
-
|
| 9 |
-
Returns:
|
| 10 |
-
dict: status and result or error msg.
|
| 11 |
-
"""
|
| 12 |
-
|
| 13 |
-
if city.lower() == "new york":
|
| 14 |
-
tz_identifier = "America/New_York"
|
| 15 |
-
else:
|
| 16 |
-
return {
|
| 17 |
-
"status": "error",
|
| 18 |
-
"error_message": (
|
| 19 |
-
f"Sorry, I don't have timezone information for {city}."
|
| 20 |
-
),
|
| 21 |
-
}
|
| 22 |
-
|
| 23 |
-
tz = ZoneInfo(tz_identifier)
|
| 24 |
-
now = datetime.datetime.now(tz)
|
| 25 |
-
report = (
|
| 26 |
-
f'The current time in {city} is {now.strftime("%Y-%m-%d %H:%M:%S %Z%z")}'
|
| 27 |
-
)
|
| 28 |
-
return {"status": "success", "report": report}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
teams/ai_quant/tools/get_weather.py
DELETED
|
@@ -1,22 +0,0 @@
|
|
| 1 |
-
def get_weather(city: str) -> dict:
|
| 2 |
-
"""Retrieves the current weather report for a specified city.
|
| 3 |
-
|
| 4 |
-
Args:
|
| 5 |
-
city (str): The name of the city for which to retrieve the weather report.
|
| 6 |
-
|
| 7 |
-
Returns:
|
| 8 |
-
dict: status and result or error msg.
|
| 9 |
-
"""
|
| 10 |
-
if city.lower() == "new york":
|
| 11 |
-
return {
|
| 12 |
-
"status": "success",
|
| 13 |
-
"report": (
|
| 14 |
-
"The weather in New York is sunny with a temperature of 25 degrees"
|
| 15 |
-
" Celsius (77 degrees Fahrenheit)."
|
| 16 |
-
),
|
| 17 |
-
}
|
| 18 |
-
else:
|
| 19 |
-
return {
|
| 20 |
-
"status": "error",
|
| 21 |
-
"error_message": f"Weather information for '{city}' is not available.",
|
| 22 |
-
}
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
test.py
DELETED
|
@@ -1,5 +0,0 @@
|
|
| 1 |
-
d=1
|
| 2 |
-
a={"b":{"c":d}}
|
| 3 |
-
print(a["b"]["c"])
|
| 4 |
-
d=2
|
| 5 |
-
print(a["b"]["c"])
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
utils.py.willdel
DELETED
|
@@ -1,122 +0,0 @@
|
|
| 1 |
-
from google.adk.agents import Agent
|
| 2 |
-
from google.adk.agents.invocation_context import InvocationContext
|
| 3 |
-
from google.adk.tools import google_search
|
| 4 |
-
from supabase import create_client, Client
|
| 5 |
-
|
| 6 |
-
import logging # 导入 logging 模块
|
| 7 |
-
import os,json
|
| 8 |
-
|
| 9 |
-
# 配置日志
|
| 10 |
-
logging.basicConfig(level=logging.INFO, format='%(asctime)s - %(levelname)s - %(name)s - %(message)s')
|
| 11 |
-
logger = logging.getLogger(__name__)
|
| 12 |
-
|
| 13 |
-
class Base_Agent(Agent):
|
| 14 |
-
def __init__(self, agent_id: str):
|
| 15 |
-
logger.info("Base_Agent __init__ started.")
|
| 16 |
-
|
| 17 |
-
# 从环境变量加载 Supabase URL 和 Key
|
| 18 |
-
url: str = os.environ.get("SUPABASE_URL")
|
| 19 |
-
key: str = os.environ.get("SUPABASE_KEY") # 从环境变量获取 Supabase Key
|
| 20 |
-
|
| 21 |
-
if not url or not key:
|
| 22 |
-
logger.error("Supabase URL or Key not set in environment variables.")
|
| 23 |
-
# 如果环境变量未设置,可以使用默认配置
|
| 24 |
-
logger.warning("Supabase URL and Key not set. Using default agent configuration.")
|
| 25 |
-
super().__init__(
|
| 26 |
-
name="基础助手",
|
| 27 |
-
model="gemini-2.0-flash-exp",
|
| 28 |
-
instruction="执行基本指令",
|
| 29 |
-
tools=[google_search],
|
| 30 |
-
description="一个执行基本通用命令的基础助手"
|
| 31 |
-
)
|
| 32 |
-
logger.info("Base_Agent initialized with default configuration.")
|
| 33 |
-
return # Exit __init__ if using default config
|
| 34 |
-
|
| 35 |
-
logger.info("Supabase URL and Key loaded from environment variables.")
|
| 36 |
-
|
| 37 |
-
# 创建 Supabase 客户端
|
| 38 |
-
try:
|
| 39 |
-
supabase: Client = create_client(url, key)
|
| 40 |
-
logger.info("Supabase client created successfully.")
|
| 41 |
-
except Exception as e:
|
| 42 |
-
logger.error(f"Error creating Supabase client: {e}")
|
| 43 |
-
# 如果创建客户端失败,使用默认配置
|
| 44 |
-
logger.warning("Error creating Supabase client. Using default agent configuration.")
|
| 45 |
-
super().__init__(
|
| 46 |
-
name="基础助手",
|
| 47 |
-
model="gemini-2.0-flash-exp",
|
| 48 |
-
instruction="执行基本指令",
|
| 49 |
-
tools=[google_search],
|
| 50 |
-
description="一个执行基本通用命令的基础助手"
|
| 51 |
-
)
|
| 52 |
-
return # Exit __init__ if using default config
|
| 53 |
-
|
| 54 |
-
# 从数据库加载 agent 配置信息
|
| 55 |
-
try:
|
| 56 |
-
logger.info(f"Attempting to load agent configuration from Supabase for id: {agent_id}")
|
| 57 |
-
# 查询 airs_agents 表,获取对应的 agent 配置
|
| 58 |
-
data, count = supabase.table('airs_agents').select('*').eq('id', agent_id).execute()
|
| 59 |
-
|
| 60 |
-
if not data or not data[0]:
|
| 61 |
-
logger.error(f"Agent configuration for id '{self.agent_id}' not found in Supabase table 'airs_agents'.")
|
| 62 |
-
# 如果配置未找到,使用默认配置
|
| 63 |
-
logger.warning("Agent configuration not found. Using default agent configuration.")
|
| 64 |
-
super().__init__(
|
| 65 |
-
name="基础助手",
|
| 66 |
-
model="gemini-2.0-flash-exp",
|
| 67 |
-
instruction="执行基本指令",
|
| 68 |
-
tools=[google_search],
|
| 69 |
-
description="一个执行基本通用命令的基础助手"
|
| 70 |
-
)
|
| 71 |
-
return # Exit __init__ if using default config
|
| 72 |
-
print('\n\n\n\ndata',data)
|
| 73 |
-
print('**************************')
|
| 74 |
-
print('data[0]',data[0])
|
| 75 |
-
print('data[1]',data[1])
|
| 76 |
-
print('data[1][0]',data[1][0])
|
| 77 |
-
|
| 78 |
-
config = data[1][0] # 假设查询结果是列表中的第一个字典
|
| 79 |
-
logger.info("Agent configuration data fetched from Supabase. config: ",)
|
| 80 |
-
|
| 81 |
-
# 解析 tools 字段(假设存储为 JSONB)
|
| 82 |
-
tools_list = []
|
| 83 |
-
if config.get("tools"):
|
| 84 |
-
logger.info("Processing tools field.")
|
| 85 |
-
try:
|
| 86 |
-
stored_tools = json.loads(config["tools"]) if isinstance(config["tools"], str) else config["tools"]
|
| 87 |
-
# 示例:如果存储的是工具名称列表,查找对应的工具对象
|
| 88 |
-
available_tools = {"google_search": google_search} # 假设可用的工具映射
|
| 89 |
-
tools_list = [available_tools.get(tool_name) for tool_name in stored_tools if available_tools.get(tool_name)]
|
| 90 |
-
print('\n\n\n\ntools_list',tools_list)
|
| 91 |
-
# logger.info(f"Tools processed: {[tool.__name__ for tool in tools_list if tool]}")
|
| 92 |
-
except Exception as tool_e:
|
| 93 |
-
logger.error(f"Error parsing or mapping tools: {tool_e}")
|
| 94 |
-
# 如果解析或映射工具失败,可以使用默认工具或空列表
|
| 95 |
-
tools_list = [google_search] # 默认使用 google_search
|
| 96 |
-
logger.warning("Using default tool: google_search")
|
| 97 |
-
|
| 98 |
-
# 使用从数据库获取的配置初始化 Base_Agent 实例自身
|
| 99 |
-
print('\n\n\n\nconfig: ',config)
|
| 100 |
-
super().__init__(
|
| 101 |
-
name=config.get("name", "基础助手"),
|
| 102 |
-
model=config.get("model", "gemini-2.0-flash-exp"),
|
| 103 |
-
instruction=config.get("instruction", "执行基本指令"),
|
| 104 |
-
tools=tools_list, # 使用从数据库加载并解析的工具列表
|
| 105 |
-
description=config.get("description", "一个执行基本通用命令的基础助手")
|
| 106 |
-
)
|
| 107 |
-
logger.info("Base_Agent initialized successfully with Supabase configuration.")
|
| 108 |
-
|
| 109 |
-
except Exception as e:
|
| 110 |
-
logger.error(f"Error loading agent configuration from Supabase: {e}")
|
| 111 |
-
# 如果从数据库加载失败,使用默认配置
|
| 112 |
-
logger.warning("Error loading agent configuration from Supabase. Using default agent configuration.")
|
| 113 |
-
super().__init__(
|
| 114 |
-
name="基础助手",
|
| 115 |
-
model="gemini-2.0-flash-exp",
|
| 116 |
-
instruction="执行基本指令",
|
| 117 |
-
tools=[google_search],
|
| 118 |
-
description="一个执行基本通用命令的基础助手"
|
| 119 |
-
)
|
| 120 |
-
|
| 121 |
-
logger.info("Base_Agent __init__ finished.")
|
| 122 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|