Files
worldquant-alpha-system/frontend/src/ai/workspace.ts
T

120 lines
5.3 KiB
TypeScript
Raw Normal View History

import type { PageContext, UIAction } from "./types";
import type { ResearchReference } from "./ResearchInput";
/** Only expose context already sent by the transport; never include unsaved notes. */
export function contextReferences(context: PageContext): ResearchReference[] {
const refs: ResearchReference[] = [];
const add = (id: string, label: string, value?: string | null) => {
if (value) refs.push({ id, name: `${label}:${value}` });
};
const scope = context.catalog_scope;
if (scope)
add("scope", "范围", `${scope.region}/${scope.universe}/D${scope.delay}`);
add("dataset", "数据集", context.dataset_id);
add("field", "字段", context.field_id);
add("input", "固定输入", context.input_snapshot_id);
add("version", "集合版本", context.collection_version);
add("asset", "研究素材", context.research_asset_id);
add("experiment", "实验", context.research_experiment_id);
add("alpha", "Alpha", context.alpha_id);
add("run", "研究运行", context.research_run_id);
add("backtest", "回测", context.backtest_run_id);
if (context.selected_ids?.length)
add("selection", "已选 Alpha", `${context.selected_ids.length} 条`);
return refs;
}
export function researchPrompts(context: PageContext): string[] {
switch (context.page) {
case "datasets":
return context.unsaved_field_selection
? ["解释当前数据集的字段和适用场景"]
: context.input_snapshot_id
? [
"分析这个固定输入中的字段,提出可验证的研究假设",
"基于这个固定输入构建候选,并预览回测",
]
: [
"解释当前数据集的字段和适用场景",
"如何选择字段并保存为固定研究输入?",
];
case "templates":
return [
"解释当前模板的经济含义和变量组合",
"检查当前研究输入与模板是否匹配",
];
case "variants":
return [
"分析种子 Alpha,提出结构与字段变体思路",
"比较结构变体与市场设置变体的适用场景",
];
case "features":
return ["解释当前特征方案的处理步骤", "根据固定输入提出可验证的特征假设"];
default:
return [
"查询当前研究对象与已有结果",
"介绍从字段选择到候选回测的研究流程",
];
}
}
export type WorkspacePage = PageContext["page"] | "mcp-keys";
const contextLabels: Record<
PageContext["page"],
(context: PageContext) => string
> = {
fields: () => "上下文:字段目录",
preparations: () => "上下文:数据准备",
2026-09-09 18:20:08 +08:00
home: () => "上下文:首页看板",
alphas: (context) =>
`上下文:${context.alpha_id ? `Alpha ${context.alpha_id}` : "Alpha 列表"}${context.selected_ids?.length ? ` · 已选 ${context.selected_ids.length} 条` : ""}`,
operators: () => "上下文:算子库",
templates: (context) =>
`上下文:模板工坊${context.research_asset_id ? ` · ${context.research_asset_id}` : ""}${context.research_experiment_id ? ` · 实验 ${context.research_experiment_id}` : ""}`,
quantflow: (context) =>
`上下文:QuantFlow${context.research_run_id ? ` · ${context.research_run_id}` : ""}`,
pipeline: (context) =>
`上下文:研究流水线${context.research_run_id ? ` · ${context.research_run_id}` : ""}`,
features: () => "上下文:特征工程",
variants: () => "上下文:Alpha 变体",
account: () => "上下文:个人信息页",
backtests: () => "上下文:回测研究",
datasets: (context) =>
`上下文:${context.dataset_id ?? "数据目录"}${context.catalog_scope ? ` · ${context.catalog_scope.region}/${context.catalog_scope.universe}/D${context.catalog_scope.delay}` : ""}${context.input_snapshot_id ? " · 固定研究输入" : context.unsaved_field_selection ? " · 请先保存字段选择" : ""}(不发送未保存备注)`,
};
export function contextLabel(context: PageContext): string {
return contextLabels[context.page](context);
}
export function pageFromHash(hash: string): WorkspacePage {
const value = hash.replace(/^#/, "").split("?")[0];
const page = value.startsWith("quantflow/") ? "quantflow" : value;
if (page === "mcp-keys") return page;
2026-09-09 18:20:08 +08:00
return Object.hasOwn(contextLabels, page) ? (page as WorkspacePage) : "home";
}
type Destination = {
page?: WorkspacePage;
chat: "open" | "close" | "responsive";
};
// Exhaustive action destinations prevent a new action silently falling into Alpha.
const destinations: Record<UIAction["type"], Destination> = {
open_feature: { page: "features", chat: "responsive" },
open_template: { page: "templates", chat: "responsive" },
open_experiment: { page: "templates", chat: "responsive" },
open_variant: { page: "variants", chat: "responsive" },
open_conversation: { chat: "open" },
open_research_input: { page: "preparations", chat: "close" },
open_backtest: { page: "backtests", chat: "responsive" },
open_backtest_preview: { page: "backtests", chat: "responsive" },
open_alpha: { page: "alphas", chat: "responsive" },
apply_filters: { page: "alphas", chat: "responsive" },
};
export function actionDestination(action: UIAction): Destination | undefined {
return Object.hasOwn(destinations, action.type)
? destinations[action.type]
: undefined;
}