feat: 自适应支线插入引擎(WIP:scoring/branching 抽取、挂点重定向、10 条支线 JSON、决策落库)

This commit is contained in:
Jayway Liu
2026-10-04 06:57:32 +08:00
parent 512651b973
commit ea9fa0fe56
37 changed files with 4311 additions and 817 deletions
+4
View File
@@ -59,6 +59,7 @@ export type JevAnswer =
};
export interface JevClient {
adaptiveScoring?: boolean;
ask(state: unknown, questions: Record<string, JevQuestion>): Promise<Record<string, JevAnswer>>;
}
@@ -86,6 +87,7 @@ export class HttpJevClient implements JevClient {
headers.Authorization = `Bearer ${this.apiKey}`;
}
const res = await fetch(url, {
signal: AbortSignal.timeout(15000),
method: 'POST',
headers,
body: JSON.stringify({ model: 'jev-latest', state, questions } satisfies JevRequest),
@@ -121,6 +123,7 @@ function prng(seed: number, n: number): number[] {
/** 无 key 开发用:确定性伪随机返分(同一输入永远同一输出,输出形状与真实 API 对齐)。 */
export class MockJevClient implements JevClient {
adaptiveScoring = true;
async ask(state: unknown, questions: Record<string, JevQuestion>): Promise<Record<string, JevAnswer>> {
const stateKey = JSON.stringify(state) ?? '';
const answers: Record<string, JevAnswer> = {};
@@ -177,6 +180,7 @@ export function getJevClient(): JevClient {
} else {
console.warn('[jev] 未配置 VITE_JEV_PROXY_URL / VITE_TYPESAFE_API_KEY,降级为 MockJevClient(确定性伪随机返分)');
singleton = new MockJevClient();
singleton.adaptiveScoring = false;
}
return singleton;
}