onTrialEnd method
Future<void>
onTrialEnd({
- required Trial trial,
- required Transcript transcript,
- required Outcome outcome,
- required List<
Score> scores,
override
Called when trial finishes with the final transcript, outcome, and scores. Implementations should attach all scores here.
Implementation
@override
Future<void> onTrialEnd({
required Trial trial,
required Transcript transcript,
required Outcome outcome,
required List<Score> scores,
}) async {
final traceId = _traceIdFor(trial);
// 用 trace-create 再写一次同 id 的 trace 来 merge:补 endTime / output /
// 终态 metadata(30 天内 langfuse 服务端会按 id 合并)。
_client.enqueue(
LangfuseEvent(
id: _uuid.v4(),
type: 'trace-create',
timestamp: trial.endedAt,
body: {
'id': traceId,
'timestamp': trial.startedAt.toUtc().toIso8601String(),
'name': '${trial.suiteName}/${trial.taskId}#${trial.trialIndex}',
'environment': config.environment,
'userId': trial.runName,
'sessionId': trial.suiteName,
'output': outcome.toJson(),
'metadata': {
'status': trial.status.name,
if (trial.failureReason != null)
'failureReason': trial.failureReason,
'durationMs': trial.duration.inMilliseconds,
'transcriptMetrics': transcript.metrics.toJson(),
},
},
),
);
// 每个 grader 一条 score-create。
for (final s in scores) {
if (s.value == null) continue; // null score 不上传(langfuse 不支持)
_client.enqueue(
LangfuseEvent(
id: _uuid.v4(),
type: 'score-create',
timestamp: trial.endedAt,
body: {
'id': _uuid.v4(),
'traceId': traceId,
'environment': config.environment,
'name': s.graderName,
'value': s.value,
'dataType': 'NUMERIC',
if (s.rationale != null) 'comment': s.rationale,
'metadata': {
if (s.passed != null) 'passed': s.passed,
'assertions': s.assertions.map((a) => a.toJson()).toList(),
...s.metadata,
},
},
),
);
}
}