Refresh operator documentation and CLI help
This commit is contained in:
@@ -1,36 +1,30 @@
|
||||
# CommandKit ckconfig
|
||||
|
||||
`ckconfig` is the optional ConfigKit integration for CommandKit. It adapts
|
||||
ConfigKit loaders and scopes into reusable `commandkit.Command` declarations;
|
||||
installing the integration is explicit and does not modify an application by
|
||||
itself.
|
||||
`ckconfig` adds configuration inspection commands to Go applications that use
|
||||
CommandKit and ConfigKit. Operators can view settings, validate configuration,
|
||||
find where values came from, and compare two configurations.
|
||||
|
||||
The application chooses which commands to install. Importing the package alone
|
||||
does not install commands.
|
||||
|
||||
## Module
|
||||
|
||||
The module path is `go.maximumdirect.net/ckconfig`. Version v0.4.0 requires Go
|
||||
1.27.0 and uses `go.maximumdirect.net/commandkit v0.4.0` and
|
||||
`go.maximumdirect.net/configkit v1.1.0`; it does not import PromptKit. See the
|
||||
[consumer guide](https://gitea.maximumdirect.net/eric/CommandKit/src/branch/main/docs/consumers/guide.md#configkit-scopes)
|
||||
for exact callback and lifetime contracts.
|
||||
The module path is `go.maximumdirect.net/ckconfig`. It does not import PromptKit.
|
||||
See the [consumer guide](https://forge.maximumdirect.net/base-layer/commandkit/src/branch/main/docs/consumers/guide.md#module-selection)
|
||||
for compatible releases and Go requirements.
|
||||
|
||||
## Example
|
||||
|
||||
For one application configuration scope, install the convenience declaration:
|
||||
To inspect one application configuration, pass your loader to `AppCommand`:
|
||||
|
||||
```go
|
||||
app, err := commandkit.New(identity, ckconfig.AppCommand(loadAppConfig))
|
||||
```
|
||||
|
||||
Use `ckconfig.Command(ckconfig.Suite[Input, State]{...})` to define named
|
||||
scopes, selectors, input checks, and state shared by the selected acquisitions
|
||||
or comparison in a config invocation. `ckconfig.FromConfigKit` adapts a typed
|
||||
ConfigKit loader. The `config` command family exposes scope discovery and the
|
||||
validate, show, sources, explain, and diff operations supported by the declared
|
||||
scopes. Source reports include native destination, placement, destination
|
||||
fallback, version evidence, and empty-import selections. Comparison returns
|
||||
ConfigKit's native records to shared report rendering; the
|
||||
[CLI reference](https://gitea.maximumdirect.net/eric/CommandKit/src/branch/main/docs/cli.md#compare-configuration-selections)
|
||||
owns its operator details.
|
||||
For multiple named configurations or application-specific flags, use
|
||||
`ckconfig.Command` with a `ckconfig.Suite`. The
|
||||
[integration guide](https://forge.maximumdirect.net/base-layer/commandkit/src/branch/main/docs/consumers/guide.md#configkit-scopes)
|
||||
explains loader setup, inputs, and shared state.
|
||||
|
||||
The maintained [simple example](examples/simple) shows a complete consumer.
|
||||
The [CommandKit CLI reference](https://gitea.maximumdirect.net/eric/CommandKit/src/branch/main/docs/cli.md#configuration-scopes)
|
||||
|
||||
@@ -1,10 +1,11 @@
|
||||
// Package ckconfig, provided by go.maximumdirect.net/ckconfig, provides
|
||||
// CommandKit's optional ConfigKit v1.1.0 integration, requiring Go 1.27.0. Its
|
||||
// canonical Command declaration installs the standard config command family
|
||||
// through the core commandkit package. Applications can install CommandKit
|
||||
// RoutingRule declarations alongside it through commandkit.New or
|
||||
// App.Register. Source reports preserve ConfigKit's destination, placement,
|
||||
// version, and empty-import evidence. Invocation reporting applies CommandKit's shared
|
||||
// visibility and delivery policy; provider warnings remain independent of
|
||||
// failure explanations. Importing ckconfig alone installs no commands.
|
||||
// Package ckconfig adds commands to view, validate, explain, and compare
|
||||
// ConfigKit configuration in CommandKit applications.
|
||||
//
|
||||
// Use AppCommand for one application configuration loader, or Command with a
|
||||
// Suite for multiple named configurations and application-specific flags.
|
||||
// Install the returned command with commandkit.New or App.Register.
|
||||
// Importing this package alone installs no commands.
|
||||
//
|
||||
// ConfigKit owns configuration loading and interpretation. CommandKit formats
|
||||
// reports and messages using its shared reporting policy.
|
||||
package ckconfig
|
||||
|
||||
@@ -1,37 +1,90 @@
|
||||
# Simple consumer
|
||||
# ConfigKit example
|
||||
|
||||
This example imports `go.maximumdirect.net/ckconfig` and
|
||||
`go.maximumdirect.net/commandkit`; ckconfig v0.4.0 uses core
|
||||
v0.4.0, ConfigKit v1.1.0, and Go 1.27.0. Set `GOWORK=off GOTOOLCHAIN=local`
|
||||
for the commands below.
|
||||
This example adds configuration inspection and a custom `greet` command to a
|
||||
small application. It uses local fixtures and in-memory defaults, with no
|
||||
external services. See [module selection](../../../../docs/consumers/guide.md#module-selection)
|
||||
for dependencies and Go requirements. Use Go 1.27.0 on `PATH` for this checkout.
|
||||
|
||||
Run the maintained example with:
|
||||
From the repository root:
|
||||
|
||||
```sh
|
||||
cd integrations/ckconfig/examples/simple
|
||||
export GOWORK=off GOTOOLCHAIN=local
|
||||
go run . config show
|
||||
go run . config show --config fixtures/before.yml --verbose
|
||||
go run . config show --config fixtures/before.yml --quiet
|
||||
```
|
||||
|
||||
The output includes the default greeting, `Hello`, and schema version 2.
|
||||
This example can run against its declared released dependencies with the
|
||||
workspace disabled.
|
||||
|
||||
## Inspect and override a value
|
||||
|
||||
```sh
|
||||
# Discover configuration paths under schema.
|
||||
go run . config explain --list --under /schema
|
||||
# Change the greeting for this invocation and show just that value.
|
||||
go run . config show --path /greeting --set '/greeting="Hi"'
|
||||
```
|
||||
|
||||
The second command prints `Hi`. It does not edit a file.
|
||||
|
||||
## Compare configurations
|
||||
|
||||
```sh
|
||||
go run . config diff --config fixtures/before.yml --against-config fixtures/after.yml
|
||||
```
|
||||
|
||||
The report includes `changes.greeting: Goodbye`.
|
||||
|
||||
```sh
|
||||
# Expected status 3: the overridden greeting differs from the ordinary default.
|
||||
go run . config diff --set '/greeting="Hi"' --details --check
|
||||
```
|
||||
|
||||
This compares the overridden left side with ordinary configuration on the
|
||||
right. `go run` prints `exit status 3` and itself exits with status 1; a built
|
||||
executable returns the application's status 3 directly.
|
||||
|
||||
## Inspect warnings and failed loads
|
||||
|
||||
```sh
|
||||
# Schema version 1 produces a warning, visible in verbose mode.
|
||||
go run . config show --config fixtures/before.yml --verbose
|
||||
# Quiet mode hides the configuration report and warning.
|
||||
go run . config show --config fixtures/before.yml --quiet
|
||||
```
|
||||
|
||||
Ordinary mode hides the warning but still displays configuration.
|
||||
|
||||
```sh
|
||||
# Intentional failure: show detailed validation findings for the invalid fixture.
|
||||
go run . config validate --config fixtures/invalid.yml --details --severity error
|
||||
# Intentional failure: still show the source recorded before loading failed.
|
||||
go run . config sources --config fixtures/invalid.yml --source-id source-1
|
||||
```
|
||||
|
||||
Both commands retain the load failure. `source-1` belongs to this fixture's
|
||||
load; other configurations can have different source IDs. See the
|
||||
[CLI reference](../../../../docs/cli.md#configuration-scopes) for report and status rules.
|
||||
|
||||
## Try a custom command
|
||||
|
||||
```sh
|
||||
go run . greet
|
||||
go run . greet --count=0 --tag=first --tag second
|
||||
```
|
||||
|
||||
The `config` family comes from one typed ConfigKit scope. The custom `greet`
|
||||
command uses CommandKit's typed bindings and shows the difference between an
|
||||
omitted `--count` and an explicitly supplied zero, plus ordered repeated tags.
|
||||
With no `--config`, application settings use the in-memory default. A supplied
|
||||
configuration and overlay are passed to ConfigKit unchanged. The comparison
|
||||
command loads the two local fixtures and reports `changes.greeting: Goodbye`.
|
||||
The before fixture uses schema version 1, which ConfigKit reports as a provider
|
||||
warning in verbose mode. Ordinary mode hides the warning while preserving the
|
||||
effective YAML report; quiet mode suppresses that report.
|
||||
The invalid fixture demonstrates a failed-load report and captured source
|
||||
inventory; `source-1` is the ID from that fixture's acquisition. The scope opts
|
||||
in to transient overrides and passes them into its normal ConfigKit load. The
|
||||
diff example compares an overridden left side with ordinary configuration on
|
||||
the right and returns status 3 because the values differ.
|
||||
The handler reports its greeting, count, and tags. It distinguishes an omitted
|
||||
count from an explicitly supplied zero and preserves repeated tag order.
|
||||
|
||||
## How it is wired
|
||||
|
||||
One ConfigKit scope supplies the standard `config` commands. Without `--config`,
|
||||
its loader uses an in-memory default. Supplied configuration and overlay values
|
||||
are passed to ConfigKit unchanged. The scope enables temporary overrides and
|
||||
passes them into its ordinary ConfigKit load. The
|
||||
[consumer guide](../../../../docs/consumers/guide.md#configkit-scopes) explains
|
||||
loader and scope setup.
|
||||
|
||||
Run `GOWORK=off GOTOOLCHAIN=local go test ./...` from this example directory to
|
||||
check it against its declared dependencies.
|
||||
|
||||
@@ -73,13 +73,13 @@ func newConfigOperationCommand[I, S any](prepared *preparedSuite[I, S], operatio
|
||||
scopeChoices = append(scopeChoices, commandkit.CompletionChoice{Value: "all"})
|
||||
}
|
||||
flags := []commandkit.Flag[*configCommandInput[I, S]]{
|
||||
commandkit.ValueFlag(commandkit.FlagMeta{Name: "scope", Usage: "Configuration scope name or all where supported.", Completion: commandkit.CompleteChoices(scopeChoices...)}, &defaultScope, parseConfigString,
|
||||
commandkit.ValueFlag(commandkit.FlagMeta{Name: "scope", Usage: "Select a named configuration, or all where supported.", Completion: commandkit.CompleteChoices(scopeChoices...)}, &defaultScope, parseConfigString,
|
||||
func(input **configCommandInput[I, S], value commandkit.Supplied[string]) { (*input).scope = value }),
|
||||
commandkit.ValueFlag(commandkit.FlagMeta{Name: "config", Usage: "Configuration source.", Completion: commandkit.CompleteFiles()}, (*string)(nil), parseConfigString,
|
||||
commandkit.ValueFlag(commandkit.FlagMeta{Name: "config", Usage: "Select the configuration source.", Completion: commandkit.CompleteFiles()}, (*string)(nil), parseConfigString,
|
||||
func(input **configCommandInput[I, S], value commandkit.Supplied[string]) {
|
||||
(*input).selection.Config = value
|
||||
}),
|
||||
commandkit.ValueFlag(commandkit.FlagMeta{Name: "overlay", Usage: "Overlay source.", Completion: commandkit.CompleteFiles()}, (*string)(nil), parseConfigString,
|
||||
commandkit.ValueFlag(commandkit.FlagMeta{Name: "overlay", Usage: "Select the configuration overlay.", Completion: commandkit.CompleteFiles()}, (*string)(nil), parseConfigString,
|
||||
func(input **configCommandInput[I, S], value commandkit.Supplied[string]) {
|
||||
(*input).selection.Overlay = value
|
||||
}),
|
||||
@@ -89,11 +89,11 @@ func newConfigOperationCommand[I, S any](prepared *preparedSuite[I, S], operatio
|
||||
}
|
||||
if operation == Validate {
|
||||
flags = append(flags,
|
||||
commandkit.BoolFlag(commandkit.FlagMeta{Name: "details", Usage: "Show native validation findings."}, false, func(input **configCommandInput[I, S], value commandkit.Supplied[bool]) { (*input).details = value }),
|
||||
commandkit.BoolFlag(commandkit.FlagMeta{Name: "details", Usage: "Show detailed validation findings."}, false, func(input **configCommandInput[I, S], value commandkit.Supplied[bool]) { (*input).details = value }),
|
||||
commandkit.RepeatFlag(commandkit.FlagMeta{Name: "severity", Usage: "Filter detailed findings by error or warning."}, []configkit.Severity(nil), parseValidationSeverity, func(input **configCommandInput[I, S], value commandkit.Supplied[[]configkit.Severity]) {
|
||||
(*input).severities = value.Value
|
||||
}),
|
||||
commandkit.RepeatFlag(commandkit.FlagMeta{Name: "code", Usage: "Filter detailed findings by exact native code."}, []string(nil), parseConfigString, func(input **configCommandInput[I, S], value commandkit.Supplied[[]string]) {
|
||||
commandkit.RepeatFlag(commandkit.FlagMeta{Name: "code", Usage: "Filter detailed findings by exact diagnostic code."}, []string(nil), parseConfigString, func(input **configCommandInput[I, S], value commandkit.Supplied[[]string]) {
|
||||
(*input).codes = value.Value
|
||||
}),
|
||||
)
|
||||
@@ -114,16 +114,16 @@ func newConfigOperationCommand[I, S any](prepared *preparedSuite[I, S], operatio
|
||||
flags = append(flags,
|
||||
commandkit.ValueFlag(commandkit.FlagMeta{Name: "path", Usage: "JSON Pointer path to explain."}, (*string)(nil), parseConfigString, func(input **configCommandInput[I, S], value commandkit.Supplied[string]) { (*input).path = value }),
|
||||
commandkit.BoolFlag(commandkit.FlagMeta{Name: "list", Usage: "List configuration paths."}, false, func(input **configCommandInput[I, S], value commandkit.Supplied[bool]) { (*input).list = value }),
|
||||
commandkit.BoolFlag(commandkit.FlagMeta{Name: "historical", Usage: "Include historical-only paths when listing."}, false, func(input **configCommandInput[I, S], value commandkit.Supplied[bool]) { (*input).historical = value }),
|
||||
commandkit.BoolFlag(commandkit.FlagMeta{Name: "historical", Usage: "Include paths that exist only in configuration history."}, false, func(input **configCommandInput[I, S], value commandkit.Supplied[bool]) { (*input).historical = value }),
|
||||
commandkit.ValueFlag(commandkit.FlagMeta{Name: "under", Usage: "List paths under a JSON Pointer."}, (*string)(nil), parseConfigString, func(input **configCommandInput[I, S], value commandkit.Supplied[string]) { (*input).under = value }),
|
||||
commandkit.BoolFlag(commandkit.FlagMeta{Name: "explicit", Usage: "Filter listed current paths by explicitness."}, false, func(input **configCommandInput[I, S], value commandkit.Supplied[bool]) { (*input).explicit = value }),
|
||||
commandkit.BoolFlag(commandkit.FlagMeta{Name: "explicit", Usage: "Filter current paths by whether ConfigKit marks them explicit."}, false, func(input **configCommandInput[I, S], value commandkit.Supplied[bool]) { (*input).explicit = value }),
|
||||
)
|
||||
}
|
||||
if operation == Show {
|
||||
flags = append(flags, commandkit.ValueFlag(commandkit.FlagMeta{Name: "path", Usage: "JSON Pointer to one effective value."}, (*string)(nil), parseConfigString, func(input **configCommandInput[I, S], value commandkit.Supplied[string]) { (*input).path = value }))
|
||||
}
|
||||
if operation == Sources {
|
||||
flags = append(flags, commandkit.ValueFlag(commandkit.FlagMeta{Name: "source-id", Usage: "Select one source ID from this acquisition."}, (*string)(nil), parseConfigString, func(input **configCommandInput[I, S], value commandkit.Supplied[string]) { (*input).sourceID = value }))
|
||||
flags = append(flags, commandkit.ValueFlag(commandkit.FlagMeta{Name: "source-id", Usage: "Show one source ID from this configuration load."}, (*string)(nil), parseConfigString, func(input **configCommandInput[I, S], value commandkit.Supplied[string]) { (*input).sourceID = value }))
|
||||
}
|
||||
flags = append(flags, commandkit.CaptureFlags(prepared.bindingsByOperation[operation], func(input **configCommandInput[I, S]) *commandkit.FlagValues[I] {
|
||||
if input == nil || *input == nil {
|
||||
@@ -160,7 +160,7 @@ func newConfigOperationCommand[I, S any](prepared *preparedSuite[I, S], operatio
|
||||
|
||||
func comparisonOperationFlags[I, S any]() []commandkit.Flag[*configCommandInput[I, S]] {
|
||||
return []commandkit.Flag[*configCommandInput[I, S]]{
|
||||
commandkit.BoolFlag(commandkit.FlagMeta{Name: "details", Usage: "Show native before and after difference evidence."}, false, func(input **configCommandInput[I, S], value commandkit.Supplied[bool]) { (*input).details = value }),
|
||||
commandkit.BoolFlag(commandkit.FlagMeta{Name: "details", Usage: "Show before and after values with presence and redaction details."}, false, func(input **configCommandInput[I, S], value commandkit.Supplied[bool]) { (*input).details = value }),
|
||||
commandkit.BoolFlag(commandkit.FlagMeta{Name: "check", Usage: "Return status 3 when differences are found."}, false, func(input **configCommandInput[I, S], value commandkit.Supplied[bool]) { (*input).check = value }),
|
||||
commandkit.ValueFlag(commandkit.FlagMeta{Name: "against-config", Usage: "Configuration source for the right side.", Completion: commandkit.CompleteFiles()}, (*string)(nil), parseConfigString,
|
||||
func(input **configCommandInput[I, S], value commandkit.Supplied[string]) {
|
||||
@@ -191,7 +191,7 @@ func operationDeclaration(operation Operation) (string, string) {
|
||||
case Explain:
|
||||
return "explain", "Explain a configuration path."
|
||||
case Diff:
|
||||
return "diff", "Compare two configuration selections."
|
||||
return "diff", "Compare two configurations."
|
||||
default:
|
||||
return string(operation), "Inspect configuration."
|
||||
}
|
||||
|
||||
@@ -1,37 +1,40 @@
|
||||
# CommandKit ckprompt
|
||||
|
||||
`ckprompt` is the optional PromptKit integration for CommandKit. It adapts
|
||||
PromptKit engine configuration, native comparison, five catalogs, named
|
||||
inspection, requirements discovery and validation, and native smoke tests.
|
||||
Importing it does not install either command family.
|
||||
`ckprompt` adds PromptKit inspection and testing commands to Go applications
|
||||
that use CommandKit. Operators can list prompts, profiles, and backends, inspect
|
||||
their settings, discover required inputs, validate and preview requests, and
|
||||
run smoke tests.
|
||||
|
||||
The application chooses which commands to install. Importing the package alone
|
||||
does not install commands.
|
||||
|
||||
## Module
|
||||
|
||||
The module path is `go.maximumdirect.net/ckprompt`. This source uses Go 1.27.0,
|
||||
`go.maximumdirect.net/commandkit v0.4.0`, `go.maximumdirect.net/ckconfig v0.4.0`,
|
||||
`go.maximumdirect.net/configkit v1.1.0`, and `go.maximumdirect.net/promptkit v0.20.0`. See the
|
||||
[consumer guide](https://gitea.maximumdirect.net/eric/CommandKit/src/branch/main/docs/consumers/guide.md#promptkit-configuration-definitions-and-requirements)
|
||||
for callback, input, state, and acquisition contracts.
|
||||
The module path is `go.maximumdirect.net/ckprompt`. See the
|
||||
[consumer guide](https://forge.maximumdirect.net/base-layer/commandkit/src/branch/main/docs/consumers/guide.md#module-selection)
|
||||
for compatible releases, Go requirements, and the current source's dependency
|
||||
alignment requirement.
|
||||
|
||||
## Example
|
||||
|
||||
Add `ckprompt.ConfigScope(loadEngine)` to the scopes passed to
|
||||
`ckconfig.Command` when the application wants PromptKit engine configuration
|
||||
and native comparison in the `config` family. Install
|
||||
`ckprompt.Command(ckprompt.FromEngine(loadEngine))` separately for catalogs,
|
||||
named inspections, and requirements discovery. `FromEngine` supplies nine
|
||||
PromptKit-backed callbacks: four inspections and five catalogs. Applications
|
||||
may narrow, wrap, or replace them before capture or provide custom callbacks
|
||||
with `ckprompt.Suite`. Add concrete request validation, prepared-request preview,
|
||||
and smoke testing explicitly with `WithRequestValidation`,
|
||||
`WithRequestPreparation`, and `WithSmokeTesting`. Inspection,
|
||||
requirements, and catalog operations do not execute prompts or contact model
|
||||
providers; application loaders and callbacks retain their own effects. Smoke
|
||||
testing invokes the selected native PromptKit operation; the
|
||||
application retains ownership of client and configuration choices. See the
|
||||
[CLI reference](https://gitea.maximumdirect.net/eric/CommandKit/src/branch/main/docs/cli.md#promptkit-smoke-testing)
|
||||
for operator commands and report semantics. The maintained
|
||||
[composed example](examples/composed) shows complete application wiring.
|
||||
Pass your engine loader to `FromEngine` to add resource listings, inspection,
|
||||
and requirements discovery:
|
||||
|
||||
```go
|
||||
app, err := commandkit.New(identity, ckprompt.Command(ckprompt.FromEngine(loadEngine)))
|
||||
```
|
||||
|
||||
Add request validation, preview, and smoke tests with `WithRequestValidation`,
|
||||
`WithRequestPreparation`, and `WithSmokeTesting`. To expose engine configuration
|
||||
under `config`, add `ckprompt.ConfigScope(loadEngine)` to a `ckconfig.Suite`.
|
||||
The [integration guide](https://forge.maximumdirect.net/base-layer/commandkit/src/branch/main/docs/consumers/guide.md#promptkit-configuration-definitions-and-requirements)
|
||||
explains these choices; the [composed example](examples/composed) shows them together.
|
||||
|
||||
Inspection commands do not call the model. Smoke tests can use the application's
|
||||
configured client or network probes. Applications own engine setup, credentials,
|
||||
and any effects of their loaders and callbacks. See the
|
||||
[CLI reference](https://forge.maximumdirect.net/base-layer/commandkit/src/branch/main/docs/cli.md#promptkit-smoke-testing)
|
||||
for commands and results.
|
||||
|
||||
## License and attribution
|
||||
|
||||
|
||||
@@ -91,7 +91,7 @@ func buildCommand[I, S any](suite Suite[I, S], aliases *[]commandkit.Declaration
|
||||
showCommands = append(showCommands, newPreparationCommand(suite, aliases))
|
||||
}
|
||||
if len(showCommands) != 0 {
|
||||
rootCommands = append(rootCommands, commandkit.Group("show", "Show a named PromptKit definition.", showCommands...))
|
||||
rootCommands = append(rootCommands, commandkit.Group("show", "Show PromptKit definitions or preview a prepared request.", showCommands...))
|
||||
}
|
||||
listCommands := make([]commandkit.Command, 0, 5)
|
||||
if suite.ListPrompts != nil {
|
||||
@@ -110,7 +110,7 @@ func buildCommand[I, S any](suite Suite[I, S], aliases *[]commandkit.Declaration
|
||||
listCommands = append(listCommands, newCatalogListCommand(suite, "collections"))
|
||||
}
|
||||
if len(listCommands) != 0 {
|
||||
rootCommands = append(rootCommands, commandkit.Group("list", "List PromptKit catalogs.", listCommands...))
|
||||
rootCommands = append(rootCommands, commandkit.Group("list", "List available PromptKit resources.", listCommands...))
|
||||
}
|
||||
requirementsCommands := make([]commandkit.Command, 0, 2)
|
||||
if suite.InspectRequirements != nil {
|
||||
@@ -125,7 +125,7 @@ func buildCommand[I, S any](suite Suite[I, S], aliases *[]commandkit.Declaration
|
||||
if suite.SmokeTest != nil {
|
||||
rootCommands = append(rootCommands, newSmokeTestCommand(suite, aliases))
|
||||
}
|
||||
command := commandkit.RootGroup("promptkit", "Inspect, list, validate requests, and run PromptKit smoke tests.", rootCommands...)
|
||||
command := commandkit.RootGroup("promptkit", "Inspect PromptKit resources, check requests, and run smoke tests.", rootCommands...)
|
||||
for _, issue := range suite.issues {
|
||||
command = commandkit.WithError(command, issue)
|
||||
}
|
||||
@@ -140,16 +140,16 @@ func newCatalogListCommand[I, S any](suite Suite[I, S], name string) commandkit.
|
||||
return &(*input).captured
|
||||
})
|
||||
flags = append(flags,
|
||||
commandkit.ValueFlag(commandkit.FlagMeta{Name: "config", Usage: "Configuration input path.", Completion: commandkit.CompleteFiles()}, (*string)(nil), parseDefinitionString,
|
||||
commandkit.ValueFlag(commandkit.FlagMeta{Name: "config", Usage: "Select the configuration input path.", Completion: commandkit.CompleteFiles()}, (*string)(nil), parseDefinitionString,
|
||||
func(input **catalogInput[I], value commandkit.Supplied[string]) { (*input).selection.Config = value }),
|
||||
commandkit.ValueFlag(commandkit.FlagMeta{Name: "overlay", Usage: "Configuration overlay path.", Completion: commandkit.CompleteFiles()}, (*string)(nil), parseDefinitionString,
|
||||
commandkit.ValueFlag(commandkit.FlagMeta{Name: "overlay", Usage: "Select the configuration overlay path.", Completion: commandkit.CompleteFiles()}, (*string)(nil), parseDefinitionString,
|
||||
func(input **catalogInput[I], value commandkit.Supplied[string]) { (*input).selection.Overlay = value }),
|
||||
)
|
||||
if name == "prompts" || name == "profiles" || name == "backends" {
|
||||
flags = append(flags,
|
||||
commandkit.ValueFlag(commandkit.FlagMeta{Name: "namespace", Usage: "Select one native namespace."}, (*string)(nil), parseDefinitionString,
|
||||
commandkit.ValueFlag(commandkit.FlagMeta{Name: "namespace", Usage: "List resources in one namespace."}, (*string)(nil), parseDefinitionString,
|
||||
func(input **catalogInput[I], value commandkit.Supplied[string]) { (*input).namespace = value }),
|
||||
commandkit.BoolFlag(commandkit.FlagMeta{Name: "all-namespaces", Usage: "Select identities from every namespace."}, false,
|
||||
commandkit.BoolFlag(commandkit.FlagMeta{Name: "all-namespaces", Usage: "List resources from every namespace."}, false,
|
||||
func(input **catalogInput[I], value commandkit.Supplied[bool]) { (*input).allNamespaces = value }),
|
||||
)
|
||||
}
|
||||
@@ -243,9 +243,9 @@ func newDefinitionCommand[I, S any](suite Suite[I, S], name string, aliases *[]c
|
||||
return &(*input).captured
|
||||
})
|
||||
flags = append(flags,
|
||||
commandkit.ValueFlag(commandkit.FlagMeta{Name: "config", Usage: "Configuration input path.", Completion: commandkit.CompleteFiles()}, (*string)(nil), parseDefinitionString,
|
||||
commandkit.ValueFlag(commandkit.FlagMeta{Name: "config", Usage: "Select the configuration input path.", Completion: commandkit.CompleteFiles()}, (*string)(nil), parseDefinitionString,
|
||||
func(input **definitionInput[I], value commandkit.Supplied[string]) { (*input).selection.Config = value }),
|
||||
commandkit.ValueFlag(commandkit.FlagMeta{Name: "overlay", Usage: "Configuration overlay path.", Completion: commandkit.CompleteFiles()}, (*string)(nil), parseDefinitionString,
|
||||
commandkit.ValueFlag(commandkit.FlagMeta{Name: "overlay", Usage: "Select the configuration overlay path.", Completion: commandkit.CompleteFiles()}, (*string)(nil), parseDefinitionString,
|
||||
func(input **definitionInput[I], value commandkit.Supplied[string]) {
|
||||
(*input).selection.Overlay = value
|
||||
}),
|
||||
@@ -288,11 +288,11 @@ func newRequirementsCommand[I, S any](suite Suite[I, S], aliases *[]commandkit.D
|
||||
return &(*input).captured
|
||||
})
|
||||
flags = append(flags,
|
||||
commandkit.ValueFlag(commandkit.FlagMeta{Name: "config", Usage: "Configuration input path.", Completion: commandkit.CompleteFiles()}, (*string)(nil), parseDefinitionString,
|
||||
commandkit.ValueFlag(commandkit.FlagMeta{Name: "config", Usage: "Select the configuration input path.", Completion: commandkit.CompleteFiles()}, (*string)(nil), parseDefinitionString,
|
||||
func(input **requirementsInput[I], value commandkit.Supplied[string]) {
|
||||
(*input).selection.Config = value
|
||||
}),
|
||||
commandkit.ValueFlag(commandkit.FlagMeta{Name: "overlay", Usage: "Configuration overlay path.", Completion: commandkit.CompleteFiles()}, (*string)(nil), parseDefinitionString,
|
||||
commandkit.ValueFlag(commandkit.FlagMeta{Name: "overlay", Usage: "Select the configuration overlay path.", Completion: commandkit.CompleteFiles()}, (*string)(nil), parseDefinitionString,
|
||||
func(input **requirementsInput[I], value commandkit.Supplied[string]) {
|
||||
(*input).selection.Overlay = value
|
||||
}),
|
||||
@@ -308,8 +308,8 @@ func newRequirementsCommand[I, S any](suite Suite[I, S], aliases *[]commandkit.D
|
||||
|
||||
spec := commandkit.CommandSpec[*requirementsInput[I]]{
|
||||
Name: "show",
|
||||
Summary: "Inspect requirements for a named PromptKit prompt.",
|
||||
Description: "Profile selection establishes the reported profile identity, not a different set of requirements. A profile namespace qualifies an explicitly supplied short profile ID, not the prompt’s stored default reference.",
|
||||
Summary: "Discover the inputs and variables a prompt needs.",
|
||||
Description: "List required inputs without running the prompt. Choosing a profile changes the reported profile ID, not the requirements. A profile namespace applies to a short profile ID supplied here; it does not change the prompt’s stored default reference.",
|
||||
NewInput: func() *requirementsInput[I] {
|
||||
return &requirementsInput[I]{}
|
||||
},
|
||||
|
||||
@@ -1,13 +1,13 @@
|
||||
// Package ckprompt, provided by go.maximumdirect.net/ckprompt, provides optional
|
||||
// PromptKit configuration comparison,
|
||||
// prompt catalogs, named inspections, requirements discovery and validation,
|
||||
// prepared-request preview, and native smoke testing for CommandKit. Command
|
||||
// returns a canonical declaration; Declarations adds scoped flag aliases.
|
||||
// Applications can install those alongside other declarations through
|
||||
// commandkit.New or App.Register. Importing ckprompt installs neither family; callers compose its
|
||||
// declarations with core and ckconfig explicitly. Provider diagnostics remain
|
||||
// passive until the owning command submits them through the invocation
|
||||
// reporter, separately from any terminal explanation. This module uses
|
||||
// PromptKit v0.20.0 and its native engine inventory, including configured
|
||||
// bundled resources.
|
||||
// Package ckprompt adds PromptKit inspection and testing commands to CommandKit
|
||||
// applications. Operators can list resources, inspect definitions, discover
|
||||
// required inputs, validate and preview requests, and run smoke tests.
|
||||
//
|
||||
// Start with FromEngine and add optional operations with WithRequestValidation,
|
||||
// WithRequestPreparation, and WithSmokeTesting. Command returns the command
|
||||
// family; Declarations also includes its convenience flag aliases. Install
|
||||
// these with commandkit.New or App.Register.
|
||||
//
|
||||
// ConfigScope separately exposes engine configuration through ckconfig.
|
||||
// Importing this package installs neither command family. Applications own
|
||||
// engine construction, credentials, and client configuration.
|
||||
package ckprompt
|
||||
|
||||
@@ -1,27 +1,40 @@
|
||||
# CommandKit ckprompt v0.3.0
|
||||
|
||||
CommandKit ckprompt v0.3.0 adopts PromptKit v0.20.0 and ConfigKit v1.1.0,
|
||||
and requires CommandKit core v0.4.0, ckconfig v0.4.0, and Go 1.27.0.
|
||||
The integration uses shared core reporting for text, YAML, and JSON output.
|
||||
This unpublished candidate adds PromptKit v0.20.0 support, including request
|
||||
preview, namespace selection, and shared text, YAML, and JSON output. It uses
|
||||
ConfigKit v1.1.0 and requires Go 1.27.0.
|
||||
|
||||
Prompt, profile, and backend commands report PromptKit's native resource
|
||||
inspections. Applications may opt into prepared-request preview, concrete
|
||||
request validation, smoke testing, and namespace selectors independently.
|
||||
Reusable request flag collections support application-owned commands;
|
||||
`ckprompt.Declarations` installs the standard family with scoped aliases.
|
||||
Literal and file inputs retain their command-line order. Provider parameters
|
||||
can be supplied for preparation and applicable diagnostics.
|
||||
## Operator features
|
||||
|
||||
The PromptKit configuration scope exposes native metadata and load-failure
|
||||
evidence through ckconfig, including independent comparison selections,
|
||||
detailed differences, and validation findings. Smoke reports retain native
|
||||
evidence and operation failures separately from presentation failures.
|
||||
- Inspect prompts, profiles, and backends, and list available resources.
|
||||
- Preview rendered requests without calling the model, or validate that a
|
||||
request can be prepared with the supplied inputs.
|
||||
- Choose namespaces and override request settings for supported commands.
|
||||
- Run smoke tests and inspect their results, including incomplete or unsupported
|
||||
checks and reports returned alongside errors.
|
||||
- Inspect engine configuration through `config`, including detailed validation
|
||||
findings, source information after failed loads, and configuration comparisons.
|
||||
|
||||
This pre-1.0 release changes resource report shapes, input flags, formatting,
|
||||
and configuration comparison behavior. Applications should update declarations
|
||||
and report consumers to the current [CLI reference](../../../../docs/cli.md#promptkit-definition-inspection)
|
||||
and [consumer guide](../../../../docs/consumers/guide.md#promptkit-configuration-definitions-and-requirements).
|
||||
Applications continue to own engine construction, credentials, and execution.
|
||||
Applications choose which commands to enable. Reusable flag collections also
|
||||
let application commands offer the same request flags. `ckprompt.Declarations`
|
||||
adds the standard commands with their shorter flag aliases. Literal and file
|
||||
inputs keep their command-line order.
|
||||
|
||||
## Compatibility and preparation
|
||||
|
||||
This candidate changes resource report shapes, input flags, formatting, and
|
||||
configuration comparison behavior. Review the current
|
||||
[CLI reference](../../../../docs/cli.md#promptkit-definition-inspection) and
|
||||
[consumer guide](../../../../docs/consumers/guide.md#promptkit-configuration-definitions-and-requirements)
|
||||
when updating declarations or code that reads reports. Applications continue to
|
||||
own engine construction, credentials, and execution.
|
||||
|
||||
The current source requires `ckconfig.AdaptDiagnostics`, which is absent from
|
||||
its selected ckconfig v0.4.0 dependency. Before publication, complete
|
||||
[dependency alignment](../../../../docs/roadmap/future.md#pending-release-and-integration-work)
|
||||
and update this candidate's dependency guidance to the selected releases.
|
||||
The [module selection table](../../../../docs/consumers/guide.md#module-selection)
|
||||
distinguishes published combinations from the current workspace.
|
||||
|
||||
[COPYRIGHT](https://forge.maximumdirect.net/base-layer/commandkit/src/tag/integrations/ckprompt/v0.3.0/integrations/ckprompt/COPYRIGHT) |
|
||||
[LICENSE](https://forge.maximumdirect.net/base-layer/commandkit/src/tag/integrations/ckprompt/v0.3.0/integrations/ckprompt/LICENSE) |
|
||||
|
||||
@@ -1,141 +1,172 @@
|
||||
# Composed consumer
|
||||
# ConfigKit and PromptKit example
|
||||
|
||||
This example is part of the ckprompt module and uses core v0.4.0, ckconfig
|
||||
v0.4.0, ConfigKit v1.1.0, and PromptKit v0.20.0. It requires Go 1.27.0.
|
||||
This example combines application and PromptKit configuration, resource
|
||||
inspection, request checks, and smoke tests. It uses local fixtures and an
|
||||
in-memory model client. **No model service or credentials are required.**
|
||||
|
||||
This example composes application configuration, PromptKit configuration,
|
||||
PromptKit comparison and catalogs, definition and requirements inspection, and
|
||||
one application-owned command:
|
||||
Use Go 1.27.0 on `PATH` and an aligned workspace containing all three local
|
||||
modules. Follow the [workspace setup](../../../../docs/development.md#documentation-validation)
|
||||
from the repository root first. Current ckprompt source needs a helper in local
|
||||
ckconfig source that its released dependency does not yet contain; independent
|
||||
builds remain pending [release alignment](../../../../docs/roadmap/future.md#pending-release-and-integration-work).
|
||||
The [consumer guide](../../../../docs/consumers/guide.md#module-selection) owns
|
||||
version and compatibility details.
|
||||
|
||||
From the repository root:
|
||||
|
||||
```sh
|
||||
cd integrations/ckprompt/examples/composed
|
||||
export GOWORK=auto GOTOOLCHAIN=local
|
||||
go run . config scopes
|
||||
go run . promptkit list prompts --campaign spring
|
||||
go run . promptkit show prompt briefing --campaign spring --format yaml
|
||||
```
|
||||
|
||||
The first command lists `app` and `promptkit` configurations and their available
|
||||
operations. The next commands find and inspect the `briefing` prompt.
|
||||
`--campaign` is a selector supplied by this example, not a standard PromptKit flag.
|
||||
|
||||
## Validate and compare configuration
|
||||
|
||||
```sh
|
||||
go run . config validate --scope all --campaign spring --limit=0
|
||||
go run . config diff --scope app --config fixtures/before.yml --against-config fixtures/after.yml
|
||||
go run . config diff --scope app --config fixtures/before.yml --against-config fixtures/after.yml --campaign spring --limit=0
|
||||
go run . config diff --scope app --campaign spring --limit=0 --against-campaign autumn --against-limit=0 --set '/campaigns/spring/model="left"' --against-set '/campaigns/spring/model="right"' --details
|
||||
go run . config diff --scope promptkit --config fixtures/before.yml --against-config fixtures/after.yml --campaign spring --against-campaign spring
|
||||
go run . promptkit list prompts --config fixtures/before.yml --campaign spring
|
||||
```
|
||||
|
||||
The application scope requires `--limit=0` when `--campaign` is supplied.
|
||||
The app comparison reports a changed default campaign and `campaigns.spring.model`.
|
||||
The PromptKit comparison selects spring on both sides and reports the changed
|
||||
profiles list as one value.
|
||||
|
||||
The two sides have independent selectors and overrides:
|
||||
|
||||
```sh
|
||||
go run . config diff --scope app --campaign spring --limit=0 --against-campaign autumn --against-limit=0 --set '/campaigns/spring/model="left"' --against-set '/campaigns/spring/model="right"' --details
|
||||
```
|
||||
|
||||
Only the application scope supports `--set` here. The released PromptKit loader
|
||||
has no override handoff, so its configuration scope does not enable the feature.
|
||||
An aggregate operation that includes that scope rejects overrides.
|
||||
|
||||
## List resources and select namespaces
|
||||
|
||||
```sh
|
||||
go run . promptkit list profiles --config fixtures/after.yml --campaign autumn --format yaml
|
||||
go run . promptkit list backends --campaign spring
|
||||
go run . promptkit list namespaces --campaign spring
|
||||
go run . promptkit list collections --campaign spring
|
||||
go run . list collections --campaign spring
|
||||
go run . pk list bundles --campaign spring
|
||||
go run . promptkit list prompts --namespace field-notes --campaign spring
|
||||
go run . promptkit show prompt briefing --campaign spring --format yaml
|
||||
go run . promptkit show prompt briefing --campaign spring --prompt-namespace field-notes
|
||||
go run . promptkit show prepared briefing --campaign spring --input topic=sprint --profile spring --extra-params '{"campaign":"preview"}'
|
||||
go run . pk show prompt briefing --campaign spring --fmt yaml
|
||||
go run . promptkit show profile spring --campaign spring
|
||||
```
|
||||
|
||||
The profile list includes the selected `autumn` profile. PromptKit's default
|
||||
bundle contributes additional resources. The example also supplies a
|
||||
`field-notes` collection containing a backend, profile, and prompt. Listing
|
||||
filters and resource namespace flags let you inspect that collection.
|
||||
|
||||
## Discover inputs, then check a request
|
||||
|
||||
```sh
|
||||
go run . promptkit requirements show briefing --campaign spring
|
||||
go run . promptkit requirements show briefing --campaign spring --var mode=full --format yaml
|
||||
```
|
||||
|
||||
The first report is incomplete: the `notes` input is conditional and `mode` is
|
||||
missing. Supplying `mode=full` selects that branch and makes `notes` required.
|
||||
Both commands succeed; discovery alone does not establish that a request can run.
|
||||
|
||||
```sh
|
||||
go run . promptkit requirements validate briefing --campaign spring --llm-input-file topic=fixtures/topic.txt
|
||||
go run . promptkit requirements validate briefing --campaign spring --llm-input-file topic=fixtures/topic.txt --llm-var mode=full --llm-input-file notes=fixtures/notes.txt --format yaml
|
||||
```
|
||||
|
||||
Both commands check request preparation and report `prompt_id` and `valid: true`.
|
||||
The builder provides campaign-specific variable defaults; the operator supplies
|
||||
the input files. For comparison, this command intentionally fails because the
|
||||
required `topic` input is missing:
|
||||
|
||||
```sh
|
||||
# Intentional failure: missing topic input.
|
||||
go run . promptkit requirements validate briefing --campaign spring
|
||||
```
|
||||
|
||||
Preview a request with literal input instead of a file:
|
||||
|
||||
```sh
|
||||
go run . promptkit show prepared briefing --campaign spring --input topic=sprint --profile spring --extra-params '{"campaign":"preview"}'
|
||||
```
|
||||
|
||||
The preview includes rendered messages and effective provider settings.
|
||||
Validation and preview do not call the model or guarantee later execution.
|
||||
|
||||
## Run smoke tests
|
||||
|
||||
```sh
|
||||
go run . promptkit test text_inference --campaign spring --prompt briefing --profile spring
|
||||
go run . smoke text_inference --campaign spring --llm-prompt briefing --llm-profile spring
|
||||
# Some diagnostics can fail or be unsupported; inspect the retained report.
|
||||
go run . promptkit test all --campaign spring --llm-prompt briefing --llm-profile spring
|
||||
```
|
||||
|
||||
Inference uses the example's in-memory client. HTTP checks may be unsupported
|
||||
or not applicable because the local backend has no network probe. The aggregate
|
||||
can return a failure while still showing results. Read the facts in the report;
|
||||
a successful command status does not mean every observation is positive.
|
||||
|
||||
For any command that returns nonzero, `go run` prints `exit status N` and itself
|
||||
exits with status 1. A built executable returns the application's status directly.
|
||||
The [CLI reference](../../../../docs/cli.md#promptkit-smoke-testing) explains the
|
||||
standard test kinds, results, and statuses.
|
||||
|
||||
## Try aliases and application commands
|
||||
|
||||
```sh
|
||||
go run . list collections --campaign spring
|
||||
go run . pk list bundles --campaign spring
|
||||
go run . pk show prompt briefing --campaign spring --fmt yaml
|
||||
go run . smoke text_inference --campaign spring --llm-prompt briefing --llm-profile spring
|
||||
go run . pk --hlep
|
||||
go run . session restore session-42 --campaign spring
|
||||
go run . request inspect --llm-prompt briefing --llm-profile= --llm-model example --llm-input-text topic=sprint --format json
|
||||
```
|
||||
|
||||
`newApp` installs application-owned command and flag aliases alongside the
|
||||
complete `ckconfig` and `ckprompt` declarations. `list collections` and
|
||||
`promptkit list bundles` both reach the canonical collection command; `pk`
|
||||
shortens the PromptKit group. `--fmt` is scoped to named prompt inspection and
|
||||
`--hlep` is available globally. The `smoke` shortcut retains the canonical
|
||||
`promptkit test KIND` operand, including the special `all` aggregate.
|
||||
The first two commands reach `promptkit list collections`. `pk` shortens the
|
||||
PromptKit group; `--fmt` is an alias on prompt inspection and `--hlep` is a global
|
||||
help alias. `smoke` shortens `promptkit test` while leaving the test kind as an
|
||||
argument. The session command uses an in-memory store. `request inspect` shows
|
||||
how an application command can reuse canonical `--llm-*` flag collections without
|
||||
installing PromptKit's short aliases.
|
||||
|
||||
The example installs `Completion("composed-example")`. Build it as
|
||||
`go build -o composed-example .`. Initialize `bash-completion` first if using
|
||||
Bash, then load a shell script as described in the
|
||||
[CLI reference](../../../../docs/cli.md#shell-completion). Try completion after
|
||||
`composed-example pk show prompt briefing --fmt=` or after the filename prefix
|
||||
in `composed-example config show --config=fixtures/`. The already-entered `pk`
|
||||
alias selects the PromptKit command context without loading an engine.
|
||||
## Try shell completion
|
||||
|
||||
The composition installs `ckconfig.Command(suite)` and the complete
|
||||
`ckprompt.Declarations(definitions)` in a `[]commandkit.Declaration` with
|
||||
root-installed routing rules. The PromptKit declarations include scoped aliases;
|
||||
the application-owned `request inspect` command reuses the flag collections
|
||||
with their canonical names and does not install those aliases.
|
||||
Group children remain canonical `Command` values. For command-only slices,
|
||||
convert each `Command` to `Declaration` before appending aliases. The
|
||||
[consumer guide](../../../../docs/consumers/guide.md#application-owned-aliases)
|
||||
includes minimal direct-call and slice-conversion examples; this README documents
|
||||
the maintained complete consumer.
|
||||
|
||||
The sources and session store are small in-memory fixtures. `--campaign` is a
|
||||
typed selector shared by the app and PromptKit configuration scopes. Their
|
||||
`ckconfig.Suite[*inspectionInput, *runCache]` uses `NewInput` to initialize each
|
||||
selected scope's input separately and `NewState` to create one cache shared by
|
||||
that invocation's acquisitions. Prompt/profile inspection prepares its input and
|
||||
cache independently for its invocation, using the same application and engine
|
||||
loader functions. See the
|
||||
[consumer guide](https://gitea.maximumdirect.net/eric/CommandKit/src/branch/main/docs/consumers/guide.md)
|
||||
and the suites' GoDoc for initialization timing and ownership.
|
||||
|
||||
The application-scope comparison reports the changed default campaign and the
|
||||
updated `campaigns.spring.model`. The PromptKit-scope comparison selects spring
|
||||
on both sides and reports the native engine change in the atomic profiles list.
|
||||
The application input check requires `--limit=0` when `--campaign` is supplied.
|
||||
Catalogs use the same selection-aware loader: the prompt catalog includes
|
||||
`briefing`, and the profile catalog includes the selected `autumn` profile.
|
||||
Prompt inspection uses an ID only. The default PromptKit bundle also contributes
|
||||
profiles and a backend to the engine inventory and source reports. The synthetic `field-notes` collection
|
||||
provides one backend, profile, and prompt for collection discovery and native
|
||||
namespace filtering. The example's shared run cache keys successful results by
|
||||
the complete supplied configuration/overlay selection, CLI overrides, and the
|
||||
supplied campaign, including presence. The campaign override and application
|
||||
scope's `--set` records are applied through ConfigKit before loading. The
|
||||
PromptKit configuration scope does not enable `--set` because its released
|
||||
configuration loader has no override handoff. An aggregate operation therefore
|
||||
rejects overrides when that scope is selected. These are choices for this
|
||||
example's loaders and do not define a CommandKit cache policy.
|
||||
|
||||
Smoke testing is explicitly wired with `ckprompt.WithSmokeTesting` and its
|
||||
optional request builder is nil, so CommandKit forwards the selected native
|
||||
request. Applications that need to adjust the request can provide a typed
|
||||
builder that starts with the seed and returns the chosen native request:
|
||||
|
||||
```go
|
||||
definitions = ckprompt.WithSmokeTesting(definitions, loadEngine,
|
||||
func(ctx context.Context, seed ckprompt.SmokeRequest, input *inspectionInput, state *runCache) (promptkit.SmokeTestRequest, error) {
|
||||
request := seed.Request
|
||||
request.ProfileID = "spring"
|
||||
return request, nil
|
||||
})
|
||||
```sh
|
||||
go build -o composed-example .
|
||||
./composed-example completion bash
|
||||
```
|
||||
|
||||
The example injects a small in-memory `promptkit.LLMClient` through its shared
|
||||
run state. Catalog, inspection, and requirements commands do not call it;
|
||||
inference smoke commands do. No model service or credentials are required.
|
||||
Native HTTP checks may retain unsupported or not-applicable observations because
|
||||
the selected local backend does not configure a network probe. An aggregate smoke command can
|
||||
return an operational outcome for a native diagnostic while still delivering
|
||||
the complete aggregate report.
|
||||
Initialize `bash-completion` if using Bash, then load the generated script using
|
||||
the [CLI reference](../../../../docs/cli.md#shell-completion). Try completing
|
||||
`composed-example pk show prompt briefing --fmt=` or
|
||||
`composed-example config show --config=fixtures/`. The already-entered `pk` alias
|
||||
selects the command context without loading an engine.
|
||||
|
||||
The first requirements command reports incomplete discovery: PromptKit records
|
||||
the conditional `notes` input and a missing `mode` issue. Supplying `mode=full`
|
||||
selects that branch, classifies the undeclared `notes` input as required, and
|
||||
completes discovery. Both commands return successful reports; the result does
|
||||
not execute the prompt or establish input, credential, or execution readiness.
|
||||
See the [CLI reference](../../../../docs/cli.md#promptkit-requirements) for the
|
||||
command and report contract.
|
||||
## How it is wired
|
||||
|
||||
The validation and preview commands exercise concrete PromptKit request preparation.
|
||||
The first uses the builder's campaign-specific default topic variable and the
|
||||
operator's topic file. The second also selects the notes branch and supplies its
|
||||
file. Validation reports only `prompt_id` and `valid: true`; preview returns the
|
||||
prepared request, including rendered messages and effective provider settings.
|
||||
Neither executes the prompt. The validation command without inputs intentionally
|
||||
fails because the prompt's
|
||||
required `topic` artifact is not supplied. The builder defaults variables from
|
||||
the selected campaign but leaves artifact bindings to the operator. The
|
||||
`requirements show` commands remain discovery reports: partial discovery can
|
||||
succeed even when a concrete request would fail validation.
|
||||
The example installs `ckconfig.Command(suite)` and
|
||||
`ckprompt.Declarations(definitions)` with application-owned aliases in a
|
||||
`[]commandkit.Declaration`. `NewInput` initializes scope inputs; `NewState`
|
||||
creates a cache shared within an invocation. The loaders cache successful
|
||||
configuration results by the complete configuration/overlay selection,
|
||||
overrides, and supplied campaign, including whether each value was supplied.
|
||||
These are example choices, not a CommandKit cache policy.
|
||||
|
||||
Run `GOWORK=off go test ./...` from this example directory to check it against
|
||||
its declared dependencies. The [developer guide](../../../../docs/development.md#documentation-validation)
|
||||
also describes aligned workspace tests.
|
||||
Smoke testing uses `WithSmokeTesting` with a nil builder, forwarding the request
|
||||
selected by flags. Applications can supply a builder to customize that request.
|
||||
See the [consumer guide](../../../../docs/consumers/guide.md#promptkit-configuration-definitions-and-requirements)
|
||||
for suite composition, builders, and ownership, and the [source](main.go) for
|
||||
the complete application.
|
||||
|
||||
Run `GOWORK=auto GOTOOLCHAIN=local go test ./...` from this example directory
|
||||
for an aligned workspace check. Once dependency alignment is complete, also use
|
||||
`GOWORK=off GOTOOLCHAIN=local go test ./...` to check the declared releases.
|
||||
|
||||
@@ -39,9 +39,9 @@ func namespaceFlags[I any](destination func(*I) *namespaceInput, kinds ...string
|
||||
}
|
||||
|
||||
var namespaceFlagDefinitions = struct{ prompt, profile, backend requestFlagDefinition }{
|
||||
prompt: requestFlagDefinition{commandkit.FlagMeta{Name: "llm-prompt-namespace", Usage: "Prompt resource namespace."}, []string{"prompt-namespace"}},
|
||||
profile: requestFlagDefinition{commandkit.FlagMeta{Name: "llm-profile-namespace", Usage: "Profile resource namespace."}, []string{"profile-namespace"}},
|
||||
backend: requestFlagDefinition{commandkit.FlagMeta{Name: "llm-backend-namespace", Usage: "Backend resource namespace."}, []string{"backend-namespace"}},
|
||||
prompt: requestFlagDefinition{commandkit.FlagMeta{Name: "llm-prompt-namespace", Usage: "Use this namespace for unqualified prompt IDs."}, []string{"prompt-namespace"}},
|
||||
profile: requestFlagDefinition{commandkit.FlagMeta{Name: "llm-profile-namespace", Usage: "Use this namespace for unqualified profile IDs."}, []string{"profile-namespace"}},
|
||||
backend: requestFlagDefinition{commandkit.FlagMeta{Name: "llm-backend-namespace", Usage: "Use this namespace for unqualified backend IDs."}, []string{"backend-namespace"}},
|
||||
}
|
||||
|
||||
func selectedNamespaces(defaults *promptkit.Namespaces, selected namespaceInput) *promptkit.Namespaces {
|
||||
|
||||
@@ -35,24 +35,24 @@ var requestFlags = struct {
|
||||
InputText requestFlagDefinition
|
||||
InputFile requestFlagDefinition
|
||||
}{
|
||||
Endpoint: requestFlagDefinition{commandkit.FlagMeta{Name: "llm-endpoint", Usage: "Execution endpoint override."}, []string{"endpoint"}},
|
||||
Model: requestFlagDefinition{commandkit.FlagMeta{Name: "llm-model", Usage: "Execution model override."}, []string{"model"}},
|
||||
Temperature: requestFlagDefinition{commandkit.FlagMeta{Name: "llm-temperature", Usage: "Execution temperature override."}, []string{"temperature"}},
|
||||
MaxTokens: requestFlagDefinition{commandkit.FlagMeta{Name: "llm-max-tokens", Usage: "Execution maximum tokens override."}, []string{"max-tokens"}},
|
||||
TopP: requestFlagDefinition{commandkit.FlagMeta{Name: "llm-top-p", Usage: "Execution top-p override."}, []string{"top-p"}},
|
||||
TimeoutSeconds: requestFlagDefinition{commandkit.FlagMeta{Name: "llm-timeout-seconds", Usage: "Execution timeout override in seconds."}, []string{"timeout-seconds"}},
|
||||
ServiceTier: requestFlagDefinition{commandkit.FlagMeta{Name: "llm-service-tier", Usage: "Execution service tier."}, []string{"service-tier"}},
|
||||
ReasoningEffort: requestFlagDefinition{commandkit.FlagMeta{Name: "llm-reasoning-effort", Usage: "Execution reasoning effort override."}, []string{"reasoning-effort"}},
|
||||
APIKeyEnv: requestFlagDefinition{commandkit.FlagMeta{Name: "llm-api-key-env", Usage: "Execution API key environment variable."}, []string{"api-key-env"}},
|
||||
TransientRetries: requestFlagDefinition{commandkit.FlagMeta{Name: "llm-transient-retries", Usage: "Inference transient retry count."}, []string{"transient-retries"}},
|
||||
ExtraParams: requestFlagDefinition{commandkit.FlagMeta{Name: "llm-extra-params", Usage: "Execution provider parameters as a JSON object."}, []string{"extra-params"}},
|
||||
Prompt: requestFlagDefinition{commandkit.FlagMeta{Name: "llm-prompt", Usage: "PromptKit prompt ID."}, []string{"prompt"}},
|
||||
Profile: requestFlagDefinition{commandkit.FlagMeta{Name: "llm-profile", Usage: "PromptKit profile ID."}, []string{"profile"}},
|
||||
Backend: requestFlagDefinition{commandkit.FlagMeta{Name: "llm-backend", Usage: "PromptKit backend ID."}, []string{"backend"}},
|
||||
SessionID: requestFlagDefinition{commandkit.FlagMeta{Name: "llm-session-id", Usage: "PromptKit session ID."}, []string{"session-id"}},
|
||||
Var: requestFlagDefinition{commandkit.FlagMeta{Name: "llm-var", Usage: "Caller variable assignment KEY=VALUE."}, []string{"var"}},
|
||||
InputText: requestFlagDefinition{commandkit.FlagMeta{Name: "llm-input-text", Usage: "Literal prompt input assignment NAME=TEXT."}, []string{"input-text", "llm-input", "input"}},
|
||||
InputFile: requestFlagDefinition{commandkit.FlagMeta{Name: "llm-input-file", Usage: "Prompt input file assignment NAME=PATH."}, []string{"input-file"}},
|
||||
Endpoint: requestFlagDefinition{commandkit.FlagMeta{Name: "llm-endpoint", Usage: "Use this endpoint."}, []string{"endpoint"}},
|
||||
Model: requestFlagDefinition{commandkit.FlagMeta{Name: "llm-model", Usage: "Use this model."}, []string{"model"}},
|
||||
Temperature: requestFlagDefinition{commandkit.FlagMeta{Name: "llm-temperature", Usage: "Use this temperature."}, []string{"temperature"}},
|
||||
MaxTokens: requestFlagDefinition{commandkit.FlagMeta{Name: "llm-max-tokens", Usage: "Use this maximum token count."}, []string{"max-tokens"}},
|
||||
TopP: requestFlagDefinition{commandkit.FlagMeta{Name: "llm-top-p", Usage: "Use this top-p value."}, []string{"top-p"}},
|
||||
TimeoutSeconds: requestFlagDefinition{commandkit.FlagMeta{Name: "llm-timeout-seconds", Usage: "Set the request timeout in seconds."}, []string{"timeout-seconds"}},
|
||||
ServiceTier: requestFlagDefinition{commandkit.FlagMeta{Name: "llm-service-tier", Usage: "Use this service tier."}, []string{"service-tier"}},
|
||||
ReasoningEffort: requestFlagDefinition{commandkit.FlagMeta{Name: "llm-reasoning-effort", Usage: "Use this reasoning effort."}, []string{"reasoning-effort"}},
|
||||
APIKeyEnv: requestFlagDefinition{commandkit.FlagMeta{Name: "llm-api-key-env", Usage: "Name the environment variable containing the API key."}, []string{"api-key-env"}},
|
||||
TransientRetries: requestFlagDefinition{commandkit.FlagMeta{Name: "llm-transient-retries", Usage: "Set the retry count for transient inference failures."}, []string{"transient-retries"}},
|
||||
ExtraParams: requestFlagDefinition{commandkit.FlagMeta{Name: "llm-extra-params", Usage: "Supply provider parameters as a JSON object."}, []string{"extra-params"}},
|
||||
Prompt: requestFlagDefinition{commandkit.FlagMeta{Name: "llm-prompt", Usage: "Select a prompt by ID."}, []string{"prompt"}},
|
||||
Profile: requestFlagDefinition{commandkit.FlagMeta{Name: "llm-profile", Usage: "Select a profile by ID."}, []string{"profile"}},
|
||||
Backend: requestFlagDefinition{commandkit.FlagMeta{Name: "llm-backend", Usage: "Select a backend by ID."}, []string{"backend"}},
|
||||
SessionID: requestFlagDefinition{commandkit.FlagMeta{Name: "llm-session-id", Usage: "Supply the session ID."}, []string{"session-id"}},
|
||||
Var: requestFlagDefinition{commandkit.FlagMeta{Name: "llm-var", Usage: "Supply a prompt variable as KEY=VALUE."}, []string{"var"}},
|
||||
InputText: requestFlagDefinition{commandkit.FlagMeta{Name: "llm-input-text", Usage: "Supply text for a prompt input as NAME=TEXT."}, []string{"input-text", "llm-input", "input"}},
|
||||
InputFile: requestFlagDefinition{commandkit.FlagMeta{Name: "llm-input-file", Usage: "Supply a file for a prompt input as NAME=PATH."}, []string{"input-file"}},
|
||||
}
|
||||
|
||||
// ExecutionInput contains request-scoped execution controls supplied on the CLI.
|
||||
|
||||
@@ -29,11 +29,11 @@ func newSmokeTestCommand[I, S any](suite Suite[I, S], aliases *[]commandkit.Decl
|
||||
return &(*input).captured
|
||||
})
|
||||
flags = append(flags,
|
||||
commandkit.ValueFlag(commandkit.FlagMeta{Name: "config", Usage: "Configuration input path.", Completion: commandkit.CompleteFiles()}, (*string)(nil), parseDefinitionString,
|
||||
commandkit.ValueFlag(commandkit.FlagMeta{Name: "config", Usage: "Select the configuration input path.", Completion: commandkit.CompleteFiles()}, (*string)(nil), parseDefinitionString,
|
||||
func(input **smokeCommandInput[I], value commandkit.Supplied[string]) {
|
||||
(*input).selection.Config = value
|
||||
}),
|
||||
commandkit.ValueFlag(commandkit.FlagMeta{Name: "overlay", Usage: "Configuration overlay path.", Completion: commandkit.CompleteFiles()}, (*string)(nil), parseDefinitionString,
|
||||
commandkit.ValueFlag(commandkit.FlagMeta{Name: "overlay", Usage: "Select the configuration overlay path.", Completion: commandkit.CompleteFiles()}, (*string)(nil), parseDefinitionString,
|
||||
func(input **smokeCommandInput[I], value commandkit.Supplied[string]) {
|
||||
(*input).selection.Overlay = value
|
||||
}),
|
||||
@@ -53,14 +53,15 @@ func newSmokeTestCommand[I, S any](suite Suite[I, S], aliases *[]commandkit.Decl
|
||||
}
|
||||
|
||||
return commandkit.NewCommand(commandkit.CommandSpec[*smokeCommandInput[I]]{
|
||||
Name: "test",
|
||||
Summary: "Run one PromptKit smoke test.",
|
||||
Name: "test",
|
||||
Summary: "Run one or all PromptKit smoke tests.",
|
||||
Description: "Tests use the configured client or probes and may contact a provider. The all option runs the four tests in order. Read the report: a successful command status does not mean every observation is positive.",
|
||||
NewInput: func() *smokeCommandInput[I] {
|
||||
return &smokeCommandInput[I]{}
|
||||
},
|
||||
Flags: flags,
|
||||
Arguments: []commandkit.Argument[*smokeCommandInput[I]]{
|
||||
commandkit.ValueArgument(commandkit.ArgumentMeta{Name: "kind", Usage: "Native smoke-test kind.", Completion: smokeKindCompletion()}, true, parseDefinitionString,
|
||||
commandkit.ValueArgument(commandkit.ArgumentMeta{Name: "kind", Usage: "Test kind: reachability, authentication, text_inference, structured_output, or all.", Completion: smokeKindCompletion()}, true, parseDefinitionString,
|
||||
func(input **smokeCommandInput[I], value commandkit.Supplied[string]) { (*input).kind = value.Value }),
|
||||
},
|
||||
CheckInput: func(input *smokeCommandInput[I]) error {
|
||||
|
||||
@@ -31,11 +31,11 @@ func newConcreteRequestSpec[I, S any](suite Suite[I, S], path string, aliases *[
|
||||
return &(*input).captured
|
||||
})
|
||||
flags = append(flags,
|
||||
commandkit.ValueFlag(commandkit.FlagMeta{Name: "config", Usage: "Configuration input path.", Completion: commandkit.CompleteFiles()}, (*string)(nil), parseDefinitionString,
|
||||
commandkit.ValueFlag(commandkit.FlagMeta{Name: "config", Usage: "Select the configuration input path.", Completion: commandkit.CompleteFiles()}, (*string)(nil), parseDefinitionString,
|
||||
func(input **concreteRequestInput[I], value commandkit.Supplied[string]) {
|
||||
(*input).request.Selection.Config = value
|
||||
}),
|
||||
commandkit.ValueFlag(commandkit.FlagMeta{Name: "overlay", Usage: "Configuration overlay path.", Completion: commandkit.CompleteFiles()}, (*string)(nil), parseDefinitionString,
|
||||
commandkit.ValueFlag(commandkit.FlagMeta{Name: "overlay", Usage: "Select the configuration overlay path.", Completion: commandkit.CompleteFiles()}, (*string)(nil), parseDefinitionString,
|
||||
func(input **concreteRequestInput[I], value commandkit.Supplied[string]) {
|
||||
(*input).request.Selection.Overlay = value
|
||||
}),
|
||||
@@ -93,7 +93,7 @@ func newConcreteRequestSpec[I, S any](suite Suite[I, S], path string, aliases *[
|
||||
func newValidationCommand[I, S any](suite Suite[I, S], aliases *[]commandkit.Declaration) commandkit.Command {
|
||||
spec := newConcreteRequestSpec(suite, "promptkit requirements validate", aliases)
|
||||
spec.Name = "validate"
|
||||
spec.Summary = "Validate a concrete PromptKit request without executing it."
|
||||
spec.Summary = "Check whether a request can be prepared without calling the model."
|
||||
spec.Run = func(invocation commandkit.Invocation, input *concreteRequestInput[I]) commandkit.Outcome {
|
||||
return runRequestValidation(invocation, suite, input)
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user