This commit is contained in:
parent
357aa45390
commit
1d13040071
54
cli/main.py
54
cli/main.py
|
|
@ -502,6 +502,43 @@ def get_user_selections():
|
||||||
selected_shallow_thinker = select_shallow_thinking_agent(selected_llm_provider)
|
selected_shallow_thinker = select_shallow_thinking_agent(selected_llm_provider)
|
||||||
selected_deep_thinker = select_deep_thinking_agent(selected_llm_provider)
|
selected_deep_thinker = select_deep_thinking_agent(selected_llm_provider)
|
||||||
|
|
||||||
|
# 步驟 7:嵌入模型供應商
|
||||||
|
console.print(
|
||||||
|
create_question_box(
|
||||||
|
"步驟 7:嵌入模型供應商", "選擇嵌入模型服務(用於記憶體系統)"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
embedding_provider, embedding_url = select_embedding_provider()
|
||||||
|
|
||||||
|
# 步驟 8:API Keys
|
||||||
|
console.print(
|
||||||
|
create_question_box(
|
||||||
|
"步驟 8:API Keys", "輸入 API Keys(可留空使用 .env 中的設定)"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
import os
|
||||||
|
|
||||||
|
# 從 .env 讀取 API Key
|
||||||
|
default_openai_key = os.getenv("OPENAI_API_KEY")
|
||||||
|
|
||||||
|
# 快速思維模型 API Key
|
||||||
|
quick_think_api_key = get_api_key("快速思維模型", default_openai_key)
|
||||||
|
|
||||||
|
# 深度思維模型 API Key
|
||||||
|
deep_think_api_key = get_api_key("深度思維模型", default_openai_key)
|
||||||
|
|
||||||
|
# 嵌入模型 API Key
|
||||||
|
embedding_api_key = get_api_key("嵌入模型", default_openai_key)
|
||||||
|
|
||||||
|
# Alpha Vantage API Key(必填)
|
||||||
|
alpha_vantage_key = os.getenv("ALPHA_VANTAGE_API_KEY")
|
||||||
|
if not alpha_vantage_key:
|
||||||
|
console.print("\n[yellow]未在 .env 中找到 ALPHA_VANTAGE_API_KEY[/yellow]")
|
||||||
|
alpha_vantage_key = get_api_key("Alpha Vantage", None)
|
||||||
|
else:
|
||||||
|
console.print(f"\n[green]✓ 使用 .env 中的 ALPHA_VANTAGE_API_KEY[/green]")
|
||||||
|
|
||||||
return {
|
return {
|
||||||
"ticker": selected_ticker,
|
"ticker": selected_ticker,
|
||||||
"analysis_date": analysis_date,
|
"analysis_date": analysis_date,
|
||||||
|
|
@ -511,6 +548,12 @@ def get_user_selections():
|
||||||
"backend_url": backend_url,
|
"backend_url": backend_url,
|
||||||
"shallow_thinker": selected_shallow_thinker,
|
"shallow_thinker": selected_shallow_thinker,
|
||||||
"deep_thinker": selected_deep_thinker,
|
"deep_thinker": selected_deep_thinker,
|
||||||
|
"embedding_provider": embedding_provider,
|
||||||
|
"embedding_url": embedding_url,
|
||||||
|
"quick_think_api_key": quick_think_api_key,
|
||||||
|
"deep_think_api_key": deep_think_api_key,
|
||||||
|
"embedding_api_key": embedding_api_key,
|
||||||
|
"alpha_vantage_api_key": alpha_vantage_key,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
@ -767,6 +810,17 @@ def run_analysis():
|
||||||
config["backend_url"] = selections["backend_url"]
|
config["backend_url"] = selections["backend_url"]
|
||||||
config["llm_provider"] = selections["llm_provider"].lower()
|
config["llm_provider"] = selections["llm_provider"].lower()
|
||||||
|
|
||||||
|
# 添加 API Keys 到配置
|
||||||
|
config["quick_think_api_key"] = selections["quick_think_api_key"]
|
||||||
|
config["deep_think_api_key"] = selections["deep_think_api_key"]
|
||||||
|
config["embedding_api_key"] = selections["embedding_api_key"]
|
||||||
|
config["embedding_base_url"] = selections["embedding_url"]
|
||||||
|
|
||||||
|
# 設置環境變數(某些工具可能需要)
|
||||||
|
import os
|
||||||
|
os.environ["OPENAI_API_KEY"] = selections["quick_think_api_key"]
|
||||||
|
os.environ["ALPHA_VANTAGE_API_KEY"] = selections["alpha_vantage_api_key"]
|
||||||
|
|
||||||
# 初始化圖
|
# 初始化圖
|
||||||
graph = TradingAgentsGraph(
|
graph = TradingAgentsGraph(
|
||||||
[analyst.value for analyst in selections["analysts"]], config=config, debug=True
|
[analyst.value for analyst in selections["analysts"]], config=config, debug=True
|
||||||
|
|
|
||||||
115
cli/utils.py
115
cli/utils.py
|
|
@ -487,3 +487,118 @@ def select_llm_provider() -> tuple[str, str]:
|
||||||
|
|
||||||
# 返回供應商名稱和 URL
|
# 返回供應商名稱和 URL
|
||||||
return display_name, url
|
return display_name, url
|
||||||
|
|
||||||
|
|
||||||
|
def select_embedding_provider() -> tuple[str, str]:
|
||||||
|
"""
|
||||||
|
使用互動式選單選擇嵌入模型供應商。
|
||||||
|
|
||||||
|
返回:
|
||||||
|
tuple[str, str]: 包含供應商名稱和 API 基礎 URL 的元組。
|
||||||
|
"""
|
||||||
|
# 定義嵌入模型供應商(只有 OpenAI 和自訂)
|
||||||
|
EMBEDDING_PROVIDERS = [
|
||||||
|
("OpenAI", "https://api.openai.com/v1"),
|
||||||
|
("自訂 URL", "custom")
|
||||||
|
]
|
||||||
|
|
||||||
|
choice = questionary.select(
|
||||||
|
"選擇您的嵌入模型供應商:",
|
||||||
|
# 設定可選項
|
||||||
|
choices=[
|
||||||
|
questionary.Choice(display, value=(display, value))
|
||||||
|
for display, value in EMBEDDING_PROVIDERS
|
||||||
|
],
|
||||||
|
# 提供操作說明
|
||||||
|
instruction="\n- 使用方向鍵導覽\n- 按下 Enter 鍵選擇",
|
||||||
|
# 設定提示的樣式
|
||||||
|
style=questionary.Style(
|
||||||
|
[
|
||||||
|
("selected", "fg:cyan noinherit"),
|
||||||
|
("highlighted", "fg:cyan noinherit"),
|
||||||
|
("pointer", "fg:cyan noinherit"),
|
||||||
|
]
|
||||||
|
),
|
||||||
|
).ask()
|
||||||
|
|
||||||
|
# 如果使用者沒有選擇,則退出程式
|
||||||
|
if choice is None:
|
||||||
|
console.print("\n[red]未選擇嵌入模型供應商。正在結束程式...[/red]")
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
# 解構選擇的元組
|
||||||
|
display_name, url = choice
|
||||||
|
|
||||||
|
# 如果選擇自訂 URL,提示使用者輸入
|
||||||
|
if url == "custom":
|
||||||
|
custom_url = questionary.text(
|
||||||
|
"請輸入自訂的 Base URL:",
|
||||||
|
validate=lambda x: (x.startswith("http://") or x.startswith("https://")) or "URL 必須以 http:// 或 https:// 開頭",
|
||||||
|
style=questionary.Style(
|
||||||
|
[
|
||||||
|
("text", "fg:green"),
|
||||||
|
("highlighted", "noinherit"),
|
||||||
|
]
|
||||||
|
),
|
||||||
|
).ask()
|
||||||
|
|
||||||
|
# 如果使用者沒有輸入,則退出程式
|
||||||
|
if not custom_url:
|
||||||
|
console.print("\n[red]未提供 Base URL。正在結束程式...[/red]")
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
url = custom_url.strip()
|
||||||
|
display_name = "自訂供應商"
|
||||||
|
|
||||||
|
# 印出使用者的選擇
|
||||||
|
print(f"您選擇了嵌入模型:{display_name}\tURL: {url}")
|
||||||
|
|
||||||
|
# 返回供應商名稱和 URL
|
||||||
|
return display_name, url
|
||||||
|
|
||||||
|
|
||||||
|
def get_api_key(model_type: str, default_key: Optional[str] = None) -> str:
|
||||||
|
"""
|
||||||
|
提示使用者輸入 API Key,如果留空則使用預設值。
|
||||||
|
|
||||||
|
參數:
|
||||||
|
model_type (str): 模型類型(例如:「快速思維」、「深度思維」、「嵌入模型」)
|
||||||
|
default_key (Optional[str]): 從 .env 文件讀取的預設 API Key
|
||||||
|
|
||||||
|
返回:
|
||||||
|
str: 使用者輸入的 API Key 或預設值
|
||||||
|
"""
|
||||||
|
import os
|
||||||
|
from rich.console import Console
|
||||||
|
|
||||||
|
console = Console()
|
||||||
|
|
||||||
|
# 顯示提示訊息
|
||||||
|
if default_key:
|
||||||
|
hint = f"[dim](留空使用 .env 中的 API Key: {default_key[:10]}...{default_key[-4:]})[/dim]"
|
||||||
|
else:
|
||||||
|
hint = "[dim](必填)[/dim]"
|
||||||
|
|
||||||
|
console.print(f"\n[cyan]{model_type} API Key {hint}[/cyan]")
|
||||||
|
|
||||||
|
api_key = questionary.password(
|
||||||
|
f"請輸入 {model_type} 的 API Key:",
|
||||||
|
style=questionary.Style(
|
||||||
|
[
|
||||||
|
("text", "fg:green"),
|
||||||
|
("highlighted", "noinherit"),
|
||||||
|
]
|
||||||
|
),
|
||||||
|
).ask()
|
||||||
|
|
||||||
|
# 如果使用者沒有輸入,使用預設值
|
||||||
|
if not api_key or api_key.strip() == "":
|
||||||
|
if default_key:
|
||||||
|
console.print(f"[green]✓ 使用 .env 中的 API Key[/green]")
|
||||||
|
return default_key
|
||||||
|
else:
|
||||||
|
console.print(f"\n[red]未提供 {model_type} API Key。正在結束程式...[/red]")
|
||||||
|
exit(1)
|
||||||
|
|
||||||
|
console.print(f"[green]✓ API Key 已設定[/green]")
|
||||||
|
return api_key.strip()
|
||||||
Loading…
Reference in New Issue