Transport structured diagnostics through the pipeline
This commit is contained in:
@@ -25,6 +25,7 @@ type laneExtractState struct {
|
||||
values []erasedExtractArtifact
|
||||
serialized []CheckpointArtifact
|
||||
warnings []contracts.Warning
|
||||
diagnostics []contracts.DiagnosticGroup
|
||||
rejected []contracts.RejectedOutput
|
||||
incomplete []int
|
||||
validationSummaries []artifacts.ValidationSummary
|
||||
@@ -39,6 +40,7 @@ type finalizedExtractResults struct {
|
||||
accepted []erasedExtractArtifact
|
||||
serialized []CheckpointArtifact
|
||||
warnings []contracts.Warning
|
||||
diagnostics []contracts.DiagnosticGroup
|
||||
rejected []contracts.RejectedOutput
|
||||
incomplete []int
|
||||
validationSummaries []artifacts.ValidationSummary
|
||||
@@ -68,6 +70,7 @@ type extractJobResult struct {
|
||||
value erasedExtractArtifact
|
||||
serialized CheckpointArtifact
|
||||
warnings []contracts.Warning
|
||||
diagnostics []contracts.DiagnosticGroup
|
||||
rejected *contracts.RejectedOutput
|
||||
validationIncomplete bool
|
||||
validationSummary *artifacts.ValidationSummary
|
||||
@@ -458,7 +461,7 @@ func (r *Runner) runExtractJob(ctx context.Context, input RunInput, doc *source.
|
||||
return producerAttemptOutput{}, terminal.record(payload, attemptErr)
|
||||
}
|
||||
serializedCandidate.ChunkID, serializedCandidate.ChunkIndex, serializedCandidate.ChunkRef = artifact.ChunkID, artifact.ChunkIndex, artifact.ChunkRef
|
||||
return producerAttemptOutput{Value: extractAttemptValue{artifact: artifact, serialized: serializedCandidate, terminal: &terminal}, Candidate: extracted.ModelCandidate, Warnings: attemptWarnings}, nil
|
||||
return producerAttemptOutput{Value: extractAttemptValue{artifact: artifact, serialized: serializedCandidate, terminal: &terminal}, Candidate: extracted.ModelCandidate, Warnings: attemptWarnings, Diagnostics: contracts.CloneProducerDiagnostics(extracted.Diagnostics)}, nil
|
||||
}, func(validationCtx context.Context, output producerAttemptOutput) (validationReport, error) {
|
||||
candidate, ok := output.Value.(extractAttemptValue)
|
||||
if !ok {
|
||||
@@ -481,6 +484,14 @@ func (r *Runner) runExtractJob(ctx context.Context, input RunInput, doc *source.
|
||||
result.err = errors.Join(result.err, debugErr)
|
||||
return result
|
||||
}
|
||||
if err == nil {
|
||||
diagnostics, diagnosticErr := terminalDiagnosticGroups(terminalResult, contracts.DiagnosticOrigin{Stage: contracts.DiagnosticOriginStageExtract, StepID: input.stepID, LaneID: lane.ID, ModuleKey: lane.Extract.Module}, &chunk)
|
||||
if diagnosticErr != nil {
|
||||
result.err = fmt.Errorf("promote extract diagnostics: %w", diagnosticErr)
|
||||
return result
|
||||
}
|
||||
result.diagnostics = diagnostics
|
||||
}
|
||||
if err == nil && terminalResult.Action == producerTerminalRejected {
|
||||
result.rejected = terminalResult.Rejection
|
||||
if result.rejected != nil {
|
||||
@@ -532,11 +543,13 @@ func finalizeLaneExtract(checkpoints CheckpointRecorder, stepID string, state *l
|
||||
if result.rejected != nil {
|
||||
state.rejected = append(state.rejected, *result.rejected)
|
||||
state.warnings = append(state.warnings, result.warnings...)
|
||||
state.diagnostics = append(state.diagnostics, result.diagnostics...)
|
||||
continue
|
||||
}
|
||||
state.values = append(state.values, result.value)
|
||||
state.serialized = append(state.serialized, result.serialized)
|
||||
state.warnings = append(state.warnings, result.warnings...)
|
||||
state.diagnostics = append(state.diagnostics, result.diagnostics...)
|
||||
if result.validationIncomplete {
|
||||
state.incomplete = append(state.incomplete, result.chunkIndex)
|
||||
}
|
||||
@@ -563,6 +576,7 @@ func (r *Runner) continueLane(ctx context.Context, input RunInput, checkpoints C
|
||||
accepted: state.values,
|
||||
serialized: state.serialized,
|
||||
warnings: state.warnings,
|
||||
diagnostics: state.diagnostics,
|
||||
rejected: state.rejected,
|
||||
incomplete: state.incomplete,
|
||||
validationSummaries: state.validationSummaries,
|
||||
@@ -570,6 +584,7 @@ func (r *Runner) continueLane(ctx context.Context, input RunInput, checkpoints C
|
||||
reuseEligible: state.reuseEligible,
|
||||
}
|
||||
local.Warnings = append(local.Warnings, cloneWarnings(results.warnings)...)
|
||||
local.diagnosticGroups = append(local.diagnosticGroups, contracts.CloneDiagnosticCollection(contracts.DiagnosticCollection{Groups: results.diagnostics}).Groups...)
|
||||
local.Rejected = append(local.Rejected, cloneRejectedOutputs(results.rejected)...)
|
||||
local.ValidationSummaries = append(local.ValidationSummaries, cloneValidationSummaries(results.validationSummaries)...)
|
||||
if err := writeDebugTimed(input.Debug, path.Join("extract", fileio.EncodePathComponent(lane.ID), "input.json"), debugTimedEnvelope{Stage: string(StageExtract), StepID: input.stepID, LaneID: lane.ID, ModuleKey: lane.Extract.Module, StartedAt: time.Now().UTC(), Payload: map[string]any{"reused": results.decision.Reused, "decision": results.decision, "source": debugSourceDocumentEnvelope(doc), "chunks": debugSourceChunkEnvelopes(chunks), "options": redactSensitiveMap(lane.Extract.Options), "metadata": redactSensitiveMap(input.Metadata)}}); err != nil {
|
||||
@@ -641,6 +656,7 @@ func mergeLaneOutput(dst *RunOutput, src RunOutput) error {
|
||||
dst.NormalizeOutputs = append(dst.NormalizeOutputs, cloneSerializedOutputs(src.NormalizeOutputs)...)
|
||||
dst.Rejected = append(dst.Rejected, cloneRejectedOutputs(src.Rejected)...)
|
||||
dst.Warnings = append(dst.Warnings, cloneWarnings(src.Warnings)...)
|
||||
appendDiagnosticGroups(dst, src.diagnosticGroups)
|
||||
dst.CheckpointEvents = append(dst.CheckpointEvents, src.CheckpointEvents...)
|
||||
dst.ValidationSummaries = append(dst.ValidationSummaries, cloneValidationSummaries(src.ValidationSummaries)...)
|
||||
if len(src.normalizeReuseEligibility) > 0 {
|
||||
|
||||
Reference in New Issue
Block a user