Integrate transcription checkpoints across lifecycle

This commit is contained in:
2026-09-22 00:00:51 +00:00
parent 2ae63dbc2b
commit d872edca94
7 changed files with 581 additions and 2 deletions

View File

@@ -306,6 +306,12 @@ func normalizeMergeInputs(
}
func discoverRawTranscripts(m *manifest.Manifest, paths artifacts.SessionPaths) ([]string, error) {
if record, versioned, err := transcribeManifestState(m); err != nil {
return nil, err
} else if versioned {
return discoverVersionedRawTranscripts(record, paths)
}
fromManifest := make([]string, 0)
if m != nil && m.Stages != nil {
if tr := m.Stages["transcribe"]; tr != nil {
@@ -350,6 +356,64 @@ func discoverRawTranscripts(m *manifest.Manifest, paths artifacts.SessionPaths)
return dedupeAndSortPaths(out), nil
}
func discoverVersionedRawTranscripts(
record *manifest.StageRecord,
paths artifacts.SessionPaths,
) ([]string, error) {
if record.Status != manifest.StatusSucceeded {
return nil, fmt.Errorf("versioned transcribe state is not aggregate-successful (status %q)", record.Status)
}
if err := manifest.ValidateTranscribeSpeakerCollection(
record.TranscribeStateVersion,
record.TranscribeSpeakers,
); err != nil {
return nil, fmt.Errorf("validate versioned transcribe state: %w", err)
}
if len(record.TranscribeSpeakers) == 0 {
return nil, fmt.Errorf("versioned transcribe state has no completed speakers")
}
expected := make(map[string]string, len(record.TranscribeSpeakers))
for speaker, speakerRecord := range record.TranscribeSpeakers {
path := filepath.Clean(artifacts.ResolveSessionLocalPathForRead(paths, speakerRecord.Output.LocalPath))
if other, exists := expected[path]; exists {
return nil, fmt.Errorf("versioned transcribe speakers %q and %q declare the same output", other, speaker)
}
expected[path] = speaker
}
inputs := make([]string, 0, len(expected))
for _, output := range record.Outputs {
if output.Kind != "transcript_raw" {
continue
}
path := strings.TrimSpace(output.LocalPath)
if path == "" {
return nil, fmt.Errorf("versioned transcribe aggregate output has an empty local path")
}
path = filepath.Clean(artifacts.ResolveSessionLocalPathForRead(paths, path))
speaker, declared := expected[path]
if !declared {
return nil, fmt.Errorf("versioned transcribe aggregate output %q is not declared by current speaker state", output.LocalPath)
}
if speaker == "" {
return nil, fmt.Errorf("versioned transcribe aggregate output %q is duplicated", output.LocalPath)
}
expected[path] = ""
inputs = append(inputs, path)
}
missing := make([]string, 0)
for _, speaker := range expected {
if speaker != "" {
missing = append(missing, speaker)
}
}
if len(missing) > 0 {
sort.Strings(missing)
return nil, fmt.Errorf("versioned transcribe aggregate outputs are incomplete for speakers: %s", strings.Join(missing, ", "))
}
return dedupeAndSortPaths(inputs), nil
}
func dedupeAndSortPaths(paths []string) []string {
if len(paths) == 0 {
return nil