Complete Phase 11 proposal generation framework
This commit is contained in:
153
internal/framework/modules/registry.go
Normal file
153
internal/framework/modules/registry.go
Normal file
@@ -0,0 +1,153 @@
|
||||
package modules
|
||||
|
||||
import (
|
||||
"context"
|
||||
"fmt"
|
||||
"strings"
|
||||
|
||||
"gitea.maximumdirect.net/eric/audita/internal/core/config"
|
||||
"gitea.maximumdirect.net/eric/audita/internal/core/schema"
|
||||
"gitea.maximumdirect.net/eric/audita/internal/framework/contracts"
|
||||
)
|
||||
|
||||
const (
|
||||
ModuleKeyGlossary = "glossary"
|
||||
ModuleKeyHomophones = "homophones"
|
||||
ModuleKeySpokenWord = "spoken_word"
|
||||
ModuleKeyGrammar = "grammar"
|
||||
)
|
||||
|
||||
const (
|
||||
ReasonUnsupportedModule = "unsupported_module"
|
||||
ReasonUnimplementedModule = "unimplemented_module"
|
||||
)
|
||||
|
||||
var knownModuleKeys = map[string]struct{}{
|
||||
ModuleKeyGlossary: {},
|
||||
ModuleKeyHomophones: {},
|
||||
ModuleKeySpokenWord: {},
|
||||
ModuleKeyGrammar: {},
|
||||
}
|
||||
|
||||
// IsKnownModuleKey reports whether a module key is recognized by the production
|
||||
// registry scaffold.
|
||||
func IsKnownModuleKey(key string) bool {
|
||||
_, ok := knownModuleKeys[strings.TrimSpace(key)]
|
||||
return ok
|
||||
}
|
||||
|
||||
// Dependencies holds explicit constructor dependencies for module creation.
|
||||
type Dependencies struct {
|
||||
Config *config.Config
|
||||
Glossary *schema.Glossary
|
||||
ProposalLLMClient contracts.StructuredLLMClient
|
||||
ProposalLLMScheduler contracts.LLMScheduler
|
||||
ValidationLLMClient contracts.StructuredLLMClient
|
||||
ValidationLLMScheduler contracts.LLMScheduler
|
||||
DiagnosticsDir string
|
||||
}
|
||||
|
||||
// ConstructRequest is one module-construction request.
|
||||
type ConstructRequest struct {
|
||||
RunSpec contracts.ModuleRunSpec
|
||||
Dependencies
|
||||
}
|
||||
|
||||
// Constructor builds one module instance from a run spec and explicit deps.
|
||||
type Constructor func(ctx context.Context, req ConstructRequest) (contracts.TranscriptModule, error)
|
||||
|
||||
// Factory resolves configured module specs into module instances.
|
||||
type Factory struct {
|
||||
deps Dependencies
|
||||
constructors map[string]Constructor
|
||||
}
|
||||
|
||||
// NewFactory creates a production registry scaffold with known module keys but
|
||||
// no real module constructors registered yet.
|
||||
func NewFactory(deps Dependencies) *Factory {
|
||||
return &Factory{
|
||||
deps: deps,
|
||||
constructors: make(map[string]Constructor, len(knownModuleKeys)),
|
||||
}
|
||||
}
|
||||
|
||||
// RegisterConstructor registers a constructor for a known module key.
|
||||
func (f *Factory) RegisterConstructor(moduleKey string, constructor Constructor) error {
|
||||
if f == nil {
|
||||
return fmt.Errorf("module factory is nil")
|
||||
}
|
||||
key := strings.TrimSpace(moduleKey)
|
||||
if !IsKnownModuleKey(key) {
|
||||
return &UnsupportedModuleError{ModuleKey: key}
|
||||
}
|
||||
if constructor == nil {
|
||||
return fmt.Errorf("constructor for module %q must not be nil", key)
|
||||
}
|
||||
f.constructors[key] = constructor
|
||||
return nil
|
||||
}
|
||||
|
||||
// ModuleForSpec resolves one configured run spec into a module instance.
|
||||
func (f *Factory) ModuleForSpec(spec contracts.ModuleRunSpec) (contracts.TranscriptModule, error) {
|
||||
if f == nil {
|
||||
return nil, fmt.Errorf("module factory is nil")
|
||||
}
|
||||
|
||||
key := strings.TrimSpace(spec.ModuleKey)
|
||||
if !IsKnownModuleKey(key) {
|
||||
return nil, &UnsupportedModuleError{ModuleKey: key}
|
||||
}
|
||||
|
||||
constructor, ok := f.constructors[key]
|
||||
if !ok || constructor == nil {
|
||||
return nil, &UnimplementedModuleError{ModuleKey: key}
|
||||
}
|
||||
|
||||
module, err := constructor(context.Background(), ConstructRequest{
|
||||
RunSpec: spec,
|
||||
Dependencies: Dependencies{
|
||||
Config: f.deps.Config,
|
||||
Glossary: f.deps.Glossary,
|
||||
ProposalLLMClient: f.deps.ProposalLLMClient,
|
||||
ProposalLLMScheduler: f.deps.ProposalLLMScheduler,
|
||||
ValidationLLMClient: f.deps.ValidationLLMClient,
|
||||
ValidationLLMScheduler: f.deps.ValidationLLMScheduler,
|
||||
DiagnosticsDir: f.deps.DiagnosticsDir,
|
||||
},
|
||||
})
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("construct module %q: %w", spec.InstanceName, err)
|
||||
}
|
||||
if module == nil {
|
||||
return nil, fmt.Errorf("constructor for module %q returned nil module", key)
|
||||
}
|
||||
return module, nil
|
||||
}
|
||||
|
||||
// UnsupportedModuleError indicates a configured module key is unknown.
|
||||
type UnsupportedModuleError struct {
|
||||
ModuleKey string
|
||||
}
|
||||
|
||||
func (e *UnsupportedModuleError) Error() string {
|
||||
return fmt.Sprintf("unsupported module key %q", strings.TrimSpace(e.ModuleKey))
|
||||
}
|
||||
|
||||
// ReasonCode returns a stable reason code suitable for reporting.
|
||||
func (e *UnsupportedModuleError) ReasonCode() string {
|
||||
return ReasonUnsupportedModule
|
||||
}
|
||||
|
||||
// UnimplementedModuleError indicates a known module key without constructor.
|
||||
type UnimplementedModuleError struct {
|
||||
ModuleKey string
|
||||
}
|
||||
|
||||
func (e *UnimplementedModuleError) Error() string {
|
||||
return fmt.Sprintf("module %q is recognized but not implemented", strings.TrimSpace(e.ModuleKey))
|
||||
}
|
||||
|
||||
// ReasonCode returns a stable reason code suitable for reporting.
|
||||
func (e *UnimplementedModuleError) ReasonCode() string {
|
||||
return ReasonUnimplementedModule
|
||||
}
|
||||
Reference in New Issue
Block a user