Select prompt metadata for inspection
This commit is contained in:
@@ -32,26 +32,27 @@ The runner has no durable run or session store.
|
|||||||
|
|
||||||
## Shared Prompt Selection
|
## Shared Prompt Selection
|
||||||
|
|
||||||
The runner uses one prompt-selection and hashing boundary for ordinary
|
Ordinary preparation selects the full prompt definition and construction-time
|
||||||
preparation and exact prompt inspection. Preparation retains its early
|
hash. It retains its early request-ID check before direct-session
|
||||||
request-ID check before direct-session normalization; both operations select
|
normalization. Referenced message content and static template syntax were
|
||||||
one captured definition and its construction-time hash. Referenced message
|
captured when the engine was built.
|
||||||
content and static template syntax were captured when the engine was built.
|
|
||||||
|
|
||||||
Inspection stops after that structural lookup. It does not render templates or
|
`InspectPrompt` selects captured metadata through an optional repository
|
||||||
touch profile, artifact, schema, renderer, validator, admission, or model
|
capability, falling back to the full definition and existing hash resolution
|
||||||
collaborators. The root [`Engine.InspectPrompt`](../../engine.go) GoDoc owns
|
for internal repositories without it. It returns owned metadata without
|
||||||
the public operation's exact contract.
|
rendering templates or touching profile, artifact, schema, renderer, validator,
|
||||||
|
admission, or model collaborators. The root
|
||||||
|
[`Engine.InspectPrompt`](../../engine.go) GoDoc owns the public operation's
|
||||||
|
exact contract.
|
||||||
|
|
||||||
`InspectRequirements` uses the same prompt selection boundary, then selects the
|
`InspectRequirements` uses the same metadata selection to resolve the
|
||||||
request profile or prompt default through an optional identity-only repository
|
request-profile/default identity, then obtains the exact captured requirement
|
||||||
capability, then obtains the exact captured requirement snapshot. Internal
|
snapshot by the selected prompt ID and version. The analyzer receives only
|
||||||
repositories without that capability use the full-profile selection boundary;
|
those identity fields rather than an execution definition. It analyzes the
|
||||||
both paths preserve the exact selected ID, and the fallback retains its
|
snapshot with the supplied caller variables and normalized direct-session
|
||||||
profile/target validity checks. It analyzes the snapshot with the supplied
|
bypass; it does not resolve target readiness or enter the preparation
|
||||||
caller variables and normalized direct-session bypass; it does not resolve
|
pipeline. Missing snapshot capability is a prompt-load failure rather than a
|
||||||
target readiness or enter the preparation pipeline. Missing snapshot
|
source fallback. The root
|
||||||
capability is a prompt-load failure rather than a source fallback. The root
|
|
||||||
[`Engine.InspectRequirements`](../../requirements.go) GoDoc owns the public
|
[`Engine.InspectRequirements`](../../requirements.go) GoDoc owns the public
|
||||||
operation's exact contract.
|
operation's exact contract.
|
||||||
|
|
||||||
|
|||||||
@@ -48,7 +48,8 @@ copies. The retained ConfigKit configuration keeps effective input message
|
|||||||
metadata and its resource origins: recording a sequence-wide normalization in
|
metadata and its resource origins: recording a sequence-wide normalization in
|
||||||
ConfigKit v0.5.0 would replace origins of unchanged content-file fields.
|
ConfigKit v0.5.0 would replace origins of unchanged content-file fields.
|
||||||
|
|
||||||
The runner selects from this index for preparation and `InspectPrompt`; the
|
The runner selects full definitions from this index for preparation and uses
|
||||||
|
captured prompt metadata for `InspectPrompt` and `InspectRequirements`; the
|
||||||
internal requirement snapshot lookup selects by exact prompt ID and version.
|
internal requirement snapshot lookup selects by exact prompt ID and version.
|
||||||
These paths do not rescan configuration or reopen message files. `InspectPrompt`
|
These paths do not rescan configuration or reopen message files. `InspectPrompt`
|
||||||
returns declared metadata without rendering or resolving profile, input, or
|
returns declared metadata without rendering or resolving profile, input, or
|
||||||
|
|||||||
@@ -13,6 +13,10 @@ type resolvedPromptDefinition struct {
|
|||||||
hash string
|
hash string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type promptInspectionRepository interface {
|
||||||
|
GetPromptInspection(context.Context, string, string) (*domain.PromptInspection, error)
|
||||||
|
}
|
||||||
|
|
||||||
func (r *Runner) resolvePromptDefinition(
|
func (r *Runner) resolvePromptDefinition(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
promptID string,
|
promptID string,
|
||||||
@@ -51,6 +55,43 @@ func (r *Runner) resolvePromptDefinition(
|
|||||||
return &resolvedPromptDefinition{definition: definition, hash: hash}, nil
|
return &resolvedPromptDefinition{definition: definition, hash: hash}, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *Runner) resolvePromptInspection(
|
||||||
|
ctx context.Context,
|
||||||
|
promptID string,
|
||||||
|
promptVersion string,
|
||||||
|
) (*domain.PromptInspection, error) {
|
||||||
|
if strings.TrimSpace(promptID) == "" {
|
||||||
|
return nil, fmt.Errorf("%w: prompt id is required", ErrInvalidRequest)
|
||||||
|
}
|
||||||
|
if r == nil || r.promptDefs == nil {
|
||||||
|
return nil, fmt.Errorf("%w: prompt repository is not configured", ErrPromptLoad)
|
||||||
|
}
|
||||||
|
if indexed, ok := r.promptDefs.(promptInspectionRepository); ok {
|
||||||
|
inspection, err := indexed.GetPromptInspection(ctx, promptID, promptVersion)
|
||||||
|
if err != nil {
|
||||||
|
return nil, fmt.Errorf("%w: %w", ErrPromptLoad, err)
|
||||||
|
}
|
||||||
|
if inspection == nil {
|
||||||
|
return nil, fmt.Errorf("%w: prompt repository returned nil inspection", ErrPromptLoad)
|
||||||
|
}
|
||||||
|
return inspection, nil
|
||||||
|
}
|
||||||
|
|
||||||
|
selection, err := r.resolvePromptDefinition(ctx, promptID, promptVersion)
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
definition := selection.definition
|
||||||
|
return &domain.PromptInspection{
|
||||||
|
PromptID: definition.ID,
|
||||||
|
PromptVersion: definition.Version,
|
||||||
|
PromptHash: selection.hash,
|
||||||
|
DefaultProfileID: definition.DefaultProfile,
|
||||||
|
Inputs: append([]domain.PromptInput(nil), definition.Inputs...),
|
||||||
|
OutputContract: definition.Validation,
|
||||||
|
}, nil
|
||||||
|
}
|
||||||
|
|
||||||
// InspectPrompt resolves one explicit prompt without execution work.
|
// InspectPrompt resolves one explicit prompt without execution work.
|
||||||
func (r *Runner) InspectPrompt(
|
func (r *Runner) InspectPrompt(
|
||||||
ctx context.Context,
|
ctx context.Context,
|
||||||
@@ -66,19 +107,5 @@ func (r *Runner) InspectPrompt(
|
|||||||
default:
|
default:
|
||||||
}
|
}
|
||||||
|
|
||||||
selection, err := r.resolvePromptDefinition(ctx, promptID, promptVersion)
|
return r.resolvePromptInspection(ctx, promptID, promptVersion)
|
||||||
if err != nil {
|
|
||||||
return nil, err
|
|
||||||
}
|
|
||||||
inputs := make([]domain.PromptInput, len(selection.definition.Inputs))
|
|
||||||
copy(inputs, selection.definition.Inputs)
|
|
||||||
|
|
||||||
return &domain.PromptInspection{
|
|
||||||
PromptID: selection.definition.ID,
|
|
||||||
PromptVersion: selection.definition.Version,
|
|
||||||
PromptHash: selection.hash,
|
|
||||||
DefaultProfileID: selection.definition.DefaultProfile,
|
|
||||||
Inputs: inputs,
|
|
||||||
OutputContract: selection.definition.Validation,
|
|
||||||
}, nil
|
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -18,6 +18,13 @@ type inspectionPromptRepository struct {
|
|||||||
version string
|
version string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type promptMetadataRepository struct {
|
||||||
|
inspection domain.PromptInspection
|
||||||
|
inspectionErr error
|
||||||
|
lookupID string
|
||||||
|
lookupVersion string
|
||||||
|
}
|
||||||
|
|
||||||
func (r *inspectionPromptRepository) GetPromptDefinition(
|
func (r *inspectionPromptRepository) GetPromptDefinition(
|
||||||
_ context.Context,
|
_ context.Context,
|
||||||
id string,
|
id string,
|
||||||
@@ -32,6 +39,22 @@ func (r *inspectionPromptRepository) GetPromptDefinition(
|
|||||||
return r.definition, nil
|
return r.definition, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (r *promptMetadataRepository) GetPromptDefinition(context.Context, string, string) (*domain.PromptDefinition, error) {
|
||||||
|
return nil, errors.New("full prompt definition should not be requested")
|
||||||
|
}
|
||||||
|
|
||||||
|
func (r *promptMetadataRepository) GetPromptInspection(
|
||||||
|
_ context.Context,
|
||||||
|
id string,
|
||||||
|
version string,
|
||||||
|
) (*domain.PromptInspection, error) {
|
||||||
|
r.lookupID = id
|
||||||
|
r.lookupVersion = version
|
||||||
|
inspection := r.inspection
|
||||||
|
inspection.Inputs = append([]domain.PromptInput(nil), inspection.Inputs...)
|
||||||
|
return &inspection, r.inspectionErr
|
||||||
|
}
|
||||||
|
|
||||||
func TestRunnerInspectPromptResolvesOneDefinitionWithoutExecutionCollaborators(t *testing.T) {
|
func TestRunnerInspectPromptResolvesOneDefinitionWithoutExecutionCollaborators(t *testing.T) {
|
||||||
definition := &domain.PromptDefinition{
|
definition := &domain.PromptDefinition{
|
||||||
ID: "normalized.prompt",
|
ID: "normalized.prompt",
|
||||||
@@ -81,6 +104,42 @@ func TestRunnerInspectPromptResolvesOneDefinitionWithoutExecutionCollaborators(t
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestRunnerInspectPromptUsesOwnedMetadataWhenRepositorySupportsIt(t *testing.T) {
|
||||||
|
repository := &promptMetadataRepository{inspection: domain.PromptInspection{
|
||||||
|
PromptID: "captured.prompt", PromptVersion: "v2", PromptHash: "cached-prompt-hash",
|
||||||
|
DefaultProfileID: "partial-profile",
|
||||||
|
Inputs: []domain.PromptInput{{Name: "document", Required: true, ContentType: "text/plain", Description: "Captured."}},
|
||||||
|
OutputContract: domain.OutputContract{Format: domain.FormatJSON, ValidationMode: domain.ValidationJSON},
|
||||||
|
}}
|
||||||
|
runner := &Runner{promptDefs: repository}
|
||||||
|
inspection, err := runner.InspectPrompt(context.Background(), " requested-id ", " requested-version ")
|
||||||
|
if err != nil || repository.lookupID != " requested-id " || repository.lookupVersion != " requested-version " ||
|
||||||
|
inspection.PromptID != "captured.prompt" || inspection.PromptVersion != "v2" ||
|
||||||
|
inspection.PromptHash != "cached-prompt-hash" || inspection.DefaultProfileID != "partial-profile" ||
|
||||||
|
!reflect.DeepEqual(inspection.Inputs, repository.inspection.Inputs) || inspection.OutputContract != repository.inspection.OutputContract {
|
||||||
|
t.Fatalf("metadata inspection=(%+v, %v), lookup=(%q,%q)", inspection, err, repository.lookupID, repository.lookupVersion)
|
||||||
|
}
|
||||||
|
inspection.Inputs[0].Name = "caller mutation"
|
||||||
|
inspection.OutputContract.SchemaPath = "caller mutation"
|
||||||
|
second, err := runner.InspectPrompt(context.Background(), "requested-id", "requested-version")
|
||||||
|
if err != nil || second.Inputs[0].Name != "document" || second.OutputContract.SchemaPath != "" {
|
||||||
|
t.Fatalf("metadata inspection was not caller-owned: (%+v, %v)", second, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestRunnerInspectPromptUsesCapturedHashWhenMetadataCapabilityIsAbsent(t *testing.T) {
|
||||||
|
repository := &requirementInspectionPromptRepository{
|
||||||
|
definition: &domain.PromptDefinition{
|
||||||
|
ID: "captured.prompt", Version: "v1", Inputs: []domain.PromptInput{{Name: "document"}},
|
||||||
|
},
|
||||||
|
}
|
||||||
|
inspection, err := (&Runner{promptDefs: repository}).InspectPrompt(context.Background(), " requested-id ", " requested-version ")
|
||||||
|
if err != nil || inspection.PromptID != "captured.prompt" || inspection.PromptVersion != "v1" ||
|
||||||
|
inspection.PromptHash != "captured-hash" || inspection.Inputs[0].Name != "document" {
|
||||||
|
t.Fatalf("captured-hash fallback inspection=(%+v, %v)", inspection, err)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestRunnerInspectPromptClassifiesFailuresWithoutRepositoryWorkAfterCancellation(t *testing.T) {
|
func TestRunnerInspectPromptClassifiesFailuresWithoutRepositoryWorkAfterCancellation(t *testing.T) {
|
||||||
t.Run("blank ID", func(t *testing.T) {
|
t.Run("blank ID", func(t *testing.T) {
|
||||||
repository := &inspectionPromptRepository{}
|
repository := &inspectionPromptRepository{}
|
||||||
|
|||||||
@@ -40,7 +40,7 @@ func (r *Runner) InspectRequirements(
|
|||||||
return nil, fmt.Errorf("%w: %w", ErrPromptLoad, err)
|
return nil, fmt.Errorf("%w: %w", ErrPromptLoad, err)
|
||||||
}
|
}
|
||||||
|
|
||||||
selection, err := r.resolvePromptDefinition(ctx, req.PromptID, req.PromptVersion)
|
selection, err := r.resolvePromptInspection(ctx, req.PromptID, req.PromptVersion)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -49,7 +49,7 @@ func (r *Runner) InspectRequirements(
|
|||||||
}
|
}
|
||||||
selectedProfileID := req.ProfileID
|
selectedProfileID := req.ProfileID
|
||||||
if strings.TrimSpace(selectedProfileID) == "" {
|
if strings.TrimSpace(selectedProfileID) == "" {
|
||||||
selectedProfileID = selection.definition.DefaultProfile
|
selectedProfileID = selection.DefaultProfileID
|
||||||
}
|
}
|
||||||
if strings.TrimSpace(selectedProfileID) == "" {
|
if strings.TrimSpace(selectedProfileID) == "" {
|
||||||
return nil, fmt.Errorf("%w: %w: profile id is required either in request or prompt default_profile", ErrInvalidRequest, ErrProfileRequired)
|
return nil, fmt.Errorf("%w: %w: profile id is required either in request or prompt default_profile", ErrInvalidRequest, ErrProfileRequired)
|
||||||
@@ -66,11 +66,12 @@ func (r *Runner) InspectRequirements(
|
|||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("%w: prompt repository does not provide captured requirement snapshots", ErrPromptLoad)
|
return nil, fmt.Errorf("%w: prompt repository does not provide captured requirement snapshots", ErrPromptLoad)
|
||||||
}
|
}
|
||||||
snapshot, ok := repository.GetRequirementSnapshot(selection.definition.ID, selection.definition.Version)
|
snapshot, ok := repository.GetRequirementSnapshot(selection.PromptID, selection.PromptVersion)
|
||||||
if !ok {
|
if !ok {
|
||||||
return nil, fmt.Errorf("%w: captured requirement snapshot is unavailable", ErrPromptLoad)
|
return nil, fmt.Errorf("%w: captured requirement snapshot is unavailable", ErrPromptLoad)
|
||||||
}
|
}
|
||||||
inspection, err := prompt.AnalyzeRequirements(ctx, selection.definition, snapshot, req.Vars, directSessionID != "")
|
definition := &domain.PromptDefinition{ID: selection.PromptID, Version: selection.PromptVersion}
|
||||||
|
inspection, err := prompt.AnalyzeRequirements(ctx, definition, snapshot, req.Vars, directSessionID != "")
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, fmt.Errorf("%w: %w", ErrPromptLoad, err)
|
return nil, fmt.Errorf("%w: %w", ErrPromptLoad, err)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -24,6 +24,13 @@ type requirementInspectionPromptRepository struct {
|
|||||||
snapshotVersion string
|
snapshotVersion string
|
||||||
}
|
}
|
||||||
|
|
||||||
|
type requirementPromptMetadataRepository struct {
|
||||||
|
*requirementInspectionPromptRepository
|
||||||
|
inspection domain.PromptInspection
|
||||||
|
lookupID string
|
||||||
|
lookupVersion string
|
||||||
|
}
|
||||||
|
|
||||||
type inspectionProfileIdentityRepository struct {
|
type inspectionProfileIdentityRepository struct {
|
||||||
*inspectionProfileRepository
|
*inspectionProfileRepository
|
||||||
identity string
|
identity string
|
||||||
@@ -49,6 +56,18 @@ func (repository *requirementInspectionPromptRepository) GetPromptDefinition(
|
|||||||
return repository.definition, repository.lookupErr
|
return repository.definition, repository.lookupErr
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (repository *requirementPromptMetadataRepository) GetPromptInspection(
|
||||||
|
_ context.Context,
|
||||||
|
id string,
|
||||||
|
version string,
|
||||||
|
) (*domain.PromptInspection, error) {
|
||||||
|
repository.lookupID = id
|
||||||
|
repository.lookupVersion = version
|
||||||
|
inspection := repository.inspection
|
||||||
|
inspection.Inputs = append([]domain.PromptInput(nil), inspection.Inputs...)
|
||||||
|
return &inspection, nil
|
||||||
|
}
|
||||||
|
|
||||||
func (repository *requirementInspectionPromptRepository) GetPromptSnapshot(
|
func (repository *requirementInspectionPromptRepository) GetPromptSnapshot(
|
||||||
_ context.Context,
|
_ context.Context,
|
||||||
id string,
|
id string,
|
||||||
@@ -111,6 +130,50 @@ func TestRunnerInspectRequirementsUsesCapturedSelectionWithoutExecutionWork(t *t
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestRunnerInspectRequirementsUsesPromptMetadataAndExactRequirementSnapshot(t *testing.T) {
|
||||||
|
message, err := prompt.CompileTemplate("message", `{{input "message-input"}} {{.caller}}`)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
session, err := prompt.CompileTemplate("session", `{{input "session-only"}}`)
|
||||||
|
if err != nil {
|
||||||
|
t.Fatal(err)
|
||||||
|
}
|
||||||
|
baseRepository := &requirementInspectionPromptRepository{
|
||||||
|
snapshotFound: true,
|
||||||
|
snapshot: prompt.RequirementSnapshot{Templates: prompt.CompiledTemplates{
|
||||||
|
Messages: []*template.Template{message}, Session: session,
|
||||||
|
}},
|
||||||
|
}
|
||||||
|
promptRepository := &requirementPromptMetadataRepository{
|
||||||
|
requirementInspectionPromptRepository: baseRepository,
|
||||||
|
inspection: domain.PromptInspection{
|
||||||
|
PromptID: "captured-id", PromptVersion: "captured-version", PromptHash: "captured-hash",
|
||||||
|
DefaultProfileID: "default-profile",
|
||||||
|
},
|
||||||
|
}
|
||||||
|
profiles := &inspectionProfileIdentityRepository{
|
||||||
|
inspectionProfileRepository: &inspectionProfileRepository{},
|
||||||
|
identity: "default-profile",
|
||||||
|
}
|
||||||
|
inspection, err := (&Runner{promptDefs: promptRepository, profiles: profiles}).InspectRequirements(
|
||||||
|
context.Background(), RequirementInspectionRequest{
|
||||||
|
PromptID: " requested-id ", PromptVersion: " requested-version ",
|
||||||
|
Vars: map[string]string{"caller": "Ada"}, SessionID: " direct-session ",
|
||||||
|
},
|
||||||
|
)
|
||||||
|
if err != nil || promptRepository.lookupID != " requested-id " || promptRepository.lookupVersion != " requested-version " ||
|
||||||
|
baseRepository.snapshotID != "captured-id" || baseRepository.snapshotVersion != "captured-version" ||
|
||||||
|
profiles.identityID != "default-profile" || inspection.PromptID != "captured-id" ||
|
||||||
|
inspection.PromptVersion != "captured-version" || inspection.ProfileID != "default-profile" ||
|
||||||
|
!inspection.Complete || len(inspection.Inputs) != 1 || inspection.Inputs[0].Name != "message-input" ||
|
||||||
|
len(inspection.Variables) != 1 || inspection.Variables[0].Name != "caller" || !inspection.Variables[0].Supplied {
|
||||||
|
t.Fatalf("metadata-based requirement inspection=(%+v, %v), prompt lookup=(%q,%q), snapshot=(%q,%q), profile=%q",
|
||||||
|
inspection, err, promptRepository.lookupID, promptRepository.lookupVersion,
|
||||||
|
baseRepository.snapshotID, baseRepository.snapshotVersion, profiles.identityID)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestRunnerInspectRequirementsUsesProfileIdentityCapabilityOrFallback(t *testing.T) {
|
func TestRunnerInspectRequirementsUsesProfileIdentityCapabilityOrFallback(t *testing.T) {
|
||||||
message, err := prompt.CompileTemplate("message", `{{.name}}`)
|
message, err := prompt.CompileTemplate("message", `{{.name}}`)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
@@ -178,6 +178,28 @@ func TestInspectRequirementsSelectionUsesExactVersionsAndProfileIdentity(t *test
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestInspectPromptHashMatchesPreparationForCapturedConfiguration(t *testing.T) {
|
||||||
|
prompts := oneVersionPrompt("hash-equality", "v1", contractPrompt(
|
||||||
|
"profile", "Hello {{.name}}", nil, "", noValidationOutput,
|
||||||
|
))
|
||||||
|
engine := requirementsEngine(t, prompts, map[string]any{
|
||||||
|
"profile": map[string]any{"endpoint": "https://example.test/v1", "model": "inspection-model"},
|
||||||
|
})
|
||||||
|
inspection, err := engine.InspectPrompt(context.Background(), "hash-equality", "v1")
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("inspect captured prompt: %v", err)
|
||||||
|
}
|
||||||
|
prepared, err := engine.Prepare(context.Background(), promptkit.RunRequest{
|
||||||
|
PromptID: "hash-equality", PromptVersion: "v1", Vars: map[string]string{"name": "Ada"},
|
||||||
|
})
|
||||||
|
if err != nil {
|
||||||
|
t.Fatalf("prepare captured prompt: %v", err)
|
||||||
|
}
|
||||||
|
if inspection.PromptHash != prepared.PromptHash {
|
||||||
|
t.Fatalf("inspection hash=%q, preparation hash=%q", inspection.PromptHash, prepared.PromptHash)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestInspectRequirementsReportsConditionalAndCompleteOptionalInventories(t *testing.T) {
|
func TestInspectRequirementsReportsConditionalAndCompleteOptionalInventories(t *testing.T) {
|
||||||
prompts := map[string]any{
|
prompts := map[string]any{
|
||||||
"conditional": map[string]any{"v1": contractPrompt("profile",
|
"conditional": map[string]any{"v1": contractPrompt("profile",
|
||||||
|
|||||||
Reference in New Issue
Block a user