feat: 使用 Semi AI 组件升级研究助手与研究入口
This commit is contained in:
@@ -8,6 +8,8 @@ import {
|
||||
TextArea,
|
||||
Toast,
|
||||
} from "@douyinfe/semi-ui-19";
|
||||
import { ResearchInput } from "../ai/ResearchInput";
|
||||
import { IconAIEditLevel3 } from "@douyinfe/semi-icons";
|
||||
import { api, post } from "../api";
|
||||
import type { PageContext, UIAction } from "../ai/types";
|
||||
import { TemplateEditor } from "./TemplateEditor";
|
||||
@@ -210,6 +212,7 @@ export function FeaturesPage({
|
||||
)}
|
||||
</ResearchList>
|
||||
<ResearchDetail
|
||||
width="min(100vw, max(640px, 60vw))"
|
||||
title={asset ? asset.name : "新建特征方案"}
|
||||
visible={active && detailOpen}
|
||||
onClose={() => setDetailOpen(false)}
|
||||
@@ -246,14 +249,49 @@ export function FeaturesPage({
|
||||
onChange={(name) => setDraft({ ...draft, name })}
|
||||
/>
|
||||
</label>
|
||||
<label>
|
||||
经济假设
|
||||
<TextArea
|
||||
aria-label="特征经济假设"
|
||||
<section className="research-ai-section">
|
||||
<h4>
|
||||
<IconAIEditLevel3 aria-hidden="true" />
|
||||
经济假设
|
||||
</h4>
|
||||
<ResearchInput
|
||||
maxLength={10000}
|
||||
label="特征经济假设"
|
||||
value={draft.hypothesis}
|
||||
onChange={(hypothesis) => setDraft({ ...draft, hypothesis })}
|
||||
placeholder="描述特征的经济含义、处理方式和预期信号…"
|
||||
references={inputs
|
||||
.filter((i) => draft.input_ids.includes(i.id))
|
||||
.map((i) => ({
|
||||
id: i.id,
|
||||
name: `${i.dataset_id} · ${i.scope.region}/${i.scope.universe}/D${i.scope.delay} · ${i.field_ids.length} 字段 · ${i.id}`,
|
||||
}))}
|
||||
disabled={!!busy}
|
||||
busy={busy === "generate"}
|
||||
canSubmit={!!draft.input_ids.length}
|
||||
submitLabel="AI 生成新方案"
|
||||
sendHotKey="shift+enter"
|
||||
onSubmit={() =>
|
||||
void run("generate", async () => {
|
||||
await load(
|
||||
await post<FeatureAsset>("/research/generate", {
|
||||
name: draft.name,
|
||||
hypothesis: draft.hypothesis,
|
||||
input_ids: draft.input_ids,
|
||||
method: "feature",
|
||||
}),
|
||||
);
|
||||
setRevision((n) => n + 1);
|
||||
})
|
||||
}
|
||||
prompts={["研究字段的时序变化,构建具有经济解释的特征"]}
|
||||
hint={
|
||||
draft.input_ids.length
|
||||
? "生成处理步骤与输出模板,保留假设供继续迭代。"
|
||||
: "请先在下方关联固定输入。"
|
||||
}
|
||||
/>
|
||||
</label>
|
||||
</section>
|
||||
<label>
|
||||
固定输入
|
||||
<ResearchSelect
|
||||
@@ -394,27 +432,6 @@ export function FeaturesPage({
|
||||
>
|
||||
保存并转为模板
|
||||
</Button>
|
||||
<Button
|
||||
disabled={
|
||||
Boolean(busy) || !draft.input_ids.length || !draft.hypothesis
|
||||
}
|
||||
loading={busy === "generate"}
|
||||
onClick={() =>
|
||||
void run("generate", async () => {
|
||||
await load(
|
||||
await post<FeatureAsset>("/research/generate", {
|
||||
name: draft.name,
|
||||
hypothesis: draft.hypothesis,
|
||||
input_ids: draft.input_ids,
|
||||
method: "feature",
|
||||
}),
|
||||
);
|
||||
setRevision((n) => n + 1);
|
||||
})
|
||||
}
|
||||
>
|
||||
AI 生成新方案
|
||||
</Button>
|
||||
</div>
|
||||
<p className="research-hint">
|
||||
保存步骤不会计算原始时间序列。转换后的模板保留此方案的完整版本,回测前仍需展开校验并确认候选。
|
||||
|
||||
@@ -42,11 +42,13 @@ export function ResearchList({
|
||||
export function ResearchDetail({
|
||||
title,
|
||||
visible,
|
||||
width = "60%",
|
||||
onClose,
|
||||
children,
|
||||
}: {
|
||||
title: string;
|
||||
visible: boolean;
|
||||
width?: string;
|
||||
onClose: () => void;
|
||||
children: ReactNode;
|
||||
}) {
|
||||
@@ -55,7 +57,7 @@ export function ResearchDetail({
|
||||
title={title}
|
||||
className="research-detail"
|
||||
placement="right"
|
||||
width="60%"
|
||||
width={width}
|
||||
visible={visible}
|
||||
onCancel={onClose}
|
||||
closeOnEsc
|
||||
|
||||
@@ -9,6 +9,8 @@ import {
|
||||
TextArea,
|
||||
Toast,
|
||||
} from "@douyinfe/semi-ui-19";
|
||||
import { ResearchInput } from "../ai/ResearchInput";
|
||||
import { IconAIEditLevel3 } from "@douyinfe/semi-icons";
|
||||
import { api, post, formatTime } from "../api";
|
||||
import type { PageContext, UIAction } from "../ai/types";
|
||||
import { initialSettings, type SimulationSettings } from "../backtests/types";
|
||||
@@ -432,6 +434,7 @@ export function ResearchWorkspace({
|
||||
)}
|
||||
</ResearchList>
|
||||
<ResearchDetail
|
||||
width="min(100vw, max(640px, 60vw))"
|
||||
title={
|
||||
detailMode === "experiment"
|
||||
? experiment?.name || "生成记录"
|
||||
@@ -504,15 +507,65 @@ export function ResearchWorkspace({
|
||||
<p className="research-hint">
|
||||
在数据目录中保存字段选择。跨数据集分别关联输入,跨市场使用目标范围的独立输入。
|
||||
</p>
|
||||
<label>
|
||||
本次研究假设
|
||||
<TextArea
|
||||
aria-label="本次研究假设"
|
||||
value={hypothesis}
|
||||
onChange={setHypothesis}
|
||||
autosize={{ minRows: 2, maxRows: 5 }}
|
||||
/>
|
||||
</label>
|
||||
{page === "variants" && method === "settings" ? (
|
||||
<label>
|
||||
本次研究假设
|
||||
<TextArea
|
||||
aria-label="本次研究假设"
|
||||
value={hypothesis}
|
||||
onChange={setHypothesis}
|
||||
autosize={{ minRows: 2, maxRows: 5 }}
|
||||
/>
|
||||
</label>
|
||||
) : (
|
||||
<div className="research-ai-section">
|
||||
<h4>
|
||||
<IconAIEditLevel3 aria-hidden="true" />
|
||||
本次研究假设
|
||||
</h4>
|
||||
<ResearchInput
|
||||
maxLength={10000}
|
||||
label="本次研究假设"
|
||||
value={hypothesis}
|
||||
onChange={setHypothesis}
|
||||
placeholder={
|
||||
page === "variants"
|
||||
? "描述希望保留的信号与要探索的变体方向…"
|
||||
: "描述经济假设、信号方向与希望验证的关系…"
|
||||
}
|
||||
references={[
|
||||
...selectedInputs.map((input) => ({
|
||||
id: input.id,
|
||||
name: `${input.dataset_id} · ${input.scope.region}/${input.scope.universe}/D${input.scope.delay} · ${input.field_ids.length} 字段 · ${input.id}`,
|
||||
})),
|
||||
...(page === "variants" && parent
|
||||
? [
|
||||
{
|
||||
id: "parent-alpha",
|
||||
name: `种子 Alpha:${parent}`,
|
||||
},
|
||||
]
|
||||
: []),
|
||||
]}
|
||||
disabled={!!busy}
|
||||
canSubmit={!!inputIds.length}
|
||||
busy={busy === "AI 生成"}
|
||||
submitLabel="AI 生成模板"
|
||||
sendHotKey="shift+enter"
|
||||
onSubmit={() => void task("AI 生成", generate)}
|
||||
prompts={
|
||||
page === "variants"
|
||||
? ["保留种子的经济含义,探索不同时间窗口和字段组合"]
|
||||
: ["研究短期价格反转与成交量之间的关系"]
|
||||
}
|
||||
hint={
|
||||
inputIds.length
|
||||
? "基于已关联的固定输入生成,保留假设供下一轮调整。"
|
||||
: "请先关联固定研究输入。"
|
||||
}
|
||||
/>
|
||||
</div>
|
||||
)}
|
||||
</section>
|
||||
{page !== "variants" || method === "structure" ? (
|
||||
<section className="research-card">
|
||||
@@ -521,13 +574,6 @@ export function ResearchWorkspace({
|
||||
编辑与展开{asset && ` · v${asset.version}`}
|
||||
{dirty && " · 未保存"}
|
||||
</h3>
|
||||
<Button
|
||||
disabled={!inputIds.length || !hypothesis || !!busy}
|
||||
loading={busy === "AI 生成"}
|
||||
onClick={() => void task("AI 生成", generate)}
|
||||
>
|
||||
AI 生成模板
|
||||
</Button>
|
||||
</div>
|
||||
<TemplateEditor
|
||||
value={template}
|
||||
|
||||
Reference in New Issue
Block a user