599 lines
19 KiB
Go
599 lines
19 KiB
Go
package cli
|
|
|
|
import (
|
|
"bytes"
|
|
"context"
|
|
"fmt"
|
|
"io"
|
|
"strings"
|
|
"time"
|
|
|
|
ck "gitea.maximumdirect.net/eric/ConfigKit"
|
|
"gitea.maximumdirect.net/eric/audita/internal/core/chunking"
|
|
"gitea.maximumdirect.net/eric/audita/internal/core/config"
|
|
"gitea.maximumdirect.net/eric/audita/internal/core/diagnostics"
|
|
coreio "gitea.maximumdirect.net/eric/audita/internal/core/io"
|
|
"gitea.maximumdirect.net/eric/audita/internal/core/normalization"
|
|
"gitea.maximumdirect.net/eric/audita/internal/core/outputschema"
|
|
"gitea.maximumdirect.net/eric/audita/internal/core/reporting"
|
|
"gitea.maximumdirect.net/eric/audita/internal/core/schema"
|
|
"gitea.maximumdirect.net/eric/audita/internal/framework/contracts"
|
|
"gitea.maximumdirect.net/eric/audita/internal/framework/llm"
|
|
"gitea.maximumdirect.net/eric/audita/internal/framework/modules"
|
|
"gitea.maximumdirect.net/eric/audita/internal/framework/processreport"
|
|
"gitea.maximumdirect.net/eric/audita/internal/framework/runner"
|
|
)
|
|
|
|
type processInvocation struct {
|
|
TranscriptPath string
|
|
GlossaryPath string
|
|
OutputPath string
|
|
ReportJSONPath string
|
|
Config config.Config
|
|
ConfigResult *ck.Result[config.Config]
|
|
LLMRuntime *llm.Runtime
|
|
ConfigPath string
|
|
ConfigSource string
|
|
ConfigVersion *int
|
|
ExplicitModules bool
|
|
}
|
|
|
|
var processModuleFactory runner.ModuleFactory
|
|
var processProposalLLMClient contracts.StructuredLLMClient
|
|
var processValidationLLMClient contracts.StructuredLLMClient
|
|
var processRunnerContext = func() (context.Context, context.CancelFunc) {
|
|
return context.Background(), func() {}
|
|
}
|
|
|
|
var processRunner = func(inv processInvocation, stdout io.Writer) (*normalization.NormalizationSummary, *chunking.Summary, *runner.RunOutput, *diagnostics.RunDirectory, error) {
|
|
runDir, err := diagnostics.NewRunDirectory(inv.Config.Diagnostics.WorkDir, string(inv.Config.Diagnostics.Retention))
|
|
if err != nil {
|
|
return nil, nil, nil, nil, fmt.Errorf("run_dir_creation: %w", err)
|
|
}
|
|
|
|
fail := func(phase string, err error, runOutput *runner.RunOutput) (*normalization.NormalizationSummary, *chunking.Summary, *runner.RunOutput, *diagnostics.RunDirectory, error) {
|
|
_ = runDir.WriteErrorLog(fmt.Sprintf("%s: %v", phase, err))
|
|
return nil, nil, runOutput, runDir, fmt.Errorf("%s: %w", phase, err)
|
|
}
|
|
|
|
if err := runDir.WriteInvocationMetadata(diagnostics.InvocationMetadata{
|
|
Operation: "process",
|
|
TranscriptPath: inv.TranscriptPath,
|
|
GlossaryPath: inv.GlossaryPath,
|
|
OutputPath: inv.OutputPath,
|
|
ReportJSONPath: inv.ReportJSONPath,
|
|
ConfigPath: inv.ConfigPath,
|
|
ConfigSource: inv.ConfigSource,
|
|
ConfigVersion: inv.ConfigVersion,
|
|
TranscriptDescription: inv.Config.Context.Description,
|
|
Modules: append([]string(nil), inv.Config.Pipeline.Modules...),
|
|
}); err != nil {
|
|
_ = runDir.WriteErrorLog(fmt.Sprintf("invocation_metadata: %v", err))
|
|
}
|
|
if inv.ConfigResult != nil {
|
|
var effective bytes.Buffer
|
|
if err := inv.ConfigResult.WriteEffective(&effective); err == nil {
|
|
err = runDir.WriteEffectiveConfig(effective.Bytes())
|
|
}
|
|
if err != nil {
|
|
_ = runDir.WriteErrorLog(fmt.Sprintf("effective_config: %v", err))
|
|
}
|
|
}
|
|
|
|
transcriptBytes, err := coreio.ReadRequiredFile(inv.TranscriptPath, "transcript")
|
|
if err != nil {
|
|
return fail("transcript_read", err, nil)
|
|
}
|
|
|
|
glossaryBytes, err := coreio.ReadRequiredFile(inv.GlossaryPath, "glossary")
|
|
if err != nil {
|
|
return fail("glossary_read", err, nil)
|
|
}
|
|
|
|
sourceTranscript, err := schema.ParseSourceTranscriptJSON(transcriptBytes)
|
|
if err != nil {
|
|
return fail("transcript_schema", err, nil)
|
|
}
|
|
|
|
glossary, err := schema.ParseGlossaryYAML(glossaryBytes)
|
|
if err != nil {
|
|
return fail("glossary_schema", err, nil)
|
|
}
|
|
|
|
if err := runDir.WriteSourceTranscript(sourceTranscript, transcriptBytes); err != nil {
|
|
_ = runDir.WriteErrorLog(fmt.Sprintf("source_artifact: %v", err))
|
|
}
|
|
|
|
canonical := sourceToCanonicalTranscript(sourceTranscript)
|
|
normalizer := normalization.NewNormalizer(normalization.NormalizationConfig{
|
|
MaxSegmentGap: inv.Config.Normalization.MaxSegmentGap,
|
|
EllipsisGap: inv.Config.Normalization.EllipsisGap,
|
|
MaxSegmentDuration: inv.Config.Normalization.MaxSegmentDuration,
|
|
MaxSegmentTokens: inv.Config.Normalization.MaxSegmentTokens,
|
|
})
|
|
|
|
normalizedTranscript, normSummary := normalizer.Normalize(canonical)
|
|
|
|
if err := runDir.WriteNormalizedTranscript(normalizedTranscript); err != nil {
|
|
_ = runDir.WriteErrorLog(fmt.Sprintf("normalized_artifact: %v", err))
|
|
}
|
|
if err := runDir.WriteNormalizationSummary(normSummary); err != nil {
|
|
_ = runDir.WriteErrorLog(fmt.Sprintf("normalization_summary: %v", err))
|
|
}
|
|
|
|
// Compute chunks after normalization
|
|
chunker := chunking.NewChunker(chunking.ChunkingConfig{
|
|
MaxSectionTokens: inv.Config.Chunking.MaxSectionTokens,
|
|
MinSectionTokens: inv.Config.Chunking.MinSectionTokens,
|
|
TargetSections: inv.Config.Chunking.TargetSections,
|
|
})
|
|
|
|
sections, chunkErr := chunker.ChunkTranscript(normalizedTranscript)
|
|
if chunkErr != nil {
|
|
return fail("chunking", chunkErr, nil)
|
|
}
|
|
|
|
chunkConfig := chunking.ChunkingConfig{
|
|
MaxSectionTokens: inv.Config.Chunking.MaxSectionTokens,
|
|
MinSectionTokens: inv.Config.Chunking.MinSectionTokens,
|
|
TargetSections: inv.Config.Chunking.TargetSections,
|
|
}
|
|
chunkSummary := chunking.ComputeSummary(sections, chunkConfig)
|
|
chunkDetailedSummary := chunking.ComputeDetailedSummary(sections, chunkConfig)
|
|
|
|
if err := runDir.WriteChunkingSummary(&chunkDetailedSummary); err != nil {
|
|
_ = runDir.WriteErrorLog(fmt.Sprintf("chunking_summary: %v", err))
|
|
}
|
|
|
|
workingTranscript := normalizedTranscript
|
|
var runOutput *runner.RunOutput
|
|
observations := llm.NewObservationCollector()
|
|
moduleFactory := processModuleFactory
|
|
if moduleFactory == nil {
|
|
moduleFactory = modules.NewFactory(modules.Dependencies{
|
|
Config: &inv.Config,
|
|
Glossary: glossary,
|
|
DiagnosticsDir: runDir.Path(),
|
|
})
|
|
}
|
|
if moduleFactory != nil {
|
|
proposalLLMClient := processProposalLLMClient
|
|
validationLLMClient := processValidationLLMClient
|
|
if inv.LLMRuntime == nil && (proposalLLMClient == nil || validationLLMClient == nil) {
|
|
return fail("runner_setup", fmt.Errorf("LLM runtime is required"), nil)
|
|
}
|
|
if proposalLLMClient == nil {
|
|
proposalLLMClient, err = inv.LLMRuntime.NewRoleClient("proposal", observations.Hooks())
|
|
if err != nil {
|
|
return fail("runner_setup", err, nil)
|
|
}
|
|
}
|
|
if validationLLMClient == nil {
|
|
validationLLMClient, err = inv.LLMRuntime.NewRoleClient("validation", observations.Hooks())
|
|
if err != nil {
|
|
return fail("runner_setup", err, nil)
|
|
}
|
|
}
|
|
|
|
moduleSpecs, err := contracts.ResolveModuleRunSpecs(inv.Config.Pipeline.Modules)
|
|
if err != nil {
|
|
return fail("runner_setup", err, nil)
|
|
}
|
|
|
|
runCtx, cancelRun := processRunnerContext()
|
|
defer cancelRun()
|
|
runnerResult, runErr := runner.New(moduleFactory).Run(runCtx, runner.RunInput{
|
|
Config: &inv.Config,
|
|
Transcript: normalizedTranscript,
|
|
Glossary: glossary,
|
|
ModuleSpecs: moduleSpecs,
|
|
|
|
ProposalLLMClient: proposalLLMClient,
|
|
ProposalDiagnosticsDir: runDir.Path(),
|
|
ValidationLLMClient: validationLLMClient,
|
|
ValidationDiagnosticsDir: runDir.Path(),
|
|
})
|
|
runnerResult.Observations = observations.Snapshot()
|
|
runnerResult.LLMSummary = llm.Summarize(runnerResult.Observations)
|
|
runOutput = &runnerResult
|
|
if runErr != nil {
|
|
return fail("runner_execution", runErr, runOutput)
|
|
}
|
|
workingTranscript = runnerResult.FinalTranscript
|
|
}
|
|
|
|
encoderDef, err := outputschema.Resolve(inv.Config.Output.Schema)
|
|
if err != nil {
|
|
return fail("output_schema", err, runOutput)
|
|
}
|
|
outputBytes, err := encoderDef.Encoder(workingTranscript)
|
|
if err != nil {
|
|
return fail("serialization", err, runOutput)
|
|
}
|
|
|
|
if strings.TrimSpace(inv.OutputPath) != "" {
|
|
if err := coreio.WriteFile(inv.OutputPath, outputBytes); err != nil {
|
|
return fail("output_write", err, runOutput)
|
|
}
|
|
return normSummary, &chunkSummary, runOutput, runDir, nil
|
|
}
|
|
|
|
if _, err := stdout.Write(outputBytes); err != nil {
|
|
return fail("stdout_write", err, runOutput)
|
|
}
|
|
|
|
return normSummary, &chunkSummary, runOutput, runDir, nil
|
|
}
|
|
|
|
func sourceToCanonicalTranscript(source *schema.SourceTranscript) *schema.Transcript {
|
|
segments := make([]schema.Segment, len(source.Segments))
|
|
for i, s := range source.Segments {
|
|
id := i + 1
|
|
if s.ID != nil {
|
|
id = *s.ID
|
|
}
|
|
segments[i] = schema.Segment{
|
|
ID: id,
|
|
Speaker: s.Speaker,
|
|
Start: s.Start,
|
|
End: s.End,
|
|
Text: s.Text,
|
|
Categories: s.Categories,
|
|
}
|
|
}
|
|
return &schema.Transcript{Segments: segments}
|
|
}
|
|
|
|
// Run executes the Audita CLI with the provided arguments and streams.
|
|
func Run(args []string, stdout, stderr io.Writer) int {
|
|
if len(args) == 0 {
|
|
writeRootUsage(stdout)
|
|
return 0
|
|
}
|
|
if len(args) == 2 && args[0] == "help" {
|
|
switch args[1] {
|
|
case "process":
|
|
writeProcessUsage(stdout)
|
|
return 0
|
|
case "config":
|
|
writeConfigUsage(stdout)
|
|
return 0
|
|
}
|
|
}
|
|
|
|
if isHelpCommand(args) {
|
|
writeRootUsage(stdout)
|
|
return 0
|
|
}
|
|
|
|
if args[0] == "process" {
|
|
return runProcess(args[1:], stdout, stderr)
|
|
}
|
|
if args[0] == "config" {
|
|
return runConfig(args[1:], stdout, stderr)
|
|
}
|
|
|
|
fmt.Fprintf(stderr, "audita: unknown command %q\n\n", args[0])
|
|
writeRootUsage(stderr)
|
|
return 2
|
|
}
|
|
|
|
func runProcess(args []string, stdout, stderr io.Writer) int {
|
|
startedAt := time.Now().UTC()
|
|
input, help, err := parseConfigInput("process", args, stderr)
|
|
if err != nil {
|
|
fmt.Fprintf(stderr, "audita process: %s\n", configInputError(err))
|
|
return 2
|
|
}
|
|
if help {
|
|
writeProcessUsage(stdout)
|
|
return 0
|
|
}
|
|
selected, err := loadConfigInput(input, "process")
|
|
if err != nil {
|
|
fmt.Fprintf(stderr, "audita process: %s\n", configInputError(err))
|
|
return 2
|
|
}
|
|
llmRuntime, err := llm.NewRuntime(context.Background(), selected.Result.Config, selected.Path, nil)
|
|
if err != nil {
|
|
fmt.Fprintf(stderr, "audita process: %s\n", llm.RedactError(err, selected.Result.Config))
|
|
if llm.IsAssetError(err) {
|
|
return 1
|
|
}
|
|
return 2
|
|
}
|
|
version := selected.Result.Config.Version
|
|
explicitModules := false
|
|
for _, override := range input.Overrides {
|
|
if override.Path.String() == ck.Keys("pipeline", "modules").String() {
|
|
explicitModules = true
|
|
}
|
|
}
|
|
|
|
inv := processInvocation{
|
|
TranscriptPath: input.TranscriptPath,
|
|
GlossaryPath: input.GlossaryPath,
|
|
OutputPath: input.OutputPath,
|
|
ReportJSONPath: input.ReportPath,
|
|
Config: selected.Result.Config,
|
|
ConfigResult: selected.Result,
|
|
LLMRuntime: llmRuntime,
|
|
ConfigPath: selected.Path,
|
|
ConfigSource: selected.Source,
|
|
ConfigVersion: &version,
|
|
ExplicitModules: explicitModules,
|
|
}
|
|
|
|
normSummary, chunkSummary, runOutput, runDir, runErr := processRunner(inv, stdout)
|
|
completedAt := time.Now().UTC()
|
|
|
|
if runErr != nil {
|
|
if runDir != nil && runOutput != nil {
|
|
|
|
_ = runDir.WriteJSONArtifact(diagnostics.ArtifactCorrectionLedger, processreport.BuildCorrectionLedger(processreport.CorrectionLedgerInput{
|
|
RunDirectoryPath: runDir.Path(),
|
|
RunOutput: runOutput,
|
|
}))
|
|
}
|
|
errorPhase, errorMessage := extractErrorPhase(runErr)
|
|
report := processreport.Build(processReportInput("failed", inv, runDir, startedAt, completedAt, errorMessage, errorPhase, nil, nil, runOutput))
|
|
|
|
if strings.TrimSpace(inv.ReportJSONPath) != "" {
|
|
if err := reporting.WriteProcessReport(inv.ReportJSONPath, report); err != nil {
|
|
fmt.Fprintf(stderr, "audita process: %v\n", err)
|
|
}
|
|
}
|
|
|
|
if runDir != nil {
|
|
_ = runDir.WriteReport(report)
|
|
_ = runDir.ApplyRetention(diagnostics.RetentionDecisionInput{
|
|
RunSucceeded: false,
|
|
})
|
|
}
|
|
|
|
fmt.Fprintf(stderr, "audita process: %v\n", runErr)
|
|
if runDir != nil {
|
|
fmt.Fprintf(stderr, "audita process: diagnostics: %s\n", runDir.Path())
|
|
}
|
|
return 1
|
|
}
|
|
|
|
if runDir != nil && runOutput != nil {
|
|
|
|
_ = runDir.WriteJSONArtifact(diagnostics.ArtifactCorrectionLedger, processreport.BuildCorrectionLedger(processreport.CorrectionLedgerInput{
|
|
RunDirectoryPath: runDir.Path(),
|
|
RunOutput: runOutput,
|
|
}))
|
|
}
|
|
|
|
report := processreport.Build(processReportInput("success", inv, runDir, startedAt, completedAt, "", "", normSummary, chunkSummary, runOutput))
|
|
|
|
if strings.TrimSpace(inv.ReportJSONPath) != "" {
|
|
if err := reporting.WriteProcessReport(inv.ReportJSONPath, report); err != nil {
|
|
if runDir != nil {
|
|
_ = runDir.WriteErrorLog(fmt.Sprintf("report_write: %v", err))
|
|
_ = runDir.ApplyRetention(diagnostics.RetentionDecisionInput{
|
|
RunSucceeded: false,
|
|
})
|
|
}
|
|
fmt.Fprintf(stderr, "audita process: %v\n", err)
|
|
return 1
|
|
}
|
|
}
|
|
|
|
if runDir != nil {
|
|
_ = runDir.WriteReport(report)
|
|
if err := runDir.ApplyRetention(diagnostics.RetentionDecisionInput{
|
|
RunSucceeded: true,
|
|
HasSkippedCorrections: processreport.HasSkippedCorrections(runOutput),
|
|
}); err != nil {
|
|
fmt.Fprintf(stderr, "audita process: failed to apply work-dir retention: %v\n", err)
|
|
return 1
|
|
}
|
|
}
|
|
|
|
return 0
|
|
}
|
|
|
|
func runConfig(args []string, stdout, stderr io.Writer) int {
|
|
if len(args) == 0 || isHelpCommand(args) || args[0] == "--help" || args[0] == "-h" {
|
|
writeConfigUsage(stdout)
|
|
return 0
|
|
}
|
|
|
|
switch args[0] {
|
|
case "validate":
|
|
return runConfigValidate(args[1:], stdout, stderr)
|
|
case "print-effective":
|
|
return runConfigPrintEffective(args[1:], stdout, stderr)
|
|
default:
|
|
fmt.Fprintf(stderr, "audita config: unknown command %q\n\n", args[0])
|
|
writeConfigUsage(stderr)
|
|
return 2
|
|
}
|
|
}
|
|
|
|
func runConfigValidate(args []string, stdout, stderr io.Writer) int {
|
|
input, help, err := parseConfigInput("validate", args, stderr)
|
|
if err != nil {
|
|
fmt.Fprintf(stderr, "audita config validate: %s\n", configInputError(err))
|
|
return 2
|
|
}
|
|
if help {
|
|
writeConfigValidateUsage(stdout)
|
|
return 0
|
|
}
|
|
selected, err := loadConfigInput(input, "validate")
|
|
if err != nil {
|
|
fmt.Fprintf(stderr, "audita config validate: %s\n", configInputError(err))
|
|
return 2
|
|
}
|
|
if _, err := llm.NewRuntime(context.Background(), selected.Result.Config, selected.Path, nil); err != nil {
|
|
fmt.Fprintf(stderr, "audita config validate: %s\n", llm.RedactError(err, selected.Result.Config))
|
|
if llm.IsAssetError(err) {
|
|
return 1
|
|
}
|
|
return 2
|
|
}
|
|
fmt.Fprintln(stdout, "config is valid")
|
|
return 0
|
|
}
|
|
|
|
func runConfigPrintEffective(args []string, stdout, stderr io.Writer) int {
|
|
input, help, err := parseConfigInput("print-effective", args, stderr)
|
|
if err != nil {
|
|
fmt.Fprintf(stderr, "audita config print-effective: %s\n", configInputError(err))
|
|
return 2
|
|
}
|
|
if help {
|
|
writeConfigPrintEffectiveUsage(stdout)
|
|
return 0
|
|
}
|
|
selected, err := loadConfigInput(input, "print-effective")
|
|
if err != nil {
|
|
fmt.Fprintf(stderr, "audita config print-effective: %s\n", configInputError(err))
|
|
return 2
|
|
}
|
|
llmRuntime, err := llm.NewRuntime(context.Background(), selected.Result.Config, selected.Path, nil)
|
|
if err != nil {
|
|
fmt.Fprintf(stderr, "audita config print-effective: %s\n", llm.RedactError(err, selected.Result.Config))
|
|
if llm.IsAssetError(err) {
|
|
return 1
|
|
}
|
|
return 2
|
|
}
|
|
if input.View == "settings" {
|
|
err = selected.Result.WriteEffective(stdout)
|
|
} else {
|
|
var output []byte
|
|
if input.View == "profiles" {
|
|
output, err = llmRuntime.SelectedProfilesYAML()
|
|
} else {
|
|
output, err = llm.ExplanationYAML(selected.Result)
|
|
}
|
|
if err == nil {
|
|
_, err = stdout.Write(output)
|
|
}
|
|
}
|
|
if err != nil {
|
|
fmt.Fprintf(stderr, "audita config print-effective: %v\n", err)
|
|
return 1
|
|
}
|
|
return 0
|
|
}
|
|
|
|
func extractErrorPhase(err error) (phase string, message string) {
|
|
msg := err.Error()
|
|
if strings.Contains(msg, ": ") {
|
|
parts := strings.SplitN(msg, ": ", 2)
|
|
if len(parts) == 2 {
|
|
return parts[0], parts[1]
|
|
}
|
|
}
|
|
return "", msg
|
|
}
|
|
|
|
func processReportInput(status string, inv processInvocation, runDir *diagnostics.RunDirectory, startedAt, completedAt time.Time, errorMessage string, errorPhase string, normalizationSummary *normalization.NormalizationSummary, chunkingSummary *chunking.Summary, runOutput *runner.RunOutput) processreport.BuildInput {
|
|
runDirectoryPath := ""
|
|
if runDir != nil {
|
|
runDirectoryPath = runDir.Path()
|
|
}
|
|
return processreport.BuildInput{
|
|
Status: status,
|
|
TranscriptPath: inv.TranscriptPath,
|
|
GlossaryPath: inv.GlossaryPath,
|
|
OutputPath: inv.OutputPath,
|
|
Modules: inv.Config.Pipeline.Modules,
|
|
OutputSchema: inv.Config.Output.Schema,
|
|
ConfigVersion: inv.ConfigVersion,
|
|
StartedAt: startedAt,
|
|
CompletedAt: completedAt,
|
|
ErrorMessage: errorMessage,
|
|
ErrorPhase: errorPhase,
|
|
RunDirectoryPath: runDirectoryPath,
|
|
NormalizationSummary: normalizationSummary,
|
|
ChunkingSummary: chunkingSummary,
|
|
RunOutput: runOutput,
|
|
}
|
|
}
|
|
|
|
func isHelpCommand(args []string) bool {
|
|
if len(args) == 0 {
|
|
return false
|
|
}
|
|
if len(args) == 1 {
|
|
switch args[0] {
|
|
case "help", "-h", "--help":
|
|
return true
|
|
}
|
|
}
|
|
if len(args) == 2 && args[0] == "help" {
|
|
switch args[1] {
|
|
case "process":
|
|
return true
|
|
}
|
|
}
|
|
return false
|
|
}
|
|
|
|
func writeRootUsage(w io.Writer) {
|
|
fmt.Fprintln(w, "Audita is a transcript processing CLI.")
|
|
fmt.Fprintln(w)
|
|
fmt.Fprintln(w, "Usage:")
|
|
fmt.Fprintln(w, " audita <command> [options]")
|
|
fmt.Fprintln(w)
|
|
fmt.Fprintln(w, "Commands:")
|
|
fmt.Fprintln(w, " process Process a transcript JSON file")
|
|
fmt.Fprintln(w, " config Validate and inspect config")
|
|
fmt.Fprintln(w)
|
|
fmt.Fprintln(w, "Example:")
|
|
fmt.Fprintln(w, " audita process transcript.json --glossary glossary.yaml --output corrected.json")
|
|
}
|
|
|
|
func writeConfigUsage(w io.Writer) {
|
|
fmt.Fprintln(w, "Validate and inspect Audita config.")
|
|
fmt.Fprintln(w)
|
|
fmt.Fprintln(w, "Usage:")
|
|
fmt.Fprintln(w, " audita config <command> [flags]")
|
|
fmt.Fprintln(w)
|
|
fmt.Fprintln(w, "Commands:")
|
|
fmt.Fprintln(w, " validate Validate a versioned YAML config file")
|
|
fmt.Fprintln(w, " print-effective Print redacted effective settings YAML")
|
|
}
|
|
|
|
func writeConfigValidateUsage(w io.Writer) {
|
|
fmt.Fprintln(w, "Validate a versioned YAML config file.")
|
|
fmt.Fprintln(w)
|
|
fmt.Fprintln(w, "Usage:")
|
|
fmt.Fprintln(w, " audita config validate --config <path> [--overlay <name>] [setting flags]")
|
|
}
|
|
|
|
func writeConfigPrintEffectiveUsage(w io.Writer) {
|
|
fmt.Fprintln(w, "Print redacted effective settings YAML.")
|
|
fmt.Fprintln(w)
|
|
fmt.Fprintln(w, "Usage:")
|
|
fmt.Fprintln(w, " audita config print-effective [--config <path>] [--overlay <name>] [setting flags]")
|
|
}
|
|
|
|
func writeProcessUsage(w io.Writer) {
|
|
fmt.Fprintln(w, "Process a transcript JSON file.")
|
|
fmt.Fprintln(w)
|
|
fmt.Fprintln(w, "Usage:")
|
|
fmt.Fprintln(w, " audita process <transcript.json> [flags]")
|
|
fmt.Fprintln(w)
|
|
fmt.Fprintln(w, "Flags:")
|
|
for _, name := range []string{
|
|
"config", "overlay", "glossary", "output", "report-json",
|
|
"proposal-profile", "validation-profile", "modules", "output-schema",
|
|
"validation-max-prompt-tokens", "target-sections", "max-section-tokens", "min-section-tokens",
|
|
"normalize-max-segment-gap", "normalize-ellipsis-gap", "normalize-max-segment-duration", "normalize-max-segment-tokens",
|
|
"glossary-confidence-threshold", "homophones-confidence-threshold", "spoken-word-confidence-threshold", "grammar-confidence-threshold",
|
|
"transcript-description", "work-dir", "work-dir-retention",
|
|
} {
|
|
fmt.Fprintf(w, " --%s\n", name)
|
|
}
|
|
fmt.Fprintln(w)
|
|
fmt.Fprintln(w, "Example:")
|
|
fmt.Fprintln(w, " audita process transcript.json --glossary glossary.yaml --output corrected.json")
|
|
}
|