feat: integrate chatbox research with datasets and backtests
This commit is contained in:
@@ -19,6 +19,7 @@ import {
|
||||
stateLabels,
|
||||
} from "../api";
|
||||
import { BacktestToolCard } from "../backtests/BacktestToolCard";
|
||||
import { CatalogToolCard } from "../research/CatalogToolCard";
|
||||
import { PnlChart } from "../components/PnlChart";
|
||||
import type { Alpha, Job, Pnl, Research } from "../types";
|
||||
import { chatTransport } from "./transport";
|
||||
@@ -45,6 +46,7 @@ export function ChatPanel({
|
||||
onWidth,
|
||||
timezone,
|
||||
jobs,
|
||||
action,
|
||||
}: {
|
||||
open: boolean;
|
||||
context: PageContext;
|
||||
@@ -56,6 +58,7 @@ export function ChatPanel({
|
||||
onWidth: (width: number) => void;
|
||||
timezone?: string;
|
||||
jobs: Job[];
|
||||
action: UIAction | null;
|
||||
}) {
|
||||
const [settings, setSettings] = useState<ModelSettings | null>(null);
|
||||
const [conversations, setConversations] = useState<Conversation[]>([]);
|
||||
@@ -179,6 +182,32 @@ export function ChatPanel({
|
||||
setLoading(true);
|
||||
void refreshConversation().finally(() => setLoading(false));
|
||||
}, [conversationId, refreshConversation]);
|
||||
useEffect(() => {
|
||||
if (action?.type !== "open_conversation") return;
|
||||
let live = true;
|
||||
void api<ConversationDetail>(
|
||||
`/ai/conversations/${encodeURIComponent(action.conversation_id)}`,
|
||||
)
|
||||
.then(async (detail) => {
|
||||
if (!live) return;
|
||||
await chat.stop();
|
||||
if (!live) return;
|
||||
setConversations((items) =>
|
||||
items.some((item) => item.id === detail.id)
|
||||
? items
|
||||
: [{ id: detail.id, title: detail.title }, ...items],
|
||||
);
|
||||
setConversationId(detail.id);
|
||||
setText("");
|
||||
setFailure("");
|
||||
})
|
||||
.catch((e) => {
|
||||
if (live) setFailure(e.message);
|
||||
});
|
||||
return () => {
|
||||
live = false;
|
||||
};
|
||||
}, [action]);
|
||||
const streaming = chat.status === "streaming" || chat.status === "submitted";
|
||||
const activeRun = runs.find((run) =>
|
||||
["running", "waiting_approval"].includes(run.status),
|
||||
@@ -375,7 +404,10 @@ export function ChatPanel({
|
||||
{!chat.messages.length && (
|
||||
<div className="ai-empty">
|
||||
<h3>从当前研究出发</h3>
|
||||
<p>可以让我筛选 Alpha、解释已有指标,或提出研究记录修改。</p>
|
||||
<p>
|
||||
可以让我选择数据字段、构建候选并预览回测,也可以查询 Alpha
|
||||
和已有结果。
|
||||
</p>
|
||||
{!conversationId && (
|
||||
<Button
|
||||
type="tertiary"
|
||||
@@ -440,7 +472,7 @@ export function ChatPanel({
|
||||
{context.page === "backtests"
|
||||
? "上下文:回测研究"
|
||||
: context.page === "datasets"
|
||||
? "上下文:数据目录(未发送字段与备注)"
|
||||
? `上下文:${context.dataset_id ?? "数据目录"}${context.catalog_scope ? ` · ${context.catalog_scope.region}/${context.catalog_scope.universe}/D${context.catalog_scope.delay}` : ""}${context.template_input_id ? " · 固定研究输入" : context.unsaved_field_selection ? " · 请先保存字段选择" : ""}(不发送未保存备注)`
|
||||
: context.page === "account"
|
||||
? "上下文:个人信息页"
|
||||
: `上下文:${context.alpha_id ? `Alpha ${context.alpha_id}` : "Alpha 列表"}${context.selected_ids?.length ? ` · 已选 ${context.selected_ids.length} 条` : ""}`}
|
||||
@@ -547,6 +579,7 @@ function BusinessCard({
|
||||
{call.name.includes("backtest") && (
|
||||
<BacktestToolCard call={call} onAction={onAction} />
|
||||
)}
|
||||
<CatalogToolCard call={call} onAction={onAction} />
|
||||
{call.preview.targets?.map((target) => (
|
||||
<details
|
||||
key={target.alpha_id}
|
||||
|
||||
Reference in New Issue
Block a user