Add Go configuration model
This commit is contained in:
@@ -5,6 +5,9 @@ import (
|
||||
"flag"
|
||||
"fmt"
|
||||
"io"
|
||||
"strings"
|
||||
|
||||
"gitea.maximumdirect.net/eric/audita/internal/core/config"
|
||||
)
|
||||
|
||||
const processNotImplementedMessage = "process command is not implemented yet"
|
||||
@@ -36,18 +39,83 @@ func runProcess(args []string, stdout, stderr io.Writer) int {
|
||||
return 0
|
||||
}
|
||||
|
||||
cfg, err := config.LoadFromEnv()
|
||||
if err != nil {
|
||||
fmt.Fprintf(stderr, "audita process: invalid environment configuration: %v\n", err)
|
||||
return 2
|
||||
}
|
||||
|
||||
fs := flag.NewFlagSet("process", flag.ContinueOnError)
|
||||
fs.SetOutput(stderr)
|
||||
|
||||
glossaryPath := fs.String("glossary", "", "Path to glossary YAML file")
|
||||
outputPath := fs.String("output", "", "Path to corrected transcript JSON output file")
|
||||
reportJSONPath := fs.String("report-json", "", "Path to machine-readable report JSON output file")
|
||||
modules := fs.String("modules", "", "Comma-separated module sequence override")
|
||||
modules := fs.String("modules", strings.Join(cfg.Modules, ","), "Comma-separated module sequence override")
|
||||
llmAPIKey := fs.String("llm-api-key", cfg.PrimaryLLM.APIKey, "Primary LLM API key")
|
||||
validationLLMAPIKey := fs.String("validation-llm-api-key", cfg.ValidationLLM.APIKey, "Validation LLM API key")
|
||||
model := fs.String("model", cfg.PrimaryLLM.Model, "Primary LLM model name")
|
||||
validationModel := fs.String("validation-model", cfg.ValidationLLM.Model, "Validation LLM model name")
|
||||
baseURL := fs.String("base-url", cfg.PrimaryLLM.BaseURL, "Primary OpenAI-compatible base URL")
|
||||
validationBaseURL := fs.String("validation-base-url", cfg.ValidationLLM.BaseURL, "Validation OpenAI-compatible base URL")
|
||||
llmTimeoutSeconds := fs.Int("llm-timeout-seconds", cfg.PrimaryLLM.TimeoutSeconds, "Primary LLM timeout in seconds")
|
||||
validationTimeoutSecondsDefault := cfg.PrimaryLLM.TimeoutSeconds
|
||||
if cfg.ValidationLLM.TimeoutSeconds != nil {
|
||||
validationTimeoutSecondsDefault = *cfg.ValidationLLM.TimeoutSeconds
|
||||
}
|
||||
validationLLMTimeoutSeconds := fs.Int("validation-llm-timeout-seconds", validationTimeoutSecondsDefault, "Validation LLM timeout in seconds")
|
||||
maxRetries := fs.Int("max-retries", cfg.PrimaryLLM.MaxRetries, "Maximum structured-output retries")
|
||||
validationMaxRetriesDefault := cfg.PrimaryLLM.MaxRetries
|
||||
if cfg.ValidationLLM.MaxRetries != nil {
|
||||
validationMaxRetriesDefault = *cfg.ValidationLLM.MaxRetries
|
||||
}
|
||||
validationMaxRetries := fs.Int("validation-max-retries", validationMaxRetriesDefault, "Validation structured-output retries")
|
||||
validationMaxPromptTokens := fs.Int("validation-max-prompt-tokens", cfg.ValidationMaxPromptTokens, "Validation max prompt tokens")
|
||||
maxSectionTokens := fs.Int("max-section-tokens", cfg.MaxSectionTokens, "Max section tokens")
|
||||
minSectionTokens := fs.Int("min-section-tokens", cfg.MinSectionTokens, "Min section tokens")
|
||||
targetSectionsDefault := 0
|
||||
if cfg.TargetSections != nil {
|
||||
targetSectionsDefault = *cfg.TargetSections
|
||||
}
|
||||
targetSections := fs.Int("target-sections", targetSectionsDefault, "Target number of transcript sections")
|
||||
glossaryConfidenceThreshold := fs.Float64("glossary-confidence-threshold", cfg.Thresholds.Glossary, "Glossary confidence threshold")
|
||||
grammarConfidenceThreshold := fs.Float64("grammar-confidence-threshold", cfg.Thresholds.Grammar, "Grammar confidence threshold")
|
||||
homophonesConfidenceThreshold := fs.Float64("homophones-confidence-threshold", cfg.Thresholds.Homophones, "Homophones confidence threshold")
|
||||
spokenWordConfidenceThreshold := fs.Float64("spoken-word-confidence-threshold", cfg.Thresholds.SpokenWord, "Spoken-word confidence threshold")
|
||||
normalizeMaxSegmentGap := fs.Float64("normalize-max-segment-gap", cfg.Normalization.MaxSegmentGap, "Maximum same-speaker merge gap")
|
||||
normalizeEllipsisGap := fs.Float64("normalize-ellipsis-gap", cfg.Normalization.EllipsisGap, "Gap threshold for ellipsis insertion")
|
||||
normalizeMaxSegmentDuration := fs.Float64("normalize-max-segment-duration", cfg.Normalization.MaxSegmentDuration, "Maximum merged segment duration")
|
||||
normalizeMaxSegmentTokens := fs.Int("normalize-max-segment-tokens", cfg.Normalization.MaxSegmentTokens, "Maximum merged segment token estimate")
|
||||
workDir := fs.String("work-dir", cfg.WorkDir, "Per-run work directory")
|
||||
workDirRetention := fs.String("work-dir-retention", string(cfg.WorkDirRetention), "Work-dir retention policy: auto|always|never")
|
||||
|
||||
_ = glossaryPath
|
||||
_ = outputPath
|
||||
_ = reportJSONPath
|
||||
_ = modules
|
||||
_ = llmAPIKey
|
||||
_ = validationLLMAPIKey
|
||||
_ = model
|
||||
_ = validationModel
|
||||
_ = baseURL
|
||||
_ = validationBaseURL
|
||||
_ = llmTimeoutSeconds
|
||||
_ = validationLLMTimeoutSeconds
|
||||
_ = maxRetries
|
||||
_ = validationMaxRetries
|
||||
_ = validationMaxPromptTokens
|
||||
_ = maxSectionTokens
|
||||
_ = minSectionTokens
|
||||
_ = targetSections
|
||||
_ = glossaryConfidenceThreshold
|
||||
_ = grammarConfidenceThreshold
|
||||
_ = homophonesConfidenceThreshold
|
||||
_ = spokenWordConfidenceThreshold
|
||||
_ = normalizeMaxSegmentGap
|
||||
_ = normalizeEllipsisGap
|
||||
_ = normalizeMaxSegmentDuration
|
||||
_ = normalizeMaxSegmentTokens
|
||||
_ = workDir
|
||||
_ = workDirRetention
|
||||
|
||||
if err := fs.Parse(args); err != nil {
|
||||
if errors.Is(err, flag.ErrHelp) {
|
||||
@@ -57,6 +125,67 @@ func runProcess(args []string, stdout, stderr io.Writer) int {
|
||||
return 2
|
||||
}
|
||||
|
||||
overrides := config.CLIOverrides{}
|
||||
fs.Visit(func(f *flag.Flag) {
|
||||
switch f.Name {
|
||||
case "modules":
|
||||
overrides.ModulesCSV = modules
|
||||
case "llm-api-key":
|
||||
overrides.PrimaryLLMAPIKey = llmAPIKey
|
||||
case "validation-llm-api-key":
|
||||
overrides.ValidationLLMAPIKey = validationLLMAPIKey
|
||||
case "model":
|
||||
overrides.PrimaryModel = model
|
||||
case "validation-model":
|
||||
overrides.ValidationModel = validationModel
|
||||
case "base-url":
|
||||
overrides.PrimaryBaseURL = baseURL
|
||||
case "validation-base-url":
|
||||
overrides.ValidationBaseURL = validationBaseURL
|
||||
case "llm-timeout-seconds":
|
||||
overrides.PrimaryLLMTimeoutSeconds = llmTimeoutSeconds
|
||||
case "validation-llm-timeout-seconds":
|
||||
overrides.ValidationLLMTimeoutSeconds = validationLLMTimeoutSeconds
|
||||
case "max-retries":
|
||||
overrides.MaxRetries = maxRetries
|
||||
case "validation-max-retries":
|
||||
overrides.ValidationMaxRetries = validationMaxRetries
|
||||
case "validation-max-prompt-tokens":
|
||||
overrides.ValidationMaxPromptTokens = validationMaxPromptTokens
|
||||
case "max-section-tokens":
|
||||
overrides.MaxSectionTokens = maxSectionTokens
|
||||
case "min-section-tokens":
|
||||
overrides.MinSectionTokens = minSectionTokens
|
||||
case "target-sections":
|
||||
overrides.TargetSections = targetSections
|
||||
case "glossary-confidence-threshold":
|
||||
overrides.GlossaryConfidenceThreshold = glossaryConfidenceThreshold
|
||||
case "grammar-confidence-threshold":
|
||||
overrides.GrammarConfidenceThreshold = grammarConfidenceThreshold
|
||||
case "homophones-confidence-threshold":
|
||||
overrides.HomophonesConfidenceThreshold = homophonesConfidenceThreshold
|
||||
case "spoken-word-confidence-threshold":
|
||||
overrides.SpokenWordConfidenceThreshold = spokenWordConfidenceThreshold
|
||||
case "normalize-max-segment-gap":
|
||||
overrides.NormalizeMaxSegmentGap = normalizeMaxSegmentGap
|
||||
case "normalize-ellipsis-gap":
|
||||
overrides.NormalizeEllipsisGap = normalizeEllipsisGap
|
||||
case "normalize-max-segment-duration":
|
||||
overrides.NormalizeMaxSegmentDuration = normalizeMaxSegmentDuration
|
||||
case "normalize-max-segment-tokens":
|
||||
overrides.NormalizeMaxSegmentTokens = normalizeMaxSegmentTokens
|
||||
case "work-dir":
|
||||
overrides.WorkDir = workDir
|
||||
case "work-dir-retention":
|
||||
overrides.WorkDirRetention = workDirRetention
|
||||
}
|
||||
})
|
||||
|
||||
if err := cfg.ApplyCLIOverrides(overrides); err != nil {
|
||||
fmt.Fprintf(stderr, "audita process: invalid CLI configuration: %v\n", err)
|
||||
return 2
|
||||
}
|
||||
|
||||
remaining := fs.Args()
|
||||
if len(remaining) != 1 {
|
||||
fmt.Fprintln(stderr, "audita process: expected exactly 1 transcript JSON path argument")
|
||||
@@ -121,6 +250,11 @@ func writeProcessUsage(w io.Writer) {
|
||||
fmt.Fprintln(w, " --output <path> Path to corrected transcript JSON output file")
|
||||
fmt.Fprintln(w, " --report-json <path> Path to machine-readable report JSON output file")
|
||||
fmt.Fprintln(w, " --modules <list> Comma-separated module sequence override")
|
||||
fmt.Fprintln(w, " --llm-api-key <key> Primary LLM API key")
|
||||
fmt.Fprintln(w, " --model <name> Primary LLM model")
|
||||
fmt.Fprintln(w, " --base-url <url> Primary OpenAI-compatible API base URL")
|
||||
fmt.Fprintln(w, " --work-dir <path> Per-run work directory")
|
||||
fmt.Fprintln(w, " --work-dir-retention <mode> auto|always|never")
|
||||
fmt.Fprintln(w)
|
||||
fmt.Fprintln(w, "Example:")
|
||||
fmt.Fprintln(w, " audita process transcript.json --glossary glossary.yaml --output corrected.json")
|
||||
|
||||
Reference in New Issue
Block a user