Finish maintained consumer examples

This commit is contained in:
2026-10-11 01:50:48 +00:00
parent f7174a078e
commit e89cc2220f
17 changed files with 291 additions and 3097 deletions

View File

@@ -5,10 +5,13 @@ import (
"errors"
"fmt"
"os"
"strconv"
commandkit "gitea.maximumdirect.net/eric/CommandKit"
"gitea.maximumdirect.net/eric/CommandKit/integrations/ckconfig"
"gitea.maximumdirect.net/eric/CommandKit/integrations/ckprompt"
configkit "gitea.maximumdirect.net/eric/ConfigKit"
"gitea.maximumdirect.net/eric/promptkit"
promptkit "gitea.maximumdirect.net/eric/promptkit"
)
type campaign struct {
@@ -23,20 +26,17 @@ type appConfiguration struct {
Campaigns map[string]campaign `yaml:"campaigns"`
}
type invocationCache struct {
type inspectionInput struct {
Campaign commandkit.Supplied[string]
Limit commandkit.Supplied[int]
}
// runCache belongs to one invocation and is shared only where the application
// chooses to pass it to its loaders.
type runCache struct {
application *configkit.Result[appConfiguration]
}
type configContext struct {
Cache *invocationCache
Campaign commandkit.Supplied[string]
}
type definitionContext struct {
Cache *invocationCache
Campaign commandkit.Supplied[string]
}
type restoreInput struct {
Campaign commandkit.Supplied[string]
Session string
@@ -48,16 +48,19 @@ type session struct {
Summary string
}
type sessionStore struct {
active string
records map[string]session
func campaignSelector() commandkit.Flag[*inspectionInput] {
return commandkit.ValueFlag(commandkit.FlagMeta{Name: "campaign", Usage: "Select campaign inputs."}, (*string)(nil), parseString,
func(input **inspectionInput, value commandkit.Supplied[string]) { (*input).Campaign = value })
}
func loadApplicationConfig(_ context.Context, _ commandkit.Selection, cache *invocationCache) (*configkit.Result[appConfiguration], error) {
func loadApplicationConfig(ctx context.Context, _ ckconfig.Selection, _ *inspectionInput, cache *runCache) (*configkit.Result[appConfiguration], error) {
if err := ctx.Err(); err != nil {
return nil, err
}
if cache != nil && cache.application != nil {
return cache.application, nil
}
result, err := configkit.Load[appConfiguration](configkit.Mapping("composed app config", map[string]any{
result, err := configkit.Load[appConfiguration](configkit.Mapping("composed application settings", map[string]any{
"default_campaign": "spring",
"campaigns": map[string]any{
"spring": map[string]any{"prompt_id": "briefing", "prompt_version": "1", "profile_id": "spring", "model": "spring-model"},
@@ -70,24 +73,12 @@ func loadApplicationConfig(_ context.Context, _ commandkit.Selection, cache *inv
return result, err
}
func selectedCampaign(configuration appConfiguration, supplied commandkit.Supplied[string]) (string, campaign, error) {
name := configuration.DefaultCampaign
if supplied.Set {
name = supplied.Value
}
value, ok := configuration.Campaigns[name]
if !ok {
return "", campaign{}, fmt.Errorf("unknown campaign %q", name)
}
return name, value, nil
}
func loadPromptEngine(ctx context.Context, selection commandkit.Selection, cache *invocationCache, selected commandkit.Supplied[string]) (*promptkit.Engine, error) {
application, err := loadApplicationConfig(ctx, selection, cache)
func loadPromptEngine(ctx context.Context, selection ckconfig.Selection, input *inspectionInput, cache *runCache) (*promptkit.Engine, error) {
application, err := loadApplicationConfig(ctx, selection, input, cache)
if err != nil {
return nil, err
}
name, chosen, err := selectedCampaign(application.Config, selected)
name, chosen, err := selectedCampaign(application.Config, input.Campaign)
if err != nil {
return nil, err
}
@@ -111,104 +102,93 @@ func loadPromptEngine(ctx context.Context, selection commandkit.Selection, cache
return promptkit.NewEngine(promptkit.Config{Sources: promptkit.ConfigurationSources{Main: &configkit.Input{Source: engineConfig}}})
}
func campaignSelector[C any](set func(*C, commandkit.Supplied[string])) commandkit.Selector[C] {
return commandkit.Selector[C]{
Binding: commandkit.ValueFlag[C](commandkit.FlagMeta{Name: "campaign", Usage: "Select a configured campaign."}, nil, func(value string) (string, error) { return value, nil }, set),
Scopes: []string{"app", "promptkit"},
func selectedCampaign(configuration appConfiguration, supplied commandkit.Supplied[string]) (string, campaign, error) {
name := configuration.DefaultCampaign
if supplied.Set {
name = supplied.Value
}
chosen, ok := configuration.Campaigns[name]
if !ok {
return "", campaign{}, fmt.Errorf("unknown campaign %q", name)
}
return name, chosen, nil
}
func newApp() (*commandkit.App, error) {
app, err := commandkit.New(commandkit.Identity{Name: "composed-example", Version: "1.0"})
if err != nil {
return nil, err
}
appScope, err := commandkit.NewConfigKitScope[configContext, appConfiguration]("app", "Application campaigns.", func(ctx context.Context, selection commandkit.Selection, input configContext) (*configkit.Result[appConfiguration], error) {
return loadApplicationConfig(ctx, selection, input.Cache)
})
if err != nil {
return nil, err
}
promptScope, err := commandkit.NewPromptKitScope(func(ctx context.Context, selection commandkit.Selection, input configContext) (*promptkit.Engine, error) {
return loadPromptEngine(ctx, selection, input.Cache, input.Campaign)
})
if err != nil {
return nil, err
}
configSuite := commandkit.ConfigSuite[configContext]{
NewContext: func() configContext { return configContext{Cache: &invocationCache{}} },
Selectors: []commandkit.Selector[configContext]{campaignSelector(func(input *configContext, value commandkit.Supplied[string]) {
input.Campaign = value
})},
Scopes: []commandkit.ConfigScope[configContext]{appScope, promptScope},
}
if err := commandkit.RegisterConfig(app, configSuite); err != nil {
return nil, err
}
limitDefault := 0
limitFlag := commandkit.ValueFlag(commandkit.FlagMeta{Name: "limit", Usage: "Override the application item limit."}, &limitDefault, strconv.Atoi,
func(input **inspectionInput, value commandkit.Supplied[int]) { (*input).Limit = value })
inputFactory := func() *inspectionInput { return &inspectionInput{} }
stateFactory := func() *runCache { return &runCache{} }
definitionSuite, err := commandkit.NewPromptKitSuite(func(ctx context.Context, selection commandkit.Selection, input definitionContext) (*promptkit.Engine, error) {
return loadPromptEngine(ctx, selection, input.Cache, input.Campaign)
appScope := ckconfig.FromConfigKit("app", "Application settings.", loadApplicationConfig)
engineScope := ckprompt.ConfigScope(loadPromptEngine)
configCommand := ckconfig.Command(ckconfig.Suite[*inspectionInput, *runCache]{
NewInput: inputFactory,
NewState: stateFactory,
CheckInput: func(scope string, _ ckconfig.Selection, input *inspectionInput) error {
if scope == "app" && input.Campaign.Set && !input.Limit.Set {
return errors.New("application campaign inspection requires --limit")
}
return nil
},
Selectors: []ckconfig.Selector[*inspectionInput]{
{Binding: campaignSelector(), Scopes: []string{"app", "promptkit"}},
{Binding: limitFlag, Scopes: []string{"app"}},
},
Scopes: []ckconfig.Scope[*inspectionInput, *runCache]{appScope, engineScope},
})
if err != nil {
return nil, err
}
definitionSuite.NewContext = func() definitionContext { return definitionContext{Cache: &invocationCache{}} }
definitionSuite.Selectors = []commandkit.Selector[definitionContext]{campaignSelector(func(input *definitionContext, value commandkit.Supplied[string]) {
input.Campaign = value
})}
if err := commandkit.RegisterPromptKit(app, definitionSuite); err != nil {
return nil, err
}
store := &sessionStore{records: map[string]session{"session-42": {ID: "session-42", Campaign: "spring", Summary: "A synthetic planning session."}}}
restore, err := commandkit.NewCommand(commandkit.CommandSpec[restoreInput]{
definitions := ckprompt.FromEngine(loadPromptEngine)
definitions.NewInput = inputFactory
definitions.NewState = stateFactory
definitions.Selectors = []commandkit.Flag[*inspectionInput]{campaignSelector()}
definitionCommand := ckprompt.Command(definitions)
store := map[string]session{
"session-42": {ID: "session-42", Campaign: "spring", Summary: "A synthetic planning session."},
}
restore := commandkit.NewCommand(commandkit.CommandSpec[restoreInput]{
Name: "restore",
Summary: "Restore one saved session.",
Flags: []commandkit.Flag[restoreInput]{commandkit.ValueFlag[restoreInput](commandkit.FlagMeta{Name: "campaign", Usage: "Campaign owning the session."}, nil, func(value string) (string, error) { return value, nil }, func(input *restoreInput, value commandkit.Supplied[string]) {
input.Campaign = value
})},
Arguments: []commandkit.Argument[restoreInput]{commandkit.ValueArgument[restoreInput](commandkit.ArgumentMeta{Name: "ID"}, true, func(value string) (string, error) { return value, nil }, func(input *restoreInput, value commandkit.Supplied[string]) {
input.Session = value.Value
})},
Summary: "Restore a saved session.",
Flags: []commandkit.Flag[restoreInput]{commandkit.ValueFlag(commandkit.FlagMeta{Name: "campaign", Usage: "Campaign owning the session."}, (*string)(nil), parseString,
func(input *restoreInput, value commandkit.Supplied[string]) { input.Campaign = value })},
Arguments: []commandkit.Argument[restoreInput]{commandkit.ValueArgument(commandkit.ArgumentMeta{Name: "ID", Usage: "Session identifier."}, true, parseString,
func(input *restoreInput, value commandkit.Supplied[string]) { input.Session = value.Value })},
Run: func(invocation commandkit.Invocation, input restoreInput) commandkit.Outcome {
return restoreSession(invocation, store, input)
if err := invocation.Context.Err(); err != nil {
return commandkit.Failure(err)
}
application, err := loadApplicationConfig(invocation.Context, ckconfig.Selection{}, nil, nil)
if err != nil {
return commandkit.Failure(err)
}
name, _, err := selectedCampaign(application.Config, input.Campaign)
if err != nil {
return commandkit.Failure(err)
}
record, ok := store[input.Session]
if !ok {
return commandkit.Outcome{Kind: commandkit.OutcomeDomain, Status: 4, Domain: "session_not_found", Cause: errors.New("saved session was not found")}
}
if record.Campaign != name {
return commandkit.Outcome{Kind: commandkit.OutcomeDomain, Status: 3, Domain: "campaign_mismatch", Cause: fmt.Errorf("session belongs to campaign %q", record.Campaign)}
}
if _, err := fmt.Fprintf(invocation.Streams.Out, "restored %s: %s\n", record.ID, record.Summary); err != nil {
return commandkit.Failure(err)
}
return commandkit.Success()
},
})
if err != nil {
return nil, err
}
sessionGroup, err := commandkit.Group("session", "Manage saved sessions.", restore)
if err != nil {
return nil, err
}
if err := app.Register(sessionGroup); err != nil {
return nil, err
}
return app, nil
return commandkit.New(
commandkit.Identity{Name: "composed-example", Version: "1.0"},
configCommand,
definitionCommand,
commandkit.Group("session", "Manage saved sessions.", restore),
)
}
func restoreSession(invocation commandkit.Invocation, store *sessionStore, input restoreInput) commandkit.Outcome {
application, err := loadApplicationConfig(invocation.Context, commandkit.Selection{}, nil)
if err != nil {
return commandkit.Failure(err)
}
name, _, err := selectedCampaign(application.Config, input.Campaign)
if err != nil {
return commandkit.Failure(err)
}
record, ok := store.records[input.Session]
if !ok {
return commandkit.Outcome{Kind: commandkit.OutcomeDomain, Status: 4, Domain: "session_not_found", Cause: errors.New("saved session was not found")}
}
if record.Campaign != name {
return commandkit.Outcome{Kind: commandkit.OutcomeDomain, Status: 3, Domain: "campaign_mismatch", Cause: fmt.Errorf("session belongs to campaign %q", record.Campaign)}
}
store.active = record.ID
if _, err := fmt.Fprintf(invocation.Streams.Out, "restored %s: %s\n", record.ID, record.Summary); err != nil {
return commandkit.Failure(err)
}
return commandkit.Success()
}
func parseString(raw string) (string, error) { return raw, nil }
func main() {
app, err := newApp()