75 lines
2.8 KiB
Go
75 lines
2.8 KiB
Go
package cli
|
|
|
|
import (
|
|
"context"
|
|
"fmt"
|
|
"reflect"
|
|
"strings"
|
|
|
|
"gitea.maximumdirect.net/eric/audita/v3/internal/core/config"
|
|
"gitea.maximumdirect.net/eric/audita/v3/internal/framework/llm"
|
|
"go.maximumdirect.net/ckconfig"
|
|
"go.maximumdirect.net/ckprompt"
|
|
commandkit "go.maximumdirect.net/commandkit"
|
|
ck "go.maximumdirect.net/configkit"
|
|
pk "go.maximumdirect.net/promptkit"
|
|
"go.maximumdirect.net/releasekit/buildinfo"
|
|
)
|
|
|
|
type invocationState struct{ engines []engineEntry }
|
|
type engineEntry struct {
|
|
selection ckconfig.Selection
|
|
engine *pk.Engine
|
|
}
|
|
|
|
func loadApplication(ctx context.Context, selection ckconfig.Selection, _ struct{}, _ *invocationState) (*ck.Result[config.Config], error) {
|
|
if err := ctx.Err(); err != nil {
|
|
return nil, err
|
|
}
|
|
var source ck.Source
|
|
if selection.Config.Set {
|
|
if strings.TrimSpace(selection.Config.Value) == "" {
|
|
return nil, fmt.Errorf("--config requires a nonempty path")
|
|
}
|
|
source = ck.File(selection.Config.Value)
|
|
} else {
|
|
source = ck.SearchConfig("audita", ck.Searches(ck.WorkingDirectory(), ck.UserConfigDirectory(), ck.UnixSystemDirectories()))
|
|
}
|
|
return config.Load(ck.Input{Source: source}, selection.Overlay.Value, selection.Overrides...)
|
|
}
|
|
|
|
func loadPromptEngine(ctx context.Context, selection ckconfig.Selection, input struct{}, state *invocationState) (*pk.Engine, error) {
|
|
if state != nil {
|
|
for _, entry := range state.engines {
|
|
if reflect.DeepEqual(entry.selection, selection) {
|
|
return entry.engine, nil
|
|
}
|
|
}
|
|
}
|
|
loaded, err := loadApplication(ctx, selection, input, state)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
runtime, err := llm.NewRuntime(ctx, loaded, nil)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if state != nil {
|
|
state.engines = append(state.engines, engineEntry{selection: selection, engine: runtime.Engine})
|
|
}
|
|
return runtime.Engine, nil
|
|
}
|
|
|
|
func buildApplication(extra ...commandkit.Declaration) (*commandkit.App, error) {
|
|
appScope := ckconfig.FromConfigKit("app", "Audita application settings.", loadApplication)
|
|
appScope.Features.Overrides = true
|
|
promptScope := ckprompt.ConfigScope(loadPromptEngine)
|
|
configCommand := ckconfig.Command(ckconfig.Suite[struct{}, *invocationState]{NewState: func() *invocationState { return &invocationState{} }, Scopes: []ckconfig.Scope[struct{}, *invocationState]{appScope, promptScope}})
|
|
definitions := ckprompt.WithNamespaces(ckprompt.FromEngine(loadPromptEngine), pk.Namespaces{})
|
|
definitions.NewState = func() *invocationState { return &invocationState{} }
|
|
declarations := []commandkit.Declaration{configCommand, commandkit.Completion("audita"), processCommand()}
|
|
declarations = append(declarations, ckprompt.Declarations(definitions)...)
|
|
declarations = append(declarations, extra...)
|
|
return commandkit.New(commandkit.Identity{Name: "audita", Version: buildinfo.Version()}, declarations...)
|
|
}
|