package spoken_word import ( "context" "fmt" "gitea.maximumdirect.net/eric/audita/internal/framework/contracts" "gitea.maximumdirect.net/eric/audita/internal/framework/proposal_generation" "gitea.maximumdirect.net/eric/audita/internal/framework/proposals" "gitea.maximumdirect.net/eric/audita/internal/framework/validators" ) type Module struct { validators []contracts.Validator } func New() (*Module, error) { spokenWordReview, err := validators.NewLLMBackedValidator("spoken_word_review", validators.LLMValidatorTypeSpokenWordReview, "") if err != nil { return nil, err } meaningReversal, err := validators.NewLLMBackedValidator("meaning_reversal_review", validators.LLMValidatorTypeMeaningReversal, "") if err != nil { return nil, err } return &Module{ validators: []contracts.Validator{ validators.NoEffectValidator{}, validators.OriginalTextPresenceValidator{}, validators.ConfidenceThresholdValidator{}, validators.ProtectedGlossaryTermValidator{}, validators.NonEmptyCorrectionValidator{}, spokenWordReview, meaningReversal, }, }, nil } func (m *Module) Key() string { return "spoken_word" } func (m *Module) ReplacementPolicy() proposals.ReplacementPolicy { // Python spoken_word module uses require_unique for conservative single-span replacement. return proposals.ReplacementPolicyRequireUnique } func (m *Module) Validators() []contracts.Validator { return append([]contracts.Validator(nil), m.validators...) } func (m *Module) Propose(ctx context.Context, req contracts.ProposalRequest) ([]proposals.CorrectionProposal, error) { messages, err := BuildProposalMessages(req.WorkingTranscript, req.Glossary) if err != nil { return nil, err } generated, err := proposal_generation.GenerateCandidates(ctx, proposal_generation.Request{ ModuleKey: req.RunSpec.ModuleKey, ModuleInstance: req.RunSpec.InstanceName, ReplacementPolicy: req.RunSpec.ReplacementPolicy, WorkingTranscript: req.WorkingTranscript, Section: req.Section, Glossary: req.Glossary, Config: req.Config, Messages: messages, StageName: fmt.Sprintf("%s:proposal", req.RunSpec.InstanceName), StartIndex: 0, LLMClient: req.LLMClient, Scheduler: req.LLMScheduler, DiagnosticsDir: req.DiagnosticsDir, }) if err != nil { return nil, err } return generated.Corrections, nil }