This commit is contained in:
parent
1a409796d1
commit
5724cb612c
|
|
@ -1 +1 @@
|
|||
Subproject commit 26f91ef0e47bc70526accb11dc43d2c20ea07a55
|
||||
Subproject commit 4f219bd74ef1d1c40f309bc5a2ec8c395111fd48
|
||||
|
|
@ -52,6 +52,7 @@ const formSchema = z.object({
|
|||
.regex(/^\d{4}-\d{2}-\d{2}$/, "日期格式必須為 YYYY-MM-DD"),
|
||||
analysts: z.array(z.string()).min(1, "請至少選擇一位分析師"),
|
||||
research_depth: z.number().int().min(1).max(5),
|
||||
analysis_mode: z.enum(["fast", "deep"]).optional().default("deep"),
|
||||
quick_think_llm: z.string().min(1, "請選擇快速思維模型"),
|
||||
deep_think_llm: z.string().min(1, "請選擇深層思維模型"),
|
||||
embedding_model: z.string().min(1, "請選擇嵌入式模型"),
|
||||
|
|
@ -111,6 +112,7 @@ export function AnalysisForm({ onSubmit, loading = false }: AnalysisFormProps) {
|
|||
analysis_date: format(new Date(), "yyyy-MM-dd"),
|
||||
analysts: ["market", "social", "news", "fundamentals"], // 預設全選
|
||||
research_depth: 3, // 預設中等層級
|
||||
analysis_mode: "deep", // 預設深層分析
|
||||
market_type: "us", // 預設美股
|
||||
quick_think_llm: "gpt-5-mini",
|
||||
deep_think_llm: "gpt-5-mini",
|
||||
|
|
@ -473,6 +475,35 @@ export function AnalysisForm({ onSubmit, loading = false }: AnalysisFormProps) {
|
|||
/>
|
||||
</div>
|
||||
|
||||
{/* 分析模式行 */}
|
||||
<div className="md:col-span-2 grid grid-cols-1 md:grid-cols-2 gap-6">
|
||||
<FormField
|
||||
control={form.control}
|
||||
name="analysis_mode"
|
||||
render={({ field }) => (
|
||||
<FormItem>
|
||||
<FormLabel>分析模式</FormLabel>
|
||||
<Select
|
||||
onValueChange={field.onChange}
|
||||
defaultValue={field.value}
|
||||
>
|
||||
<FormControl>
|
||||
<SelectTrigger>
|
||||
<SelectValue placeholder="選擇分析模式" />
|
||||
</SelectTrigger>
|
||||
</FormControl>
|
||||
<SelectContent>
|
||||
<SelectItem value="fast">快速分析 (~15-25 分鐘)</SelectItem>
|
||||
<SelectItem value="deep">深層分析 (~1 小時)</SelectItem>
|
||||
</SelectContent>
|
||||
</Select>
|
||||
<FormDescription>快速模式跳過辯論,深層模式包含投資和風險辯論</FormDescription>
|
||||
<FormMessage />
|
||||
</FormItem>
|
||||
)}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* 第二行:研究深度、快速思維模型、深層思維模型、嵌入式模型(4列) */}
|
||||
<div className="md:col-span-2 grid grid-cols-1 md:grid-cols-4 gap-6">
|
||||
<FormField
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
|
||||
import time
|
||||
import json
|
||||
from tradingagents.agents.utils.agent_utils import get_fundamentals, get_balance_sheet, get_cashflow, get_income_statement, get_insider_sentiment, get_insider_transactions, filter_messages_for_analyst
|
||||
from tradingagents.agents.utils.agent_utils import get_fundamentals, get_balance_sheet, get_cashflow, get_income_statement, get_insider_sentiment, get_insider_transactions
|
||||
from tradingagents.agents.utils.prompts import get_fundamentals_analyst_prompt, get_agent_role_instruction, get_context_message
|
||||
from tradingagents.dataflows.config import get_config
|
||||
|
||||
|
|
@ -60,8 +60,7 @@ def create_fundamentals_analyst(llm, language: str = "zh-TW"):
|
|||
|
||||
chain = prompt | llm.bind_tools(tools)
|
||||
|
||||
tool_names = {t.name for t in tools}
|
||||
result = chain.invoke(filter_messages_for_analyst(state["messages"], tool_names))
|
||||
result = chain.invoke(state["messages"])
|
||||
|
||||
# Report logic: only save report when LLM gives final response
|
||||
report = state.get("fundamentals_report", "")
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
|
||||
import time
|
||||
import json
|
||||
from tradingagents.agents.utils.agent_utils import get_stock_data, get_indicators, filter_messages_for_analyst
|
||||
from tradingagents.agents.utils.agent_utils import get_stock_data, get_indicators
|
||||
from tradingagents.agents.utils.prompts import get_language_instruction, get_agent_role_instruction, get_context_message
|
||||
from tradingagents.dataflows.config import get_config
|
||||
|
||||
|
|
@ -140,8 +140,7 @@ Please provide a professional, precise, and actionable technical analysis report
|
|||
|
||||
chain = prompt | llm.bind_tools(tools)
|
||||
|
||||
tool_names = {t.name for t in tools}
|
||||
result = chain.invoke(filter_messages_for_analyst(state["messages"], tool_names))
|
||||
result = chain.invoke(state["messages"])
|
||||
|
||||
# Report logic: only save report when LLM gives final response
|
||||
report = state.get("market_report", "")
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
|
||||
import time
|
||||
import json
|
||||
from tradingagents.agents.utils.agent_utils import get_news, get_global_news, filter_messages_for_analyst
|
||||
from tradingagents.agents.utils.agent_utils import get_news, get_global_news
|
||||
from tradingagents.agents.utils.prompts import get_news_analyst_prompt, get_agent_role_instruction, get_context_message
|
||||
from tradingagents.dataflows.config import get_config
|
||||
|
||||
|
|
@ -57,8 +57,7 @@ def create_news_analyst(llm, language: str = "zh-TW"):
|
|||
prompt = prompt.partial(tool_names=", ".join([tool.name for tool in tools]))
|
||||
|
||||
chain = prompt | llm.bind_tools(tools)
|
||||
tool_names = {t.name for t in tools}
|
||||
result = chain.invoke(filter_messages_for_analyst(state["messages"], tool_names))
|
||||
result = chain.invoke(state["messages"])
|
||||
|
||||
# Report logic: only save report when LLM gives final response
|
||||
report = state.get("news_report", "")
|
||||
|
|
|
|||
|
|
@ -1,7 +1,7 @@
|
|||
from langchain_core.prompts import ChatPromptTemplate, MessagesPlaceholder
|
||||
import time
|
||||
import json
|
||||
from tradingagents.agents.utils.agent_utils import get_news, filter_messages_for_analyst
|
||||
from tradingagents.agents.utils.agent_utils import get_news
|
||||
from tradingagents.agents.utils.prompts import get_social_analyst_prompt, get_agent_role_instruction, get_context_message
|
||||
from tradingagents.dataflows.config import get_config
|
||||
|
||||
|
|
@ -57,8 +57,7 @@ def create_social_media_analyst(llm, language: str = "zh-TW"):
|
|||
|
||||
chain = prompt | llm.bind_tools(tools)
|
||||
|
||||
tool_names = {t.name for t in tools}
|
||||
result = chain.invoke(filter_messages_for_analyst(state["messages"], tool_names))
|
||||
result = chain.invoke(state["messages"])
|
||||
|
||||
# Report logic: only save report when LLM gives final response
|
||||
report = state.get("sentiment_report", "")
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
from langchain_core.messages import HumanMessage, RemoveMessage, AIMessage, ToolMessage
|
||||
from langchain_core.messages import HumanMessage, RemoveMessage
|
||||
|
||||
# 從獨立的工具程式檔案匯入工具
|
||||
from tradingagents.agents.utils.core_stock_tools import (
|
||||
|
|
@ -20,42 +20,6 @@ from tradingagents.agents.utils.news_data_tools import (
|
|||
get_global_news
|
||||
)
|
||||
|
||||
def filter_messages_for_analyst(messages, analyst_tool_names):
|
||||
"""
|
||||
Filter shared state messages to only include conversations relevant to this analyst.
|
||||
|
||||
In parallel analyst execution, all analysts share state["messages"]. When analyst A
|
||||
makes tool_use calls, those get merged into shared state. When analyst B runs its
|
||||
second iteration, it sees orphaned tool_use blocks from analyst A without matching
|
||||
tool_results, causing anthropic.BadRequestError (400).
|
||||
|
||||
This function keeps only:
|
||||
- Non-tool messages (HumanMessage etc.)
|
||||
- AIMessages whose tool_calls ALL belong to this analyst's tools
|
||||
- ToolMessages whose tool_call_id matches this analyst's tool calls
|
||||
"""
|
||||
analyst_tool_call_ids = set()
|
||||
for msg in messages:
|
||||
if isinstance(msg, AIMessage) and msg.tool_calls:
|
||||
for tc in msg.tool_calls:
|
||||
if tc["name"] in analyst_tool_names:
|
||||
analyst_tool_call_ids.add(tc["id"])
|
||||
|
||||
result = []
|
||||
for msg in messages:
|
||||
if isinstance(msg, AIMessage) and msg.tool_calls:
|
||||
if all(tc["name"] in analyst_tool_names for tc in msg.tool_calls):
|
||||
result.append(msg)
|
||||
# Skip AI messages containing tool_calls from other parallel analysts
|
||||
elif isinstance(msg, ToolMessage):
|
||||
if msg.tool_call_id in analyst_tool_call_ids:
|
||||
result.append(msg)
|
||||
else:
|
||||
result.append(msg)
|
||||
|
||||
return result
|
||||
|
||||
|
||||
def create_msg_delete():
|
||||
"""
|
||||
建立一個刪除訊息的函式。
|
||||
|
|
|
|||
Loading…
Reference in New Issue