geqintan commited on
Commit
44fb377
·
1 Parent(s): 772a17e
__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
- conda - google-adk
2
- supabase
3
- site - http://supabase.com
4
- username - tanbushi@qq.com
5
- project - rzwl2024
 
 
 
 
 
 
 
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: Client = get_supabase_client()
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
- import os
2
- from google.adk.agents import Agent
3
- from supabase import create_client, Client
4
- from .tools.get_current_time import get_current_time
5
- from .tools.get_weather import get_weather
6
- from .cache import get_api_key
 
 
 
 
 
 
 
 
 
 
 
 
 
7
  def my_before_model_callback(callback_context, **kwargs):
8
  os.environ["GOOGLE_API_KEY"] = get_api_key() # 直接设置环境变量
9
 
10
- # 从环境变量获取 Supabase 配置
11
- # 建议将敏感信息通过环境变量传递,而不是直接硬编码或从文件中读取
12
- # 这里为了演示,直接使用了从 .env 文件读取到的值
13
- # 在实际生产环境中,请确保通过安全的方式加载配置
14
- SUPABASE_URL = os.environ.get("SUPABASE_URL", "https://bbvyxjvleoizsipxydsm.supabase.co")
15
- SUPABASE_KEY = os.environ.get("SUPABASE_KEY", "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJpc3MiOiJzdXBhYmFzZSIsInJlZiI6ImJidnl4anZsZW9изsipxydsmIiwicm9sZSI6ImFub24iLCJpYXQiOjE3NDQ1MzkwNjIsImV4cCI6MjA2MDExNTA2Mn0.cbUNhiCHXqIaW4leU_vGTKVI51gLVvsFOVWYS_vJrA4")
16
- DB_TABLE_NAME = os.environ.get("DB_TABLE_NAME", "team_quant")
17
-
18
- # 初始化 Supabase 客户端
19
- supabase: Client = create_client(SUPABASE_URL, SUPABASE_KEY)
20
-
21
- def get_all_agents_from_db() -> dict:
22
- """
23
- 从 Supabase 数据库中提取所有 agent 记录,并形成字典。
24
- """
25
- try:
26
- # 从指定的表中查询所有数据
27
- response = supabase.table(DB_TABLE_NAME).select("*").order('sort_id', desc=False).execute()
28
-
29
- # 检查响应
30
- if response.data:
31
- #查询结果字典,这里假设每条记录都有一个唯一的 'id' 或其他键
32
- # 如果没有合适的唯一键,可能需要调整字典的构建方式
33
- agents_dict = {record.get("id"): record for record in response.data}
34
- return agents_dict
35
- else:
36
- print("从数据库提取 agent 记录失败或没有记录。")
37
- return {}
38
- except Exception as e:
39
- print(f"提取 agent 记录时发生错误: {e}")
40
- return {}
41
-
42
- # 示例用法 (可选,根据需要决定是否保留)
43
- # if __name__ == "__main__":
44
- # all_agents = get_all_agents_from_db()
45
- # print("提取到 agent 字典:")
46
- # print(all_agents)
47
-
48
- # 从数据库加载所有 agents 数据 (字典形式)
49
- all_agents_data_dict = get_all_agents_from_db()
50
-
51
- # 将字典值转换为列并按 sort_id 排序
52
- agent_records = sorted(all_agents_data_dict.values(), key=lambda x: x.get("sort_id", float('inf')))
53
-
54
- # 初始化 root_ageint_idx 变量
55
- root_ageint_idx = -1
56
-
57
- # 查找 root agent 的索引
58
- if agent_records:
59
- for index, agent_data in enumerate(agent_records):
60
- if agent_data.get("is_root", False): # 假设数据库记录包含 is_root 字段
61
- root_ageint_idx = index
62
- print(f"找到 root agent 索引: {root_ageint_idx}")
63
- break # 假设只有一个 root agent
64
-
65
- # 创建 Agent 对象并存储到按名称索引的字典中
66
- agents_by_name = {}
67
- loaded_agents_list = [] # Keep a list for the final output if needed
68
- if agent_records:
69
- for agent_data in agent_records:
70
- try:
71
- # 假设数据库记录包含 name, model, instruction, description, sub_agents, sort_id, is_root 字段
72
- agent_name = agent_data.get("name", f"agent_{agent_data.get('id', 'unknown')}")
73
- global_instruction=agent_data.get("global_instruction", "")
74
- if (global_instruction == None):
75
- global_instruction = ""
76
- agent = Agent(
77
- name=agent_name,
78
- model=agent_data.get("model", "gemini-2.0-flash-exp"),
79
- instruction=agent_data.get("instruction", ""),
80
- description=agent_data.get("description", ""),
81
- global_instruction=global_instruction,
82
- # global_instruction=agent_data.get("global_instruction", ""),
83
- # sub_agents will be added in the next step
84
- # callbacks etc. can be added here if present in data
85
- )
86
- # Map tool names from database to actual tool functions
87
- tool_map = {"get_weather": get_weather, "get_current_time": get_current_time}
88
- tools_list = [tool_map.get(tool_name) for tool_name in agent_data.get("tools") or [] if tool_name in tool_map]
89
- agent.tools = tools_list # Use the mapped tool functions
90
-
91
- agents_by_name[agent_name] = agent
92
- loaded_agents_list.append(agent) # Add to list if needed later
93
- print(f"成功创建 agent 对象: {agent.name}")
94
- except Exception as e:
95
- print(f"创建 agent 对象发生错误 (数据: {agent_data}): {e}")
96
-
97
- # 处理 sub_agents 引用
98
- if agent_records:
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
-