Update the composed PromptKit consumer

This commit is contained in:
2026-11-07 05:01:30 +00:00
parent 42af1da142
commit 1289868ed0
4 changed files with 236 additions and 30 deletions

View File

@@ -6,6 +6,7 @@ import (
"fmt"
"io"
"os"
"reflect"
"strconv"
"go.maximumdirect.net/ckconfig"
@@ -31,16 +32,16 @@ type inspectionInput struct {
Limit commandkit.Supplied[int]
}
type applicationCacheKey struct {
config commandkit.Supplied[string]
overlay commandkit.Supplied[string]
campaign commandkit.Supplied[string]
type applicationCacheEntry struct {
selection ckconfig.Selection
campaign commandkit.Supplied[string]
result *configkit.Result[appConfiguration]
}
// runCache belongs to one invocation and is shared only where the application
// chooses to pass it to its loaders.
type runCache struct {
applications map[applicationCacheKey]*configkit.Result[appConfiguration]
applications []applicationCacheEntry
llmClient promptkit.LLMClient
}
@@ -60,6 +61,12 @@ type restoreInput struct {
Session string
}
type requestInputs struct {
Execution ckprompt.ExecutionInput `json:"execution"`
Resources ckprompt.ResourceInput `json:"resources"`
Inputs ckprompt.PromptInputs `json:"inputs"`
}
type session struct {
ID string
Campaign string
@@ -81,10 +88,11 @@ func loadApplicationConfig(ctx context.Context, selection ckconfig.Selection, in
if input != nil {
campaignInput = input.Campaign
}
key := applicationCacheKey{config: selection.Config, overlay: selection.Overlay, campaign: campaignInput}
if cache != nil {
if cached, ok := cache.applications[key]; ok {
return cached, nil
for _, cached := range cache.applications {
if reflect.DeepEqual(cached.selection, selection) && cached.campaign == campaignInput {
return cached.result, nil
}
}
}
source := configkit.Mapping("composed application settings", map[string]any{
@@ -105,12 +113,10 @@ func loadApplicationConfig(ctx context.Context, selection ckconfig.Selection, in
if campaignInput.Set {
options.Overrides = []configkit.Override{{Path: configkit.Keys("default_campaign"), Value: campaignInput.Value, Flag: "--campaign"}}
}
options.Overrides = append(options.Overrides, selection.Overrides...)
result, err := configkit.Load(source, options)
if err == nil && result != nil && cache != nil {
if cache.applications == nil {
cache.applications = make(map[applicationCacheKey]*configkit.Result[appConfiguration])
}
cache.applications[key] = result
cache.applications = append(cache.applications, applicationCacheEntry{selection: selection, campaign: campaignInput, result: result})
}
return result, err
}
@@ -224,6 +230,7 @@ func newAppWithEngineLoader(
stateFactory := func() *runCache { return &runCache{llmClient: client} }
appScope := ckconfig.FromConfigKit("app", "Application settings.", loadApplicationConfig)
appScope.Features.Overrides = true
engineScope := ckprompt.ConfigScope(engineLoader)
configCommand := ckconfig.Command(ckconfig.Suite[*inspectionInput, *runCache]{
NewInput: inputFactory,
@@ -246,11 +253,28 @@ func newAppWithEngineLoader(
definitions.NewState = stateFactory
definitions.Selectors = []commandkit.Flag[*inspectionInput]{campaignSelector()}
definitions = ckprompt.WithRequestValidation(definitions, engineLoader, buildValidationRequest)
definitions = ckprompt.WithRequestPreparation(definitions, engineLoader,
func(ctx context.Context, seed ckprompt.PreparationRequest, input *inspectionInput, cache *runCache) (promptkit.RunRequest, error) {
return buildValidationRequest(ctx, ckprompt.ValidationRequest{Selection: seed.Selection, Request: seed.Request, Namespaces: seed.Namespaces}, input, cache)
})
definitions = ckprompt.WithSmokeTesting(definitions, engineLoader, nil)
definitions = ckprompt.WithNamespaces(definitions, promptkit.Namespaces{})
if smokeTest != nil {
definitions.SmokeTest = smokeTest
}
definitionDeclarations := ckprompt.Declarations(definitions)
resources := ckprompt.NewResourceFlags(func(input *requestInputs) *ckprompt.ResourceInput { return &input.Resources })
execution := ckprompt.NewExecutionFlags(func(input *requestInputs) *ckprompt.ExecutionInput { return &input.Execution })
inputs := ckprompt.NewPromptInputFlags(func(input *requestInputs) *ckprompt.PromptInputs { return &input.Inputs })
requestFlags := append([]commandkit.Flag[requestInputs]{resources.Prompt, resources.Profile}, execution.All()...)
requestFlags = append(requestFlags, inputs.All()...)
requestInspect := commandkit.NewCommand(commandkit.CommandSpec[requestInputs]{
Name: "inspect", Summary: "Inspect application-owned request inputs.", Flags: requestFlags,
Run: func(invocation commandkit.Invocation, input requestInputs) commandkit.Outcome {
_ = invocation.Reporter().Report(commandkit.Report{Value: input})
return commandkit.Success()
},
})
store := map[string]session{
"session-42": {ID: "session-42", Campaign: "spring", Summary: "A synthetic planning session."},
@@ -294,6 +318,7 @@ func newAppWithEngineLoader(
configCommand,
commandkit.Completion("composed-example"),
commandkit.Group("session", "Manage saved sessions.", restore),
commandkit.Group("request", "Inspect application-owned request inputs.", requestInspect),
commandkit.Alias("list collections", "promptkit list collections"),
commandkit.Alias("promptkit list bundles", "promptkit list collections"),
commandkit.Alias("pk", "promptkit"),