fix(web-probe): anchor prompt timing at command start (#773)
Co-authored-by: Codex <codex@noreply.local>
This commit is contained in:
@@ -3903,11 +3903,7 @@ function isFinalResultText(text) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function buildSampleMetrics(samples, control) {
|
function buildSampleMetrics(samples, control) {
|
||||||
const promptCommands = control
|
const promptCommands = buildSendPromptCommandTimeline(control);
|
||||||
.filter((item) => item.type === "sendPrompt" && item.phase === "completed")
|
|
||||||
.map((item) => ({ ts: item.ts, tsMs: Date.parse(item.ts), commandId: item.commandId ?? null, textHash: item.input?.textHash ?? null, textBytes: item.input?.textBytes ?? null }))
|
|
||||||
.filter((item) => Number.isFinite(item.tsMs))
|
|
||||||
.sort((a, b) => a.tsMs - b.tsMs);
|
|
||||||
const promptTimes = promptCommands.map((item) => item.tsMs);
|
const promptTimes = promptCommands.map((item) => item.tsMs);
|
||||||
const timeline = samples.map((sample) => {
|
const timeline = samples.map((sample) => {
|
||||||
const texts = sampleTexts(sample);
|
const texts = sampleTexts(sample);
|
||||||
@@ -4070,6 +4066,49 @@ function buildSampleMetrics(samples, control) {
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function buildSendPromptCommandTimeline(control) {
|
||||||
|
const byCommand = new Map();
|
||||||
|
let ordinal = 0;
|
||||||
|
for (const item of Array.isArray(control) ? control : []) {
|
||||||
|
if (item?.type !== "sendPrompt") continue;
|
||||||
|
const commandId = item.commandId ? String(item.commandId) : "sendPrompt-" + String(ordinal++);
|
||||||
|
const existing = byCommand.get(commandId) || {
|
||||||
|
commandId,
|
||||||
|
startedAt: null,
|
||||||
|
startedTsMs: null,
|
||||||
|
completedAt: null,
|
||||||
|
completedTsMs: null,
|
||||||
|
failedAt: null,
|
||||||
|
failedTsMs: null,
|
||||||
|
textHash: null,
|
||||||
|
textBytes: null,
|
||||||
|
};
|
||||||
|
if (!existing.textHash && item.input?.textHash) existing.textHash = item.input.textHash;
|
||||||
|
if (!existing.textBytes && item.input?.textBytes) existing.textBytes = item.input.textBytes;
|
||||||
|
const tsMs = Date.parse(item.ts);
|
||||||
|
if (item.phase === "started" && Number.isFinite(tsMs)) {
|
||||||
|
existing.startedAt = item.ts ?? existing.startedAt;
|
||||||
|
existing.startedTsMs = tsMs;
|
||||||
|
} else if (item.phase === "completed" && Number.isFinite(tsMs)) {
|
||||||
|
existing.completedAt = item.ts ?? existing.completedAt;
|
||||||
|
existing.completedTsMs = tsMs;
|
||||||
|
} else if (item.phase === "failed" && Number.isFinite(tsMs)) {
|
||||||
|
existing.failedAt = item.ts ?? existing.failedAt;
|
||||||
|
existing.failedTsMs = tsMs;
|
||||||
|
}
|
||||||
|
byCommand.set(commandId, existing);
|
||||||
|
}
|
||||||
|
return Array.from(byCommand.values())
|
||||||
|
.map((item) => {
|
||||||
|
const tsMs = Number.isFinite(item.startedTsMs) ? item.startedTsMs : Number.isFinite(item.completedTsMs) ? item.completedTsMs : item.failedTsMs;
|
||||||
|
const ts = Number.isFinite(item.startedTsMs) ? item.startedAt : Number.isFinite(item.completedTsMs) ? item.completedAt : item.failedAt;
|
||||||
|
return { ...item, ts, tsMs };
|
||||||
|
})
|
||||||
|
.filter((item) => Number.isFinite(item.tsMs))
|
||||||
|
.sort((a, b) => a.tsMs - b.tsMs)
|
||||||
|
.map((item, index) => ({ ...item, promptIndex: index + 1 }));
|
||||||
|
}
|
||||||
|
|
||||||
function buildSessionRailTitleMetrics(samples, timeline) {
|
function buildSessionRailTitleMetrics(samples, timeline) {
|
||||||
const rows = [];
|
const rows = [];
|
||||||
const examplesByHash = new Map();
|
const examplesByHash = new Map();
|
||||||
@@ -4384,7 +4423,10 @@ function buildTurnTimingTable(samples, timeline) {
|
|||||||
for (const rawMetric of rawMetrics) {
|
for (const rawMetric of rawMetrics) {
|
||||||
const samplePromptIndex = Number(timelineItem.promptIndex ?? 0);
|
const samplePromptIndex = Number(timelineItem.promptIndex ?? 0);
|
||||||
const evidencePromptIndex = inferTurnMetricPromptIndex(rawMetric, samplePromptIndex, maxDomIndex);
|
const evidencePromptIndex = inferTurnMetricPromptIndex(rawMetric, samplePromptIndex, maxDomIndex);
|
||||||
if (evidencePromptIndex !== null && !promptAssignmentByKey.has(rawMetric.key)) promptAssignmentByKey.set(rawMetric.key, evidencePromptIndex);
|
if (evidencePromptIndex !== null) {
|
||||||
|
const existingPromptIndex = promptAssignmentByKey.get(rawMetric.key);
|
||||||
|
if (existingPromptIndex === undefined || evidencePromptIndex > existingPromptIndex) promptAssignmentByKey.set(rawMetric.key, evidencePromptIndex);
|
||||||
|
}
|
||||||
const assignedPromptIndex = promptAssignmentByKey.get(rawMetric.key) ?? null;
|
const assignedPromptIndex = promptAssignmentByKey.get(rawMetric.key) ?? null;
|
||||||
const metric = { ...rawMetric, promptIndex: assignedPromptIndex, samplePromptIndex };
|
const metric = { ...rawMetric, promptIndex: assignedPromptIndex, samplePromptIndex };
|
||||||
let column = registry.get(metric.key);
|
let column = registry.get(metric.key);
|
||||||
@@ -4411,7 +4453,7 @@ function buildTurnTimingTable(samples, timeline) {
|
|||||||
} else {
|
} else {
|
||||||
column.lastSeq = sample.seq ?? null;
|
column.lastSeq = sample.seq ?? null;
|
||||||
column.lastTs = sample.ts ?? null;
|
column.lastTs = sample.ts ?? null;
|
||||||
if (!column.promptIndex && metric.promptIndex) column.promptIndex = metric.promptIndex;
|
if (metric.promptIndex && column.promptIndex !== metric.promptIndex) column.promptIndex = metric.promptIndex;
|
||||||
column.lastPromptIndex = metric.promptIndex ?? column.lastPromptIndex ?? null;
|
column.lastPromptIndex = metric.promptIndex ?? column.lastPromptIndex ?? null;
|
||||||
if (!column.traceId && metric.traceId) column.traceId = metric.traceId;
|
if (!column.traceId && metric.traceId) column.traceId = metric.traceId;
|
||||||
if (!column.messageId && metric.messageId) column.messageId = metric.messageId;
|
if (!column.messageId && metric.messageId) column.messageId = metric.messageId;
|
||||||
|
|||||||
Reference in New Issue
Block a user