feat: 对齐 Jev 真实 API schema、Web Speech 语音输入(优雅降级)、C1-01 语音化身份登记与真 key 冒烟脚本
This commit is contained in:
@@ -18,15 +18,17 @@ interface Props {
|
||||
onReplay: () => void;
|
||||
}
|
||||
|
||||
/** 把 append-only 事件轨迹汇总为喂给 Jev 的 state 文本 */
|
||||
/** 把 append-only 事件轨迹汇总为喂给 Jev 的 state 文本(profile 身份字段是硬过滤字段,不进画像) */
|
||||
function buildState(events: StoryEvent[]): string {
|
||||
const lines = events.map((e) => {
|
||||
if (e.kind === 'choice') {
|
||||
return `[${e.pointId}] 选择「${e.optionLabel}」(维度: ${e.dimensions.join('/') || '字段采集'})`;
|
||||
}
|
||||
const t = e.transcript === null ? '(沉默)' : `(讲述: ${e.transcript})`;
|
||||
return `[${e.pointId}] 讲述${t} 情绪签名: ${e.emotionSignature ?? '未知'}`;
|
||||
});
|
||||
const lines = events
|
||||
.filter((e) => e.kind !== 'profile')
|
||||
.map((e) => {
|
||||
if (e.kind === 'choice') {
|
||||
return `[${e.pointId}] 选择「${e.optionLabel}」(维度: ${e.dimensions.join('/') || '字段采集'})`;
|
||||
}
|
||||
const t = e.transcript === null ? '(沉默)' : `(讲述: ${e.transcript})`;
|
||||
return `[${e.pointId}] 讲述${t} 情绪签名: ${e.emotionSignature ?? '未知'}`;
|
||||
});
|
||||
return `用户在互动剧情《苍梧疑冢》第一幕中的行为轨迹(按时间排序,含初刷与重玩轨迹):\n${lines.join('\n')}`;
|
||||
}
|
||||
|
||||
@@ -40,14 +42,14 @@ export function ReportPage({ store, jev, onReplay }: Props) {
|
||||
(async () => {
|
||||
const events = await store.list();
|
||||
const state = buildState(events);
|
||||
// 7 维 score 问题,criteria 为 1-10 级有序数组
|
||||
const criteria = Array.from({ length: 10 }, (_, i) => String(i + 1));
|
||||
// 7 维 score 问题,criteria 为 10 级有序数组(索引 0-9 对应 1-10 级)
|
||||
const criteria = Array.from({ length: 10 }, (_, i) => `${i + 1} 级`);
|
||||
const questions = Object.fromEntries(
|
||||
PROFILE_DIMENSIONS.map((d) => [
|
||||
d.id,
|
||||
{
|
||||
type: 'score' as const,
|
||||
description: `根据用户行为轨迹,评估其「${d.label}」维度水平:${d.description}`,
|
||||
instructions: `根据用户行为轨迹,评估其「${d.label}」维度水平:${d.description}`,
|
||||
criteria,
|
||||
},
|
||||
]),
|
||||
@@ -58,8 +60,9 @@ export function ReportPage({ store, jev, onReplay }: Props) {
|
||||
setScores(
|
||||
PROFILE_DIMENSIONS.map((d) => {
|
||||
const a = answers[d.id];
|
||||
// API score 是 [0, criteria.length-1] 的概率加权浮点值,+1 映射到 1-10 级展示
|
||||
return a?.type === 'score'
|
||||
? { id: d.id, label: d.label, score: a.score, max: a.max, confidence: a.confidence }
|
||||
? { id: d.id, label: d.label, score: Math.round((a.score + 1) * 10) / 10, max: 10, confidence: a.confidence }
|
||||
: { id: d.id, label: d.label, score: 0, max: 10, confidence: 0 };
|
||||
}),
|
||||
);
|
||||
@@ -118,7 +121,7 @@ export function ReportPage({ store, jev, onReplay }: Props) {
|
||||
<div className="dimension-fill" style={{ width: `${(s.score / s.max) * 100}%` }} />
|
||||
</div>
|
||||
<span className="dimension-value">
|
||||
{s.score}/{s.max} · 置信度 {Math.round(s.confidence * 100)}%
|
||||
{s.score.toFixed(1)}/{s.max} · 置信度 {Math.round(s.confidence * 100)}%
|
||||
</span>
|
||||
</div>
|
||||
))}
|
||||
|
||||
Reference in New Issue
Block a user