107 lines
3.4 KiB
Go
107 lines
3.4 KiB
Go
package glossary
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
|
|
"gitea.maximumdirect.net/eric/audita/internal/core/schema"
|
|
"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) {
|
|
spokenForm, err := validators.NewLLMBackedValidator("spoken_form_plausibility_review", validators.LLMValidatorTypeSpokenFormPlausibility, "")
|
|
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.GlossaryStageProtectedGlossaryTermValidator{},
|
|
validators.NonEmptyCorrectionValidator{},
|
|
spokenForm,
|
|
meaningReversal,
|
|
},
|
|
}, nil
|
|
}
|
|
|
|
func (m *Module) Key() string { return "glossary" }
|
|
|
|
func (m *Module) ReplacementPolicy() proposals.ReplacementPolicy {
|
|
// Update repeated term occurrences.
|
|
return proposals.ReplacementPolicyReplaceAll
|
|
}
|
|
|
|
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) {
|
|
sectionTranscript := transcriptForSection(req.WorkingTranscript, req.Section)
|
|
sectionIndex := 0
|
|
if req.Section != nil {
|
|
sectionIndex = req.Section.Index
|
|
}
|
|
transcriptDescription := ""
|
|
if req.Config != nil {
|
|
transcriptDescription = req.Config.TranscriptDescription
|
|
}
|
|
messages, err := BuildProposalMessages(sectionTranscript, req.Glossary, sectionIndex, transcriptDescription)
|
|
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: proposalStageName(req),
|
|
StartIndex: 0,
|
|
LLMClient: req.LLMClient,
|
|
Scheduler: req.LLMScheduler,
|
|
DiagnosticsDir: req.DiagnosticsDir,
|
|
})
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return generated.Corrections, nil
|
|
}
|
|
|
|
func transcriptForSection(transcript *schema.Transcript, section *contracts.SectionMetadata) *schema.Transcript {
|
|
if section == nil || transcript == nil {
|
|
return transcript
|
|
}
|
|
segments := make([]schema.Segment, 0, len(transcript.Segments))
|
|
for _, seg := range transcript.Segments {
|
|
if seg.ID >= section.StartSegmentID && seg.ID <= section.EndSegmentID {
|
|
segments = append(segments, seg)
|
|
}
|
|
}
|
|
return &schema.Transcript{Segments: segments}
|
|
}
|
|
|
|
func proposalStageName(req contracts.ProposalRequest) string {
|
|
if req.Section == nil || req.Section.Index == 0 {
|
|
return fmt.Sprintf("%s:proposal", req.RunSpec.InstanceName)
|
|
}
|
|
return fmt.Sprintf("%s:proposal:section-%04d", req.RunSpec.InstanceName, req.Section.Index)
|
|
}
|