package main import ( "context" "encoding/json" coreconfig "gitea.maximumdirect.net/eric/audita/internal/core/config" "gitea.maximumdirect.net/eric/audita/internal/core/schema" "gitea.maximumdirect.net/eric/audita/internal/framework/promptcontext" "gitea.maximumdirect.net/eric/audita/internal/framework/proposals" "gitea.maximumdirect.net/eric/audita/internal/framework/validators" pk "gitea.maximumdirect.net/eric/promptkit" ) type WorkflowResult struct { Accepted int `json:"accepted"` Rejected int `json:"rejected"` Warnings []string `json:"warnings,omitempty"` } // workflow demonstrates one section and two roles; it never mutates a transcript. // Production migration will retain the full validator chains and runner. func (r *Runtime) workflow(ctx context.Context, observe func(string) pk.ExecutionObserver) (WorkflowResult, error) { var out WorkflowResult transcript := &schema.Transcript{Segments: []schema.Segment{{ID: 1, Text: "hello world"}}} section, err := promptcontext.MarshalTranscriptSectionJSON(transcript, 0) if err != nil { return out, err } vars := map[string]string{"SectionJSON": string(section), "GlossaryJSON": "[]", "TranscriptDescriptionBlock": promptcontext.TranscriptDescriptionBlock("Synthetic grammar example")} result, err := r.call(ctx, "proposal", vars, observe("proposal")) if err != nil { return out, err } if !result.Validation.IsValid { out.Warnings = append(out.Warnings, "proposal_response_malformed") return out, nil } var response struct { Corrections []proposals.CorrectionProposal `json:"corrections"` } if err := json.Unmarshal([]byte(result.RawOutput), &response); err != nil { return out, err } candidates := []proposals.EnrichedCorrectionProposal{} payload := []map[string]any{} for index, p := range response.Corrections { preview := proposals.PreviewProposalForSegment(&transcript.Segments[0], p, proposals.ReplacementPolicyRequireUnique) if !preview.Applicable || p.Confidence < coreconfig.Default().Thresholds.Grammar { out.Rejected++ continue } candidates = append(candidates, proposals.EnrichedCorrectionProposal{CorrectionProposal: p, ProposalMetadata: proposals.ProposalMetadata{ProposalIndex: index}}) payload = append(payload, map[string]any{"correction_index": index, "id": p.TargetSegmentID, "original_text": p.OriginalText, "corrected_text": p.CorrectedText, "original_segment_text": transcript.Segments[0].Text, "corrected_segment_text": preview.CorrectedSegmentText}) } if len(candidates) == 0 { return out, nil } body, err := json.Marshal(payload) if err != nil { return out, err } result, err = r.call(ctx, "assessment", map[string]string{"PayloadJSON": string(body), "TranscriptDescriptionBlock": vars["TranscriptDescriptionBlock"]}, observe("assessment")) if err != nil { return out, err } if !result.Validation.IsValid { out.Rejected += len(candidates) out.Warnings = append(out.Warnings, "validator_response_malformed") return out, nil } var assessment struct { Validations []struct { Index int `json:"correction_index"` Approved bool `json:"approved"` Confidence float64 `json:"confidence"` Reason string `json:"reason"` } `json:"validations"` } if err := json.Unmarshal([]byte(result.RawOutput), &assessment); err != nil { return out, err } decisions := make([]validators.Decision, len(assessment.Validations)) for i, d := range assessment.Validations { decisions[i] = validators.Decision{ProposalIndex: d.Index, Approved: d.Approved} } if err := validators.EnforceDecisionCardinality(candidates, decisions); err != nil { out.Rejected += len(candidates) out.Warnings = append(out.Warnings, "validator_response_malformed") return out, nil } for _, d := range decisions { if d.Approved { out.Accepted++ } else { out.Rejected++ } } return out, nil }