Add opt-in PromptKit namespaces
This commit is contained in:
28
docs/cli.md
28
docs/cli.md
@@ -555,6 +555,25 @@ performs a network probe. See the [PromptKit resource inspection contracts](http
|
|||||||
A missing ID is a usage error; native lookup errors and cancellation retain
|
A missing ID is a usage error; native lookup errors and cancellation retain
|
||||||
supported cause identity.
|
supported cause identity.
|
||||||
|
|
||||||
|
### Resource namespace selection
|
||||||
|
|
||||||
|
An application can enable resource namespace flags with `ckprompt.WithNamespaces`
|
||||||
|
and provide prompt, profile, and backend defaults. Omitted flags retain those
|
||||||
|
defaults; an explicitly empty value clears the corresponding default. Qualified
|
||||||
|
resource IDs pass through unchanged. Without the option, the application loader
|
||||||
|
controls the engine view and these flags are unavailable.
|
||||||
|
|
||||||
|
| Operation | Available namespace flags |
|
||||||
|
| --- | --- |
|
||||||
|
| `show prompt` | `--llm-prompt-namespace` |
|
||||||
|
| `show profile` | `--llm-profile-namespace` |
|
||||||
|
| `show backend` | `--llm-backend-namespace` |
|
||||||
|
| `requirements show` | `--llm-prompt-namespace`, `--llm-profile-namespace` |
|
||||||
|
| `requirements validate`, `show prepared`, `test` | All three, including `--llm-backend-namespace` |
|
||||||
|
|
||||||
|
Catalog namespace filters remain separate; configuration inspection has no
|
||||||
|
resource namespace selectors.
|
||||||
|
|
||||||
## PromptKit prepared-request preview
|
## PromptKit prepared-request preview
|
||||||
|
|
||||||
When `Suite.PrepareRequest` is present, `ckprompt.Command(suite)` installs
|
When `Suite.PrepareRequest` is present, `ckprompt.Command(suite)` installs
|
||||||
@@ -601,9 +620,12 @@ The command accepts:
|
|||||||
|
|
||||||
The `promptkit` namespace identifies the operation, so there is no built-in
|
The `promptkit` namespace identifies the operation, so there is no built-in
|
||||||
`--scope` flag. An explicitly empty profile or session value retains PromptKit's
|
`--scope` flag. An explicitly empty profile or session value retains PromptKit's
|
||||||
native empty-string meaning. Requirements inspection does not require a profile
|
native empty-string meaning. Profile selection establishes the reported profile
|
||||||
to be execution-ready. See the
|
identity rather than changing the discovered requirements. An enabled profile
|
||||||
[PromptKit v0.18.0 consumer guide](https://forge.maximumdirect.net/base-layer/promptkit/src/commit/d9f6aad30509e538fc73ea16710df3a3ec084502/docs/consumers/pkg-promptkit.md)
|
namespace qualifies an explicitly supplied short profile ID; it does not rewrite
|
||||||
|
the prompt's stored default reference. Requirements inspection does not require
|
||||||
|
the selected profile to be execution-ready. See the
|
||||||
|
[PromptKit v0.20.0 consumer guide](https://forge.maximumdirect.net/base-layer/promptkit/src/commit/8ff9aa3efdc9f16b9d2729e0a29ea083eb3c3eaf/docs/consumers/pkg-promptkit.md)
|
||||||
for native configuration, selection, and requirements behavior. The built-in
|
for native configuration, selection, and requirements behavior. The built-in
|
||||||
flags other than `--llm-var` are singleton bindings; when repeated, the last value
|
flags other than `--llm-var` are singleton bindings; when repeated, the last value
|
||||||
is used. Suite selectors retain their declared binding behavior.
|
is used. Suite selectors retain their declared binding behavior.
|
||||||
|
|||||||
@@ -339,6 +339,12 @@ same canonical request flags into their own input types. Each collection exposes
|
|||||||
individual handles and an `All` method, so a command can choose its applicable
|
individual handles and an `All` method, so a command can choose its applicable
|
||||||
subset. The application decides how to apply the resulting values to its request.
|
subset. The application decides how to apply the resulting values to its request.
|
||||||
|
|
||||||
|
`ckprompt.WithNamespaces` enables standard resource namespace selection from
|
||||||
|
application-supplied defaults. Loaders used with this option should leave view
|
||||||
|
selection to the adapter. Without it, a loader can supply its own engine view.
|
||||||
|
Direct callbacks receive the composed selection in their request. The
|
||||||
|
[CLI reference](../cli.md#resource-namespace-selection) lists applicable flags.
|
||||||
|
|
||||||
Catalog, named definition inspection, and requirements discovery do not render
|
Catalog, named definition inspection, and requirements discovery do not render
|
||||||
messages or load request artifacts. Concrete request validation follows native
|
messages or load request artifacts. Concrete request validation follows native
|
||||||
PromptKit preparation, which can resolve prompt/profile resources, load
|
PromptKit preparation, which can resolve prompt/profile resources, load
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
# Shared reporting and PromptKit v0.20.0 implementation plan
|
# Shared reporting and PromptKit v0.20.0 implementation plan
|
||||||
|
|
||||||
Status: implementation in progress; Stages 1–11 complete.
|
Status: implementation in progress; Stages 1–12 complete.
|
||||||
|
|
||||||
## Scope, authority, and execution
|
## Scope, authority, and execution
|
||||||
|
|
||||||
@@ -433,6 +433,11 @@ native result rather than asserting PromptKit's rendering algorithm.
|
|||||||
|
|
||||||
## Stage 12: Opt-in namespace composition
|
## Stage 12: Opt-in namespace composition
|
||||||
|
|
||||||
|
**Complete.** Opt-in namespace defaults and applicable selectors reach custom
|
||||||
|
callbacks and native engine views. The root, ckconfig, and ckprompt workspace
|
||||||
|
suites passed with Go 1.27.0; focused tests cover default composition, clearing,
|
||||||
|
applicability, loader views, and native error identity.
|
||||||
|
|
||||||
Add `WithNamespaces(suite, promptkit.Namespaces) Suite` and store explicit
|
Add `WithNamespaces(suite, promptkit.Namespaces) Suite` and store explicit
|
||||||
application defaults in an optional suite field. Add `Namespaces
|
application defaults in an optional suite field. Add `Namespaces
|
||||||
*promptkit.Namespaces` to applicable ckprompt request envelopes, including
|
*promptkit.Namespaces` to applicable ckprompt request envelopes, including
|
||||||
|
|||||||
@@ -19,6 +19,8 @@ type PromptRequest struct {
|
|||||||
Selection ckconfig.Selection
|
Selection ckconfig.Selection
|
||||||
// ID is the selected named prompt.
|
// ID is the selected named prompt.
|
||||||
ID string
|
ID string
|
||||||
|
// Namespaces selects the native engine view; nil preserves the loader view.
|
||||||
|
Namespaces *promptkit.Namespaces
|
||||||
}
|
}
|
||||||
|
|
||||||
// ProfileRequest selects one named profile for inspection.
|
// ProfileRequest selects one named profile for inspection.
|
||||||
@@ -27,6 +29,8 @@ type ProfileRequest struct {
|
|||||||
Selection ckconfig.Selection
|
Selection ckconfig.Selection
|
||||||
// ID is the selected named profile.
|
// ID is the selected named profile.
|
||||||
ID string
|
ID string
|
||||||
|
// Namespaces selects the native engine view; nil preserves the loader view.
|
||||||
|
Namespaces *promptkit.Namespaces
|
||||||
}
|
}
|
||||||
|
|
||||||
// BackendRequest selects one named backend for inspection.
|
// BackendRequest selects one named backend for inspection.
|
||||||
@@ -35,6 +39,8 @@ type BackendRequest struct {
|
|||||||
Selection ckconfig.Selection
|
Selection ckconfig.Selection
|
||||||
// ID is the selected named backend.
|
// ID is the selected named backend.
|
||||||
ID string
|
ID string
|
||||||
|
// Namespaces selects the native engine view; nil preserves the loader view.
|
||||||
|
Namespaces *promptkit.Namespaces
|
||||||
}
|
}
|
||||||
|
|
||||||
// CatalogRequest selects the configuration and native namespace filter for a
|
// CatalogRequest selects the configuration and native namespace filter for a
|
||||||
@@ -68,6 +74,8 @@ type RequirementsRequest struct {
|
|||||||
// discovery context. Profile and session strings retain PromptKit's
|
// discovery context. Profile and session strings retain PromptKit's
|
||||||
// empty-value semantics.
|
// empty-value semantics.
|
||||||
Inspection promptkit.RequirementInspectionRequest
|
Inspection promptkit.RequirementInspectionRequest
|
||||||
|
// Namespaces selects the native engine view; nil preserves the loader view.
|
||||||
|
Namespaces *promptkit.Namespaces
|
||||||
}
|
}
|
||||||
|
|
||||||
// Suite describes application-owned input, shared state, and optional catalog,
|
// Suite describes application-owned input, shared state, and optional catalog,
|
||||||
@@ -150,7 +158,8 @@ type Suite[I, S any] struct {
|
|||||||
// omits only this catalog command.
|
// omits only this catalog command.
|
||||||
ListCollections func(context.Context, ckconfig.Selection, I, S) (commandkit.Acquired[[]promptkit.CollectionInfo], error)
|
ListCollections func(context.Context, ckconfig.Selection, I, S) (commandkit.Acquired[[]promptkit.CollectionInfo], error)
|
||||||
|
|
||||||
issues []error
|
namespaces *promptkit.Namespaces
|
||||||
|
issues []error
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithRequestValidation attaches PromptKit-backed concrete request validation
|
// WithRequestValidation attaches PromptKit-backed concrete request validation
|
||||||
@@ -205,6 +214,12 @@ func WithRequestValidation[I, S any](
|
|||||||
return commandkit.Acquired[struct{}]{Diagnostics: messages.diagnostics, Explanation: messages.explanation}, fmt.Errorf("PromptKit request validation before native validation: %w", err)
|
return commandkit.Acquired[struct{}]{Diagnostics: messages.diagnostics, Explanation: messages.explanation}, fmt.Errorf("PromptKit request validation before native validation: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
engine, err = namespacedEngine(engine, request.Namespaces)
|
||||||
|
if err != nil {
|
||||||
|
messages = messages.withOperationError(err)
|
||||||
|
return commandkit.Acquired[struct{}]{Diagnostics: messages.diagnostics, Explanation: messages.explanation}, err
|
||||||
|
}
|
||||||
|
|
||||||
if err := engine.ValidateRequest(ctx, concreteRequest); err != nil {
|
if err := engine.ValidateRequest(ctx, concreteRequest); err != nil {
|
||||||
messages = messages.withOperationError(err)
|
messages = messages.withOperationError(err)
|
||||||
return commandkit.Acquired[struct{}]{Diagnostics: messages.diagnostics, Explanation: messages.explanation}, err
|
return commandkit.Acquired[struct{}]{Diagnostics: messages.diagnostics, Explanation: messages.explanation}, err
|
||||||
@@ -384,6 +399,11 @@ func FromEngine[I, S any](load func(context.Context, ckconfig.Selection, I, S) (
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return commandkit.Acquired[*promptkit.PromptInspection]{Diagnostics: messages.diagnostics, Explanation: messages.explanation}, err
|
return commandkit.Acquired[*promptkit.PromptInspection]{Diagnostics: messages.diagnostics, Explanation: messages.explanation}, err
|
||||||
}
|
}
|
||||||
|
engine, err = namespacedEngine(engine, request.Namespaces)
|
||||||
|
if err != nil {
|
||||||
|
messages = messages.withOperationError(err)
|
||||||
|
return commandkit.Acquired[*promptkit.PromptInspection]{Diagnostics: messages.diagnostics, Explanation: messages.explanation}, err
|
||||||
|
}
|
||||||
inspection, err := engine.InspectPrompt(ctx, request.ID)
|
inspection, err := engine.InspectPrompt(ctx, request.ID)
|
||||||
messages = messages.withOperationError(err)
|
messages = messages.withOperationError(err)
|
||||||
return commandkit.Acquired[*promptkit.PromptInspection]{Value: inspection, Diagnostics: messages.diagnostics, Explanation: messages.explanation}, err
|
return commandkit.Acquired[*promptkit.PromptInspection]{Value: inspection, Diagnostics: messages.diagnostics, Explanation: messages.explanation}, err
|
||||||
@@ -393,6 +413,11 @@ func FromEngine[I, S any](load func(context.Context, ckconfig.Selection, I, S) (
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return commandkit.Acquired[*promptkit.ProfileInspection]{Diagnostics: messages.diagnostics, Explanation: messages.explanation}, err
|
return commandkit.Acquired[*promptkit.ProfileInspection]{Diagnostics: messages.diagnostics, Explanation: messages.explanation}, err
|
||||||
}
|
}
|
||||||
|
engine, err = namespacedEngine(engine, request.Namespaces)
|
||||||
|
if err != nil {
|
||||||
|
messages = messages.withOperationError(err)
|
||||||
|
return commandkit.Acquired[*promptkit.ProfileInspection]{Diagnostics: messages.diagnostics, Explanation: messages.explanation}, err
|
||||||
|
}
|
||||||
inspection, err := engine.InspectProfile(ctx, request.ID)
|
inspection, err := engine.InspectProfile(ctx, request.ID)
|
||||||
messages = messages.withOperationError(err)
|
messages = messages.withOperationError(err)
|
||||||
return commandkit.Acquired[*promptkit.ProfileInspection]{Value: inspection, Diagnostics: messages.diagnostics, Explanation: messages.explanation}, err
|
return commandkit.Acquired[*promptkit.ProfileInspection]{Value: inspection, Diagnostics: messages.diagnostics, Explanation: messages.explanation}, err
|
||||||
@@ -402,6 +427,11 @@ func FromEngine[I, S any](load func(context.Context, ckconfig.Selection, I, S) (
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return commandkit.Acquired[*promptkit.BackendInspection]{Diagnostics: messages.diagnostics, Explanation: messages.explanation}, err
|
return commandkit.Acquired[*promptkit.BackendInspection]{Diagnostics: messages.diagnostics, Explanation: messages.explanation}, err
|
||||||
}
|
}
|
||||||
|
engine, err = namespacedEngine(engine, request.Namespaces)
|
||||||
|
if err != nil {
|
||||||
|
messages = messages.withOperationError(err)
|
||||||
|
return commandkit.Acquired[*promptkit.BackendInspection]{Diagnostics: messages.diagnostics, Explanation: messages.explanation}, err
|
||||||
|
}
|
||||||
inspection, err := engine.InspectBackend(ctx, request.ID)
|
inspection, err := engine.InspectBackend(ctx, request.ID)
|
||||||
messages = messages.withOperationError(err)
|
messages = messages.withOperationError(err)
|
||||||
return commandkit.Acquired[*promptkit.BackendInspection]{Value: inspection, Diagnostics: messages.diagnostics, Explanation: messages.explanation}, err
|
return commandkit.Acquired[*promptkit.BackendInspection]{Value: inspection, Diagnostics: messages.diagnostics, Explanation: messages.explanation}, err
|
||||||
@@ -411,6 +441,11 @@ func FromEngine[I, S any](load func(context.Context, ckconfig.Selection, I, S) (
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
return commandkit.Acquired[*promptkit.RequirementInspection]{Diagnostics: messages.diagnostics, Explanation: messages.explanation}, err
|
return commandkit.Acquired[*promptkit.RequirementInspection]{Diagnostics: messages.diagnostics, Explanation: messages.explanation}, err
|
||||||
}
|
}
|
||||||
|
engine, err = namespacedEngine(engine, request.Namespaces)
|
||||||
|
if err != nil {
|
||||||
|
messages = messages.withOperationError(err)
|
||||||
|
return commandkit.Acquired[*promptkit.RequirementInspection]{Diagnostics: messages.diagnostics, Explanation: messages.explanation}, err
|
||||||
|
}
|
||||||
inspection, err := engine.InspectRequirements(ctx, request.Inspection)
|
inspection, err := engine.InspectRequirements(ctx, request.Inspection)
|
||||||
messages = messages.withOperationError(err)
|
messages = messages.withOperationError(err)
|
||||||
return commandkit.Acquired[*promptkit.RequirementInspection]{Value: inspection, Diagnostics: messages.diagnostics, Explanation: messages.explanation}, err
|
return commandkit.Acquired[*promptkit.RequirementInspection]{Value: inspection, Diagnostics: messages.diagnostics, Explanation: messages.explanation}, err
|
||||||
|
|||||||
@@ -12,10 +12,11 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type definitionInput[I any] struct {
|
type definitionInput[I any] struct {
|
||||||
selection ckconfig.Selection
|
namespaces namespaceInput
|
||||||
id string
|
selection ckconfig.Selection
|
||||||
captured commandkit.FlagValues[I]
|
id string
|
||||||
selected I
|
captured commandkit.FlagValues[I]
|
||||||
|
selected I
|
||||||
}
|
}
|
||||||
|
|
||||||
type catalogInput[I any] struct {
|
type catalogInput[I any] struct {
|
||||||
@@ -29,6 +30,7 @@ type catalogInput[I any] struct {
|
|||||||
}
|
}
|
||||||
|
|
||||||
type requirementsInput[I any] struct {
|
type requirementsInput[I any] struct {
|
||||||
|
namespaces namespaceInput
|
||||||
selection ckconfig.Selection
|
selection ckconfig.Selection
|
||||||
inspection promptkit.RequirementInspectionRequest
|
inspection promptkit.RequirementInspectionRequest
|
||||||
resources ResourceInput
|
resources ResourceInput
|
||||||
@@ -244,6 +246,10 @@ func newDefinitionCommand[I, S any](suite Suite[I, S], name string) commandkit.C
|
|||||||
(*input).selection.Overlay = value
|
(*input).selection.Overlay = value
|
||||||
}),
|
}),
|
||||||
)
|
)
|
||||||
|
if suite.namespaces != nil {
|
||||||
|
flags = append(flags, namespaceFlags(func(input **definitionInput[I]) *namespaceInput { return &(*input).namespaces }, name)...)
|
||||||
|
}
|
||||||
|
|
||||||
spec := commandkit.CommandSpec[*definitionInput[I]]{
|
spec := commandkit.CommandSpec[*definitionInput[I]]{
|
||||||
Name: name,
|
Name: name,
|
||||||
Summary: "Inspect a named PromptKit " + name + ".",
|
Summary: "Inspect a named PromptKit " + name + ".",
|
||||||
@@ -292,9 +298,14 @@ func newRequirementsCommand[I, S any](suite Suite[I, S]) commandkit.Command {
|
|||||||
inputs := NewPromptInputFlags(func(input **requirementsInput[I]) *PromptInputs { return &(*input).inputs })
|
inputs := NewPromptInputFlags(func(input **requirementsInput[I]) *PromptInputs { return &(*input).inputs })
|
||||||
flags = append(flags, resources.Profile, resources.SessionID, inputs.Variable)
|
flags = append(flags, resources.Profile, resources.SessionID, inputs.Variable)
|
||||||
|
|
||||||
|
if suite.namespaces != nil {
|
||||||
|
flags = append(flags, namespaceFlags(func(input **requirementsInput[I]) *namespaceInput { return &(*input).namespaces }, "prompt", "profile")...)
|
||||||
|
}
|
||||||
|
|
||||||
spec := commandkit.CommandSpec[*requirementsInput[I]]{
|
spec := commandkit.CommandSpec[*requirementsInput[I]]{
|
||||||
Name: "show",
|
Name: "show",
|
||||||
Summary: "Inspect requirements for a named PromptKit prompt.",
|
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.",
|
||||||
NewInput: func() *requirementsInput[I] {
|
NewInput: func() *requirementsInput[I] {
|
||||||
return &requirementsInput[I]{}
|
return &requirementsInput[I]{}
|
||||||
},
|
},
|
||||||
@@ -398,21 +409,21 @@ func runDefinitionInspection[I, S any](invocation commandkit.Invocation, suite S
|
|||||||
switch kind {
|
switch kind {
|
||||||
case "prompt":
|
case "prompt":
|
||||||
var result commandkit.Acquired[*promptkit.PromptInspection]
|
var result commandkit.Acquired[*promptkit.PromptInspection]
|
||||||
result, err = suite.InspectPrompt(invocation.Context, PromptRequest{Selection: input.selection, ID: input.id}, input.selected, state)
|
result, err = suite.InspectPrompt(invocation.Context, PromptRequest{Selection: input.selection, ID: input.id, Namespaces: selectedNamespaces(suite.namespaces, input.namespaces)}, input.selected, state)
|
||||||
if result.Value != nil {
|
if result.Value != nil {
|
||||||
value = result.Value
|
value = result.Value
|
||||||
}
|
}
|
||||||
diagnostics, explanation = result.Diagnostics, result.Explanation
|
diagnostics, explanation = result.Diagnostics, result.Explanation
|
||||||
case "profile":
|
case "profile":
|
||||||
var result commandkit.Acquired[*promptkit.ProfileInspection]
|
var result commandkit.Acquired[*promptkit.ProfileInspection]
|
||||||
result, err = suite.InspectProfile(invocation.Context, ProfileRequest{Selection: input.selection, ID: input.id}, input.selected, state)
|
result, err = suite.InspectProfile(invocation.Context, ProfileRequest{Selection: input.selection, ID: input.id, Namespaces: selectedNamespaces(suite.namespaces, input.namespaces)}, input.selected, state)
|
||||||
if result.Value != nil {
|
if result.Value != nil {
|
||||||
value = result.Value
|
value = result.Value
|
||||||
}
|
}
|
||||||
diagnostics, explanation = result.Diagnostics, result.Explanation
|
diagnostics, explanation = result.Diagnostics, result.Explanation
|
||||||
case "backend":
|
case "backend":
|
||||||
var result commandkit.Acquired[*promptkit.BackendInspection]
|
var result commandkit.Acquired[*promptkit.BackendInspection]
|
||||||
result, err = suite.InspectBackend(invocation.Context, BackendRequest{Selection: input.selection, ID: input.id}, input.selected, state)
|
result, err = suite.InspectBackend(invocation.Context, BackendRequest{Selection: input.selection, ID: input.id, Namespaces: selectedNamespaces(suite.namespaces, input.namespaces)}, input.selected, state)
|
||||||
if result.Value != nil {
|
if result.Value != nil {
|
||||||
value = result.Value
|
value = result.Value
|
||||||
}
|
}
|
||||||
@@ -518,7 +529,7 @@ func runRequirementsInspection[I, S any](invocation commandkit.Invocation, suite
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
request := RequirementsRequest{Selection: input.selection, Inspection: input.inspection}
|
request := RequirementsRequest{Selection: input.selection, Inspection: input.inspection, Namespaces: selectedNamespaces(suite.namespaces, input.namespaces)}
|
||||||
acquired, err := suite.InspectRequirements(invocation.Context, request, input.selected, state)
|
acquired, err := suite.InspectRequirements(invocation.Context, request, input.selected, state)
|
||||||
queuePromptDiagnostics(invocation.Reporter(), acquired.Diagnostics)
|
queuePromptDiagnostics(invocation.Reporter(), acquired.Diagnostics)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
69
integrations/ckprompt/namespaces.go
Normal file
69
integrations/ckprompt/namespaces.go
Normal file
@@ -0,0 +1,69 @@
|
|||||||
|
package ckprompt
|
||||||
|
|
||||||
|
import (
|
||||||
|
commandkit "go.maximumdirect.net/commandkit"
|
||||||
|
promptkit "go.maximumdirect.net/promptkit"
|
||||||
|
)
|
||||||
|
|
||||||
|
// WithNamespaces enables standard resource namespace selection with explicit
|
||||||
|
// defaults. Supplied CLI namespace flags replace only the corresponding default.
|
||||||
|
// Loaders used with this option should leave namespace selection to the adapter.
|
||||||
|
func WithNamespaces[I, S any](suite Suite[I, S], defaults promptkit.Namespaces) Suite[I, S] {
|
||||||
|
suite.namespaces = &defaults
|
||||||
|
return suite
|
||||||
|
}
|
||||||
|
|
||||||
|
type namespaceInput struct {
|
||||||
|
prompt, profile, backend commandkit.Supplied[string]
|
||||||
|
}
|
||||||
|
|
||||||
|
func namespaceFlags[I any](destination func(*I) *namespaceInput, kinds ...string) []commandkit.Flag[I] {
|
||||||
|
flags := make([]commandkit.Flag[I], 0, len(kinds))
|
||||||
|
for _, kind := range kinds {
|
||||||
|
var meta commandkit.FlagMeta
|
||||||
|
var field func(*namespaceInput) *commandkit.Supplied[string]
|
||||||
|
switch kind {
|
||||||
|
case "prompt":
|
||||||
|
meta = namespaceFlagDefinitions.prompt.meta
|
||||||
|
field = func(input *namespaceInput) *commandkit.Supplied[string] { return &input.prompt }
|
||||||
|
case "profile":
|
||||||
|
meta = namespaceFlagDefinitions.profile.meta
|
||||||
|
field = func(input *namespaceInput) *commandkit.Supplied[string] { return &input.profile }
|
||||||
|
case "backend":
|
||||||
|
meta = namespaceFlagDefinitions.backend.meta
|
||||||
|
field = func(input *namespaceInput) *commandkit.Supplied[string] { return &input.backend }
|
||||||
|
}
|
||||||
|
flags = append(flags, commandkit.ValueFlag(meta, (*string)(nil), parseDefinitionString, func(input *I, value commandkit.Supplied[string]) { *field(destination(input)) = value }))
|
||||||
|
}
|
||||||
|
return flags
|
||||||
|
}
|
||||||
|
|
||||||
|
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"}},
|
||||||
|
}
|
||||||
|
|
||||||
|
func selectedNamespaces(defaults *promptkit.Namespaces, selected namespaceInput) *promptkit.Namespaces {
|
||||||
|
if defaults == nil {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
value := *defaults
|
||||||
|
if selected.prompt.Set {
|
||||||
|
value.Prompt = selected.prompt.Value
|
||||||
|
}
|
||||||
|
if selected.profile.Set {
|
||||||
|
value.Profile = selected.profile.Value
|
||||||
|
}
|
||||||
|
if selected.backend.Set {
|
||||||
|
value.Backend = selected.backend.Value
|
||||||
|
}
|
||||||
|
return &value
|
||||||
|
}
|
||||||
|
|
||||||
|
func namespacedEngine(engine *promptkit.Engine, namespaces *promptkit.Namespaces) (*promptkit.Engine, error) {
|
||||||
|
if namespaces == nil {
|
||||||
|
return engine, nil
|
||||||
|
}
|
||||||
|
return engine.WithNamespaces(*namespaces)
|
||||||
|
}
|
||||||
146
integrations/ckprompt/namespaces_test.go
Normal file
146
integrations/ckprompt/namespaces_test.go
Normal file
@@ -0,0 +1,146 @@
|
|||||||
|
package ckprompt
|
||||||
|
|
||||||
|
import (
|
||||||
|
"context"
|
||||||
|
"errors"
|
||||||
|
"io"
|
||||||
|
"reflect"
|
||||||
|
"testing"
|
||||||
|
|
||||||
|
"go.maximumdirect.net/ckconfig"
|
||||||
|
commandkit "go.maximumdirect.net/commandkit"
|
||||||
|
promptkit "go.maximumdirect.net/promptkit"
|
||||||
|
)
|
||||||
|
|
||||||
|
func TestNamespaceSelectionAndApplicability(t *testing.T) {
|
||||||
|
var got *promptkit.Namespaces
|
||||||
|
var id string
|
||||||
|
suite := Suite[struct{}, struct{}]{
|
||||||
|
InspectPrompt: func(_ context.Context, req PromptRequest, _, _ struct{}) (commandkit.Acquired[*promptkit.PromptInspection], error) {
|
||||||
|
got, id = req.Namespaces, req.ID
|
||||||
|
return commandkit.Acquired[*promptkit.PromptInspection]{Value: &promptkit.PromptInspection{}}, nil
|
||||||
|
},
|
||||||
|
InspectProfile: func(_ context.Context, req ProfileRequest, _, _ struct{}) (commandkit.Acquired[*promptkit.ProfileInspection], error) {
|
||||||
|
got, id = req.Namespaces, req.ID
|
||||||
|
return commandkit.Acquired[*promptkit.ProfileInspection]{Value: &promptkit.ProfileInspection{}}, nil
|
||||||
|
},
|
||||||
|
InspectBackend: func(_ context.Context, req BackendRequest, _, _ struct{}) (commandkit.Acquired[*promptkit.BackendInspection], error) {
|
||||||
|
got, id = req.Namespaces, req.ID
|
||||||
|
return commandkit.Acquired[*promptkit.BackendInspection]{Value: &promptkit.BackendInspection{}}, nil
|
||||||
|
},
|
||||||
|
InspectRequirements: func(_ context.Context, req RequirementsRequest, _, _ struct{}) (commandkit.Acquired[*promptkit.RequirementInspection], error) {
|
||||||
|
got, id = req.Namespaces, req.Inspection.PromptID
|
||||||
|
return commandkit.Acquired[*promptkit.RequirementInspection]{Value: &promptkit.RequirementInspection{}}, nil
|
||||||
|
},
|
||||||
|
ValidateRequest: func(_ context.Context, req ValidationRequest, _, _ struct{}) (commandkit.Acquired[struct{}], error) {
|
||||||
|
got, id = req.Namespaces, req.Request.PromptID
|
||||||
|
return commandkit.Acquired[struct{}]{}, nil
|
||||||
|
},
|
||||||
|
PrepareRequest: func(_ context.Context, req PreparationRequest, _, _ struct{}) (commandkit.Acquired[*promptkit.PreparedRun], error) {
|
||||||
|
got, id = req.Namespaces, req.Request.PromptID
|
||||||
|
return commandkit.Acquired[*promptkit.PreparedRun]{Value: &promptkit.PreparedRun{}}, nil
|
||||||
|
},
|
||||||
|
SmokeTest: func(_ context.Context, req SmokeRequest, _, _ struct{}) (commandkit.Acquired[*promptkit.SmokeTestReport], error) {
|
||||||
|
got = req.Namespaces
|
||||||
|
return commandkit.Acquired[*promptkit.SmokeTestReport]{Value: &promptkit.SmokeTestReport{}}, nil
|
||||||
|
},
|
||||||
|
ListPrompts: func(context.Context, CatalogRequest, struct{}, struct{}) (commandkit.Acquired[[]promptkit.PromptIdentity], error) {
|
||||||
|
return commandkit.Acquired[[]promptkit.PromptIdentity]{}, nil
|
||||||
|
},
|
||||||
|
}
|
||||||
|
defaults := promptkit.Namespaces{Prompt: "prompt-default", Profile: "profile-default", Backend: "backend-default"}
|
||||||
|
app := newPromptTestApp(t, Command(WithNamespaces(suite, defaults)))
|
||||||
|
tests := []struct {
|
||||||
|
args []string
|
||||||
|
allowed, forbidden string
|
||||||
|
expected promptkit.Namespaces
|
||||||
|
}{
|
||||||
|
{[]string{"show", "prompt", "qualified/name"}, "--llm-prompt-namespace=", "--llm-profile-namespace=x", promptkit.Namespaces{Profile: defaults.Profile, Backend: defaults.Backend}},
|
||||||
|
{[]string{"show", "profile", "qualified/name"}, "--llm-profile-namespace=other", "--llm-prompt-namespace=x", promptkit.Namespaces{Prompt: defaults.Prompt, Profile: "other", Backend: defaults.Backend}},
|
||||||
|
{[]string{"show", "backend", "qualified/name"}, "--llm-backend-namespace=other", "--llm-profile-namespace=x", promptkit.Namespaces{Prompt: defaults.Prompt, Profile: defaults.Profile, Backend: "other"}},
|
||||||
|
{[]string{"requirements", "show", "qualified/name"}, "--llm-profile-namespace=other", "--llm-backend-namespace=x", promptkit.Namespaces{Prompt: defaults.Prompt, Profile: "other", Backend: defaults.Backend}},
|
||||||
|
{[]string{"requirements", "validate", "qualified/name"}, "--llm-backend-namespace=other", "--llm-prompt=invalid", promptkit.Namespaces{Prompt: defaults.Prompt, Profile: defaults.Profile, Backend: "other"}},
|
||||||
|
{[]string{"show", "prepared", "qualified/name"}, "--llm-prompt-namespace=", "--llm-backend=invalid", promptkit.Namespaces{Profile: defaults.Profile, Backend: defaults.Backend}},
|
||||||
|
{[]string{"test", "authentication"}, "--llm-backend-namespace=other", "--llm-session-id=invalid", promptkit.Namespaces{Prompt: defaults.Prompt, Profile: defaults.Profile, Backend: "other"}},
|
||||||
|
}
|
||||||
|
for _, test := range tests {
|
||||||
|
got = nil
|
||||||
|
id = ""
|
||||||
|
args := append(append([]string{"promptkit"}, test.args...), test.allowed)
|
||||||
|
result := app.Execute(context.Background(), args, commandkit.Streams{Out: io.Discard, Err: io.Discard})
|
||||||
|
if result.Kind != commandkit.OutcomeSuccess || got == nil || *got != test.expected || (test.args[0] != "test" && id != "qualified/name") {
|
||||||
|
t.Fatalf("%v: result=%#v got=%#v id=%q", args, result, got, id)
|
||||||
|
}
|
||||||
|
args = append(append([]string{"promptkit"}, test.args...), test.forbidden)
|
||||||
|
if result := app.Execute(context.Background(), args, commandkit.Streams{Out: io.Discard, Err: io.Discard}); result.Kind != commandkit.OutcomeUsage {
|
||||||
|
t.Fatalf("%v: %#v", args, result)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
unscoped := newPromptTestApp(t, Command(suite))
|
||||||
|
result := unscoped.Execute(context.Background(), []string{"promptkit", "show", "prompt", "name"}, commandkit.Streams{Out: io.Discard, Err: io.Discard})
|
||||||
|
if result.Kind != commandkit.OutcomeSuccess || got != nil {
|
||||||
|
t.Fatalf("without option: %#v %#v", result, got)
|
||||||
|
}
|
||||||
|
result = unscoped.Execute(context.Background(), []string{"promptkit", "show", "prompt", "name", "--llm-prompt-namespace=x"}, commandkit.Streams{Out: io.Discard, Err: io.Discard})
|
||||||
|
if result.Kind != commandkit.OutcomeUsage {
|
||||||
|
t.Fatalf("unexpected flag without option: %#v", result)
|
||||||
|
}
|
||||||
|
result = app.Execute(context.Background(), []string{"promptkit", "list", "prompts", "--llm-prompt-namespace=x"}, commandkit.Streams{Out: io.Discard, Err: io.Discard})
|
||||||
|
if result.Kind != commandkit.OutcomeUsage {
|
||||||
|
t.Fatalf("namespace selection on catalog: %#v", result)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestNativeNamespaceViewAndErrorForwarding(t *testing.T) {
|
||||||
|
engine := adapterEngine(t)
|
||||||
|
load := func(context.Context, ckconfig.Selection, struct{}, struct{}) (*promptkit.Engine, error) {
|
||||||
|
return engine, nil
|
||||||
|
}
|
||||||
|
namespaces := promptkit.Namespaces{Prompt: "team"}
|
||||||
|
view, err := engine.WithNamespaces(namespaces)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
want, err := view.InspectProfile(context.Background(), "default")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
suite := FromEngine(load)
|
||||||
|
got, err := suite.InspectProfile(context.Background(), ProfileRequest{ID: "default", Namespaces: &namespaces}, struct{}{}, struct{}{})
|
||||||
|
if err != nil || !reflect.DeepEqual(got.Value, want) {
|
||||||
|
t.Fatalf("native view: %#v %v", got, err)
|
||||||
|
}
|
||||||
|
invalid := promptkit.Namespaces{Prompt: "invalid/name"}
|
||||||
|
_, nativeErr := engine.WithNamespaces(invalid)
|
||||||
|
_, err = suite.InspectProfile(context.Background(), ProfileRequest{ID: "default", Namespaces: &invalid}, struct{}{}, struct{}{})
|
||||||
|
if nativeErr == nil || !errors.Is(err, promptkit.ErrInvalidConfig) {
|
||||||
|
t.Fatalf("namespace error: native=%v forwarded=%v", nativeErr, err)
|
||||||
|
}
|
||||||
|
validation := WithRequestValidation(Suite[struct{}, struct{}]{}, load, nil)
|
||||||
|
_, err = validation.ValidateRequest(context.Background(), ValidationRequest{Namespaces: &invalid}, struct{}{}, struct{}{})
|
||||||
|
if !errors.Is(err, promptkit.ErrInvalidConfig) {
|
||||||
|
t.Fatalf("validation namespace error: %v", err)
|
||||||
|
}
|
||||||
|
preparation := WithRequestPreparation(Suite[struct{}, struct{}]{}, load, nil)
|
||||||
|
_, err = preparation.PrepareRequest(context.Background(), PreparationRequest{Namespaces: &invalid}, struct{}{}, struct{}{})
|
||||||
|
if !errors.Is(err, promptkit.ErrInvalidConfig) {
|
||||||
|
t.Fatalf("preparation namespace error: %v", err)
|
||||||
|
}
|
||||||
|
smoke := WithSmokeTesting(Suite[struct{}, struct{}]{}, load, nil)
|
||||||
|
_, err = smoke.SmokeTest(context.Background(), SmokeRequest{Namespaces: &invalid}, struct{}{}, struct{}{})
|
||||||
|
if !errors.Is(err, promptkit.ErrInvalidConfig) {
|
||||||
|
t.Fatalf("smoke namespace error: %v", err)
|
||||||
|
}
|
||||||
|
preexisting, err := engine.WithNamespaces(promptkit.Namespaces{Profile: "other"})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
_, nativeErr = preexisting.InspectProfile(context.Background(), "default")
|
||||||
|
custom := FromEngine(func(context.Context, ckconfig.Selection, struct{}, struct{}) (*promptkit.Engine, error) {
|
||||||
|
return preexisting, nil
|
||||||
|
})
|
||||||
|
_, err = custom.InspectProfile(context.Background(), ProfileRequest{ID: "default"}, struct{}{}, struct{}{})
|
||||||
|
if !errors.Is(nativeErr, promptkit.ErrProfileNotFound) || !errors.Is(err, promptkit.ErrProfileNotFound) {
|
||||||
|
t.Fatalf("loader view: native=%v forwarded=%v", nativeErr, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -17,6 +17,8 @@ type PreparationRequest struct {
|
|||||||
Selection ckconfig.Selection
|
Selection ckconfig.Selection
|
||||||
// Request contains the native seed request populated by command inputs.
|
// Request contains the native seed request populated by command inputs.
|
||||||
Request promptkit.RunRequest
|
Request promptkit.RunRequest
|
||||||
|
// Namespaces selects the native engine view; nil preserves the loader view.
|
||||||
|
Namespaces *promptkit.Namespaces
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithRequestPreparation attaches native prepared-request inspection. The
|
// WithRequestPreparation attaches native prepared-request inspection. The
|
||||||
@@ -55,6 +57,11 @@ func WithRequestPreparation[I, S any](
|
|||||||
if err := promptKitContextError(ctx); err != nil {
|
if err := promptKitContextError(ctx); err != nil {
|
||||||
return commandkit.Acquired[*promptkit.PreparedRun]{Diagnostics: messages.diagnostics, Explanation: messages.explanation}, fmt.Errorf("PromptKit request preparation before native preparation: %w", err)
|
return commandkit.Acquired[*promptkit.PreparedRun]{Diagnostics: messages.diagnostics, Explanation: messages.explanation}, fmt.Errorf("PromptKit request preparation before native preparation: %w", err)
|
||||||
}
|
}
|
||||||
|
engine, err = namespacedEngine(engine, request.Namespaces)
|
||||||
|
if err != nil {
|
||||||
|
messages = messages.withOperationError(err)
|
||||||
|
return commandkit.Acquired[*promptkit.PreparedRun]{Diagnostics: messages.diagnostics, Explanation: messages.explanation}, err
|
||||||
|
}
|
||||||
prepared, err := engine.Prepare(ctx, concrete)
|
prepared, err := engine.Prepare(ctx, concrete)
|
||||||
messages = messages.withOperationError(err)
|
messages = messages.withOperationError(err)
|
||||||
return commandkit.Acquired[*promptkit.PreparedRun]{Value: prepared, Diagnostics: messages.diagnostics, Explanation: messages.explanation}, err
|
return commandkit.Acquired[*promptkit.PreparedRun]{Value: prepared, Diagnostics: messages.diagnostics, Explanation: messages.explanation}, err
|
||||||
@@ -84,7 +91,7 @@ func runRequestPreparation[I, S any](invocation commandkit.Invocation, suite Sui
|
|||||||
if err := promptKitContextError(invocation.Context); err != nil {
|
if err := promptKitContextError(invocation.Context); err != nil {
|
||||||
return definitionFailure("PromptKit request preparation was canceled.", commandkit.Explanation{}, err)
|
return definitionFailure("PromptKit request preparation was canceled.", commandkit.Explanation{}, err)
|
||||||
}
|
}
|
||||||
request := PreparationRequest{Selection: input.request.Selection, Request: input.request.Request}
|
request := PreparationRequest{Selection: input.request.Selection, Request: input.request.Request, Namespaces: input.request.Namespaces}
|
||||||
acquired, err := suite.PrepareRequest(invocation.Context, request, input.selected, state)
|
acquired, err := suite.PrepareRequest(invocation.Context, request, input.selected, state)
|
||||||
queuePromptDiagnostics(invocation.Reporter(), acquired.Diagnostics)
|
queuePromptDiagnostics(invocation.Reporter(), acquired.Diagnostics)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -18,6 +18,8 @@ type SmokeRequest struct {
|
|||||||
Selection ckconfig.Selection
|
Selection ckconfig.Selection
|
||||||
// Request contains the native smoke-test operation and its selected inputs.
|
// Request contains the native smoke-test operation and its selected inputs.
|
||||||
Request promptkit.SmokeTestRequest
|
Request promptkit.SmokeTestRequest
|
||||||
|
// Namespaces selects the native engine view; nil preserves the loader view.
|
||||||
|
Namespaces *promptkit.Namespaces
|
||||||
}
|
}
|
||||||
|
|
||||||
// WithSmokeTesting attaches PromptKit-backed smoke testing to suite while
|
// WithSmokeTesting attaches PromptKit-backed smoke testing to suite while
|
||||||
@@ -65,6 +67,11 @@ func WithSmokeTesting[I, S any](
|
|||||||
return commandkit.Acquired[*promptkit.SmokeTestReport]{Diagnostics: messages.diagnostics, Explanation: messages.explanation}, fmt.Errorf("PromptKit smoke test before native operation: %w", err)
|
return commandkit.Acquired[*promptkit.SmokeTestReport]{Diagnostics: messages.diagnostics, Explanation: messages.explanation}, fmt.Errorf("PromptKit smoke test before native operation: %w", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
engine, err = namespacedEngine(engine, request.Namespaces)
|
||||||
|
if err != nil {
|
||||||
|
messages = messages.withOperationError(err)
|
||||||
|
return commandkit.Acquired[*promptkit.SmokeTestReport]{Diagnostics: messages.diagnostics, Explanation: messages.explanation}, err
|
||||||
|
}
|
||||||
report, err := engine.SmokeTest(ctx, concreteRequest)
|
report, err := engine.SmokeTest(ctx, concreteRequest)
|
||||||
messages = messages.withOperationError(err)
|
messages = messages.withOperationError(err)
|
||||||
return commandkit.Acquired[*promptkit.SmokeTestReport]{Value: report, Diagnostics: messages.diagnostics, Explanation: messages.explanation}, err
|
return commandkit.Acquired[*promptkit.SmokeTestReport]{Value: report, Diagnostics: messages.diagnostics, Explanation: messages.explanation}, err
|
||||||
|
|||||||
@@ -11,13 +11,14 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type smokeCommandInput[I any] struct {
|
type smokeCommandInput[I any] struct {
|
||||||
selection ckconfig.Selection
|
namespaces namespaceInput
|
||||||
kind string
|
selection ckconfig.Selection
|
||||||
request promptkit.SmokeTestRequest
|
kind string
|
||||||
execution ExecutionInput
|
request promptkit.SmokeTestRequest
|
||||||
resources ResourceInput
|
execution ExecutionInput
|
||||||
captured commandkit.FlagValues[I]
|
resources ResourceInput
|
||||||
selected I
|
captured commandkit.FlagValues[I]
|
||||||
|
selected I
|
||||||
}
|
}
|
||||||
|
|
||||||
func newSmokeTestCommand[I, S any](suite Suite[I, S]) commandkit.Command {
|
func newSmokeTestCommand[I, S any](suite Suite[I, S]) commandkit.Command {
|
||||||
@@ -43,6 +44,10 @@ func newSmokeTestCommand[I, S any](suite Suite[I, S]) commandkit.Command {
|
|||||||
flags = append(flags, resources.Backend, resources.Prompt, resources.Profile)
|
flags = append(flags, resources.Backend, resources.Prompt, resources.Profile)
|
||||||
flags = append(flags, execution.All()...)
|
flags = append(flags, execution.All()...)
|
||||||
|
|
||||||
|
if suite.namespaces != nil {
|
||||||
|
flags = append(flags, namespaceFlags(func(input **smokeCommandInput[I]) *namespaceInput { return &(*input).namespaces }, "prompt", "profile", "backend")...)
|
||||||
|
}
|
||||||
|
|
||||||
return commandkit.NewCommand(commandkit.CommandSpec[*smokeCommandInput[I]]{
|
return commandkit.NewCommand(commandkit.CommandSpec[*smokeCommandInput[I]]{
|
||||||
Name: "test",
|
Name: "test",
|
||||||
Summary: "Run one PromptKit smoke test.",
|
Summary: "Run one PromptKit smoke test.",
|
||||||
@@ -94,7 +99,7 @@ func runSmokeTest[I, S any](invocation commandkit.Invocation, suite Suite[I, S],
|
|||||||
return runSmokeAggregate(invocation, suite, input, state)
|
return runSmokeAggregate(invocation, suite, input, state)
|
||||||
}
|
}
|
||||||
|
|
||||||
request := SmokeRequest{Selection: input.selection, Request: input.request}
|
request := SmokeRequest{Selection: input.selection, Request: input.request, Namespaces: selectedNamespaces(suite.namespaces, input.namespaces)}
|
||||||
acquired, operationErr := suite.SmokeTest(invocation.Context, request, input.selected, state)
|
acquired, operationErr := suite.SmokeTest(invocation.Context, request, input.selected, state)
|
||||||
queuePromptDiagnostics(invocation.Reporter(), acquired.Diagnostics)
|
queuePromptDiagnostics(invocation.Reporter(), acquired.Diagnostics)
|
||||||
if acquired.Value == nil && operationErr == nil {
|
if acquired.Value == nil && operationErr == nil {
|
||||||
@@ -143,7 +148,7 @@ func runSmokeAggregate[I, S any](invocation commandkit.Invocation, suite Suite[I
|
|||||||
}
|
}
|
||||||
|
|
||||||
seed := smokeRequestForKind(input.request, kind)
|
seed := smokeRequestForKind(input.request, kind)
|
||||||
acquired, operationErr := suite.SmokeTest(invocation.Context, SmokeRequest{Selection: input.selection, Request: seed}, input.selected, state)
|
acquired, operationErr := suite.SmokeTest(invocation.Context, SmokeRequest{Selection: input.selection, Request: seed, Namespaces: selectedNamespaces(suite.namespaces, input.namespaces)}, input.selected, state)
|
||||||
if acquired.Value == nil && operationErr == nil {
|
if acquired.Value == nil && operationErr == nil {
|
||||||
operationErr = errors.New("PromptKit smoke test returned neither a report nor an error")
|
operationErr = errors.New("PromptKit smoke test returned neither a report nor an error")
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,4 +13,6 @@ type ValidationRequest struct {
|
|||||||
// Request contains the prompt identity, scalar context, variables, and
|
// Request contains the prompt identity, scalar context, variables, and
|
||||||
// artifact references supplied to the command.
|
// artifact references supplied to the command.
|
||||||
Request promptkit.RunRequest
|
Request promptkit.RunRequest
|
||||||
|
// Namespaces selects the native engine view; nil preserves the loader view.
|
||||||
|
Namespaces *promptkit.Namespaces
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -8,13 +8,14 @@ import (
|
|||||||
)
|
)
|
||||||
|
|
||||||
type concreteRequestInput[I any] struct {
|
type concreteRequestInput[I any] struct {
|
||||||
promptID string
|
namespaces namespaceInput
|
||||||
request ValidationRequest
|
promptID string
|
||||||
execution ExecutionInput
|
request ValidationRequest
|
||||||
resources ResourceInput
|
execution ExecutionInput
|
||||||
inputs PromptInputs
|
resources ResourceInput
|
||||||
captured commandkit.FlagValues[I]
|
inputs PromptInputs
|
||||||
selected I
|
captured commandkit.FlagValues[I]
|
||||||
|
selected I
|
||||||
}
|
}
|
||||||
|
|
||||||
type requestValidationReport struct {
|
type requestValidationReport struct {
|
||||||
@@ -46,6 +47,10 @@ func newConcreteRequestSpec[I, S any](suite Suite[I, S]) commandkit.CommandSpec[
|
|||||||
flags = append(flags, resources.Profile, resources.SessionID, inputs.Variable, inputs.Text, inputs.File)
|
flags = append(flags, resources.Profile, resources.SessionID, inputs.Variable, inputs.Text, inputs.File)
|
||||||
flags = append(flags, execution.All()...)
|
flags = append(flags, execution.All()...)
|
||||||
|
|
||||||
|
if suite.namespaces != nil {
|
||||||
|
flags = append(flags, namespaceFlags(func(input **concreteRequestInput[I]) *namespaceInput { return &(*input).namespaces }, "prompt", "profile", "backend")...)
|
||||||
|
}
|
||||||
|
|
||||||
return commandkit.CommandSpec[*concreteRequestInput[I]]{
|
return commandkit.CommandSpec[*concreteRequestInput[I]]{
|
||||||
NewInput: func() *concreteRequestInput[I] {
|
NewInput: func() *concreteRequestInput[I] {
|
||||||
return &concreteRequestInput[I]{}
|
return &concreteRequestInput[I]{}
|
||||||
@@ -62,6 +67,7 @@ func newConcreteRequestSpec[I, S any](suite Suite[I, S]) commandkit.CommandSpec[
|
|||||||
if input == nil {
|
if input == nil {
|
||||||
return errors.New("PromptKit request input must not be nil")
|
return errors.New("PromptKit request input must not be nil")
|
||||||
}
|
}
|
||||||
|
input.request.Namespaces = selectedNamespaces(suite.namespaces, input.namespaces)
|
||||||
input.request.Request.ProfileID = input.resources.Profile.Value
|
input.request.Request.ProfileID = input.resources.Profile.Value
|
||||||
input.request.Request.SessionID = input.resources.SessionID.Value
|
input.request.Request.SessionID = input.resources.SessionID.Value
|
||||||
input.request.Request.Vars = input.inputs.Vars
|
input.request.Request.Vars = input.inputs.Vars
|
||||||
|
|||||||
Reference in New Issue
Block a user