Remove prompt version selectors

This commit is contained in:
2026-10-17 05:47:14 +00:00
parent d40a010538
commit 8cbb7c0daf
36 changed files with 182 additions and 253 deletions

View File

@@ -227,7 +227,7 @@ func BenchmarkInspectionSelection(b *testing.B) {
b.Fatal(err)
}
ctx := context.Background()
definition, hash, err := result.GetPromptSnapshot(ctx, "inspection", "1")
definition, hash, err := result.GetPromptSnapshot(ctx, "inspection")
if err != nil || definition.ID != "inspection" || definition.Version != "1" || hash == "" ||
len(definition.Inputs) != 1 || definition.Inputs[0].Name != "transcript" || !definition.Inputs[0].Required {
b.Fatalf("prompt lookup fixture is invalid: definition=%+v hash=%q err=%v", definition, hash, err)
@@ -237,7 +237,7 @@ func BenchmarkInspectionSelection(b *testing.B) {
len(profile.ResolvedTarget.ExtraParams["provider_options"].(map[string]any)) != scenario.entries {
b.Fatalf("profile lookup fixture is invalid: profile=%+v err=%v", profile, err)
}
inspection, err := result.GetPromptInspection(ctx, "inspection", "1")
inspection, err := result.GetPromptInspection(ctx, "inspection")
if err != nil || inspection.PromptID != "inspection" || inspection.PromptVersion != "1" ||
len(inspection.Inputs) != 1 || inspection.Inputs[0].Name != "transcript" {
b.Fatalf("prompt inspection fixture is invalid: inspection=%+v err=%v", inspection, err)
@@ -250,7 +250,7 @@ func BenchmarkInspectionSelection(b *testing.B) {
b.Run("prompt/"+scenario.name, func(b *testing.B) {
b.ReportAllocs()
for b.Loop() {
definition, hash, err := result.GetPromptSnapshot(ctx, "inspection", "1")
definition, hash, err := result.GetPromptSnapshot(ctx, "inspection")
if err != nil {
b.Fatal(err)
}
@@ -262,7 +262,7 @@ func BenchmarkInspectionSelection(b *testing.B) {
b.Run("prompt_inspection/"+scenario.name, func(b *testing.B) {
b.ReportAllocs()
for b.Loop() {
inspection, err := result.GetPromptInspection(ctx, "inspection", "1")
inspection, err := result.GetPromptInspection(ctx, "inspection")
if err != nil {
b.Fatal(err)
}

View File

@@ -286,7 +286,7 @@ func (state *loaded) readContent(fieldPath configkit.Path, name string, lookupOr
return string(content), nil
}
func (state *loaded) lookupPromptEntry(id, version string) (*promptEntry, error) {
func (state *loaded) lookupPromptEntry(id string) (*promptEntry, error) {
if state == nil || strings.TrimSpace(id) == "" {
return nil, errPromptNotFound
}
@@ -322,7 +322,7 @@ func promptLookupError(err error) error {
}
func (state *loaded) prompt(id string) (*domain.PromptDefinition, domain.PromptInspection, error) {
entry, err := state.lookupPromptEntry(id, "")
entry, err := state.lookupPromptEntry(id)
if err != nil {
return nil, domain.PromptInspection{}, err
}
@@ -330,13 +330,12 @@ func (state *loaded) prompt(id string) (*domain.PromptDefinition, domain.PromptI
}
// GetPromptSnapshot returns an independently owned captured definition and its
// construction-time hash. The version argument is retained temporarily at the
// adapter boundary and does not participate in lookup.
func (state *loaded) GetPromptSnapshot(ctx context.Context, id, version string) (*domain.PromptDefinition, string, error) {
// construction-time hash.
func (state *loaded) GetPromptSnapshot(ctx context.Context, id string) (*domain.PromptDefinition, string, error) {
if err := ctx.Err(); err != nil {
return nil, "", err
}
entry, err := state.lookupPromptEntry(id, version)
entry, err := state.lookupPromptEntry(id)
if err != nil {
return nil, "", promptLookupError(err)
}
@@ -345,11 +344,11 @@ func (state *loaded) GetPromptSnapshot(ctx context.Context, id, version string)
// GetPromptInspection returns an independently owned inspection of one
// captured prompt without copying its execution templates.
func (state *loaded) GetPromptInspection(ctx context.Context, id, version string) (*domain.PromptInspection, error) {
func (state *loaded) GetPromptInspection(ctx context.Context, id string) (*domain.PromptInspection, error) {
if err := ctx.Err(); err != nil {
return nil, err
}
entry, err := state.lookupPromptEntry(id, version)
entry, err := state.lookupPromptEntry(id)
if err != nil {
return nil, promptLookupError(err)
}
@@ -357,13 +356,13 @@ func (state *loaded) GetPromptInspection(ctx context.Context, id, version string
}
// GetPromptDefinition implements the runner's prompt lookup boundary.
func (state *loaded) GetPromptDefinition(ctx context.Context, id, version string) (*domain.PromptDefinition, error) {
definition, _, err := state.GetPromptSnapshot(ctx, id, version)
func (state *loaded) GetPromptDefinition(ctx context.Context, id string) (*domain.PromptDefinition, error) {
definition, _, err := state.GetPromptSnapshot(ctx, id)
return definition, err
}
// GetCompiledTemplates returns construction-time parses for one prompt ID.
func (state *loaded) GetCompiledTemplates(id, version string) (prompt.CompiledTemplates, bool) {
func (state *loaded) GetCompiledTemplates(id string) (prompt.CompiledTemplates, bool) {
if state == nil {
return prompt.CompiledTemplates{}, false
}
@@ -377,7 +376,7 @@ func (state *loaded) GetCompiledTemplates(id, version string) (prompt.CompiledTe
// GetRequirementSnapshot returns captured templates and input metadata for
// one prompt ID. Returned metadata and slices are independently
// owned; the compiled templates are shared immutable construction-time parses.
func (state *loaded) GetRequirementSnapshot(id, version string) (prompt.RequirementSnapshot, bool) {
func (state *loaded) GetRequirementSnapshot(id string) (prompt.RequirementSnapshot, bool) {
if state == nil {
return prompt.RequirementSnapshot{}, false
}

View File

@@ -161,11 +161,11 @@ func TestPromptInspectionLookupMatchesSnapshotSelectionAndOwnsInputs(t *testing.
}
{
inspection, err := state.GetPromptInspection(context.Background(), "selected", "")
inspection, err := state.GetPromptInspection(context.Background(), "selected")
if err != nil {
t.Fatalf("inspect prompt ID: %v", err)
}
definition, hash, err := state.GetPromptSnapshot(context.Background(), "selected", "")
definition, hash, err := state.GetPromptSnapshot(context.Background(), "selected")
if err != nil {
t.Fatalf("snapshot prompt ID: %v", err)
}
@@ -180,30 +180,30 @@ func TestPromptInspectionLookupMatchesSnapshotSelectionAndOwnsInputs(t *testing.
}
}
owned, err := state.GetPromptInspection(context.Background(), "selected", "")
owned, err := state.GetPromptInspection(context.Background(), "selected")
if err != nil {
t.Fatal(err)
}
owned.Inputs[0].Name = "caller mutation"
owned.Inputs[0].Description = "caller mutation"
again, err := state.GetPromptInspection(context.Background(), "selected", "")
again, err := state.GetPromptInspection(context.Background(), "selected")
if err != nil || again.Inputs[0].Name != "document" || again.Inputs[0].Description != "source document" {
t.Fatalf("inspection mutation escaped into captured state: inspection=%+v err=%v", again, err)
}
for _, id := range []string{"missing", " "} {
inspection, err := state.GetPromptInspection(context.Background(), id, "")
inspection, err := state.GetPromptInspection(context.Background(), id)
if inspection != nil || !errors.Is(err, promptdef.ErrPromptDefinitionNotFound) {
t.Errorf("inspection lookup %q=(%+v, %v), want not found", id, inspection, err)
}
definition, _, err := state.GetPromptSnapshot(context.Background(), id, "")
definition, _, err := state.GetPromptSnapshot(context.Background(), id)
if definition != nil || !errors.Is(err, promptdef.ErrPromptDefinitionNotFound) {
t.Errorf("snapshot lookup %q=(%+v, %v), want not found", id, definition, err)
}
}
ctx, cancel := context.WithCancel(context.Background())
cancel()
if _, err := state.GetPromptInspection(ctx, "selected", ""); !errors.Is(err, context.Canceled) {
if _, err := state.GetPromptInspection(ctx, "selected"); !errors.Is(err, context.Canceled) {
t.Errorf("canceled inspection selection error=%v", err)
}
}
@@ -269,7 +269,7 @@ func TestRequirementSnapshotCapturesMetadataPresenceAndNormalizedValues(t *testi
t.Fatal(err)
}
snapshot, ok := state.GetRequirementSnapshot("example", "")
snapshot, ok := state.GetRequirementSnapshot("example")
if !ok || len(snapshot.Inputs) != 4 || len(snapshot.Templates.Messages) != 1 || snapshot.Templates.Session == nil {
t.Fatalf("requirement snapshot was not captured: %+v, %t", snapshot, ok)
}
@@ -299,7 +299,7 @@ func TestRequirementSnapshotCapturesMetadataPresenceAndNormalizedValues(t *testi
*snapshot.Inputs[2].ContentType = "caller mutation"
snapshot.Inputs[3].Name = "caller mutation"
snapshot.Templates.Messages[0] = nil
again, ok := state.GetRequirementSnapshot("example", "")
again, ok := state.GetRequirementSnapshot("example")
if !ok || *again.Inputs[2].ContentType != "" || again.Inputs[3].Name != "normalized" || again.Templates.Messages[0] == nil {
t.Fatalf("snapshot mutation escaped into captured state: %+v, %t", again, ok)
}

View File

@@ -61,7 +61,6 @@ type CacheControl struct {
// RunRequest represents a request to generate a single artifact.
type RunRequest struct {
PromptID string
PromptVersion string
ProfileID string
SessionID string
APIKey string `json:"-" yaml:"-"`
@@ -135,7 +134,7 @@ type Artifact struct {
Hash string
}
// PromptIdentity identifies one configured prompt version.
// PromptIdentity identifies one configured prompt and its descriptive version label.
type PromptIdentity struct {
ID string
Version string

View File

@@ -39,7 +39,6 @@ type SmokeTestRequest struct {
Kind SmokeTestKind
BackendID string
PromptID string
PromptVersion string
ProfileID string
Execution *ExecutionTargetOverride
APIKey string `json:"-" yaml:"-"`

View File

@@ -187,8 +187,8 @@ func fileSource(name string) (fs.FS, string, string, error) {
return os.DirFS(directory), filepath.ToSlash(base), directory, nil
}
func (e *Engine) InspectPrompt(ctx context.Context, id, version string) (*domain.PromptInspection, error) {
return e.runner.InspectPrompt(ctx, id, version)
func (e *Engine) InspectPrompt(ctx context.Context, id string) (*domain.PromptInspection, error) {
return e.runner.InspectPrompt(ctx, id)
}
func (e *Engine) InspectRequirements(
ctx context.Context,

View File

@@ -19,8 +19,7 @@ var (
)
type rendererBenchmarkIdentity struct {
id string
version string
id string
}
type rendererBenchmarkLookup struct {
@@ -28,8 +27,8 @@ type rendererBenchmarkLookup struct {
templates CompiledTemplates
}
func (lookup rendererBenchmarkLookup) GetCompiledTemplates(id, version string) (CompiledTemplates, bool) {
if id != lookup.identity.id || version != lookup.identity.version {
func (lookup rendererBenchmarkLookup) GetCompiledTemplates(id string) (CompiledTemplates, bool) {
if id != lookup.identity.id {
return CompiledTemplates{}, false
}
return lookup.templates, true
@@ -148,7 +147,7 @@ func BenchmarkRetainedRenderedOutput(b *testing.B) {
}
compiled := CompiledTemplates{Messages: []*template.Template{mustCompileRendererBenchmarkTemplate(b, content)}}
renderer := NewCompiledRenderer(rendererBenchmarkLookup{
identity: rendererBenchmarkIdentity{id: definition.ID, version: definition.Version},
identity: rendererBenchmarkIdentity{id: definition.ID},
templates: compiled,
})
inputs := map[string]*domain.Artifact{"document": {Name: "document", Body: body}}
@@ -228,7 +227,7 @@ func newCompiledRenderingBenchmarkCase(
return compiledRenderingBenchmarkCase{
name: name,
renderer: NewCompiledRenderer(rendererBenchmarkLookup{
identity: rendererBenchmarkIdentity{id: definition.ID, version: definition.Version},
identity: rendererBenchmarkIdentity{id: definition.ID},
templates: compiled,
}),
definition: definition, inputs: inputs, vars: vars, ctx: context.Background(),

View File

@@ -59,7 +59,7 @@ func (r *goRenderer) Render(ctx context.Context, definition *domain.PromptDefini
var compiled CompiledTemplates
if r.templates != nil {
var found bool
compiled, found = r.templates.GetCompiledTemplates(definition.ID, definition.Version)
compiled, found = r.templates.GetCompiledTemplates(definition.ID)
if !found || len(compiled.Messages) != len(definition.Templates) {
return nil, fmt.Errorf("%w: captured templates are unavailable", ErrRenderFailure)
}

View File

@@ -518,8 +518,7 @@ func TestCompiledRendererKeepsConcurrentRequestsIndependent(t *testing.T) {
t.Fatalf("compile message template: %v", err)
}
renderer := NewCompiledRenderer(compiledRendererTestLookup{
id: promptID,
version: version,
id: promptID,
templates: CompiledTemplates{
Session: sessionTemplate,
Messages: []*template.Template{messageTemplate},
@@ -562,12 +561,12 @@ func TestCompiledRendererKeepsConcurrentRequestsIndependent(t *testing.T) {
}
type compiledRendererTestLookup struct {
id, version string
templates CompiledTemplates
id string
templates CompiledTemplates
}
func (lookup compiledRendererTestLookup) GetCompiledTemplates(id, version string) (CompiledTemplates, bool) {
if id != lookup.id || version != lookup.version {
func (lookup compiledRendererTestLookup) GetCompiledTemplates(id string) (CompiledTemplates, bool) {
if id != lookup.id {
return CompiledTemplates{}, false
}
return lookup.templates, true

View File

@@ -27,7 +27,7 @@ type RequirementSnapshot struct {
// TemplateLookup provides parsed templates for a captured prompt identity.
type TemplateLookup interface {
GetCompiledTemplates(id, version string) (CompiledTemplates, bool)
GetCompiledTemplates(id string) (CompiledTemplates, bool)
}
// CompileTemplate checks static syntax with the same grammar and function

View File

@@ -12,5 +12,5 @@ var ErrPromptDefinitionNotFound = errors.New("prompt definition not found")
// Repository selects prompt definitions from a captured index.
type Repository interface {
GetPromptDefinition(ctx context.Context, id string, version string) (*domain.PromptDefinition, error)
GetPromptDefinition(ctx context.Context, id string) (*domain.PromptDefinition, error)
}

View File

@@ -680,7 +680,7 @@ func TestRunnerPreparedExecutionDetachesTransferredSnapshotSources(t *testing.T)
reader, renderer, llmClient, validator, nil,
)
request := domain.RunRequest{
PromptID: "p", PromptVersion: "1", ProfileID: "exec",
PromptID: "p", ProfileID: "exec",
Inputs: map[string]domain.ArtifactRef{
"transcript": {Type: domain.ArtifactRefFile, URI: "source"},
},

View File

@@ -119,7 +119,7 @@ func newPreparedSnapshotBenchmarkRunner(
nil,
)
request := domain.RunRequest{
PromptID: "p", PromptVersion: "1", ProfileID: "exec",
PromptID: "p", ProfileID: "exec",
Inputs: singleInputRef(), Vars: map[string]string{"name": "Ada"},
AppendedMessages: []domain.RenderedMessage{{
Role: domain.RoleAssistant, Content: "appended message",

View File

@@ -14,14 +14,10 @@ type resolvedPromptDefinition struct {
}
type promptInspectionRepository interface {
GetPromptInspection(context.Context, string, string) (*domain.PromptInspection, error)
GetPromptInspection(context.Context, string) (*domain.PromptInspection, error)
}
func (r *Runner) resolvePromptDefinition(
ctx context.Context,
promptID string,
promptVersion string,
) (*resolvedPromptDefinition, error) {
func (r *Runner) resolvePromptDefinition(ctx context.Context, promptID string) (*resolvedPromptDefinition, error) {
if strings.TrimSpace(promptID) == "" {
return nil, fmt.Errorf("%w: prompt id is required", ErrInvalidRequest)
}
@@ -33,11 +29,11 @@ func (r *Runner) resolvePromptDefinition(
var hash string
var err error
if indexed, ok := r.promptDefs.(interface {
GetPromptSnapshot(context.Context, string, string) (*domain.PromptDefinition, string, error)
GetPromptSnapshot(context.Context, string) (*domain.PromptDefinition, string, error)
}); ok {
definition, hash, err = indexed.GetPromptSnapshot(ctx, promptID, promptVersion)
definition, hash, err = indexed.GetPromptSnapshot(ctx, promptID)
} else {
definition, err = r.promptDefs.GetPromptDefinition(ctx, promptID, promptVersion)
definition, err = r.promptDefs.GetPromptDefinition(ctx, promptID)
}
if err != nil {
return nil, fmt.Errorf("%w: %w", ErrPromptLoad, err)
@@ -55,11 +51,7 @@ func (r *Runner) resolvePromptDefinition(
return &resolvedPromptDefinition{definition: definition, hash: hash}, nil
}
func (r *Runner) resolvePromptInspection(
ctx context.Context,
promptID string,
promptVersion string,
) (*domain.PromptInspection, error) {
func (r *Runner) resolvePromptInspection(ctx context.Context, promptID string) (*domain.PromptInspection, error) {
if strings.TrimSpace(promptID) == "" {
return nil, fmt.Errorf("%w: prompt id is required", ErrInvalidRequest)
}
@@ -67,7 +59,7 @@ func (r *Runner) resolvePromptInspection(
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)
inspection, err := indexed.GetPromptInspection(ctx, promptID)
if err != nil {
return nil, fmt.Errorf("%w: %w", ErrPromptLoad, err)
}
@@ -77,7 +69,7 @@ func (r *Runner) resolvePromptInspection(
return inspection, nil
}
selection, err := r.resolvePromptDefinition(ctx, promptID, promptVersion)
selection, err := r.resolvePromptDefinition(ctx, promptID)
if err != nil {
return nil, err
}
@@ -93,11 +85,7 @@ func (r *Runner) resolvePromptInspection(
}
// InspectPrompt resolves one explicit prompt without execution work.
func (r *Runner) InspectPrompt(
ctx context.Context,
promptID string,
promptVersion string,
) (*domain.PromptInspection, error) {
func (r *Runner) InspectPrompt(ctx context.Context, promptID string) (*domain.PromptInspection, error) {
if strings.TrimSpace(promptID) == "" {
return nil, fmt.Errorf("%w: prompt id is required", ErrInvalidRequest)
}
@@ -107,5 +95,5 @@ func (r *Runner) InspectPrompt(
default:
}
return r.resolvePromptInspection(ctx, promptID, promptVersion)
return r.resolvePromptInspection(ctx, promptID)
}

View File

@@ -15,41 +15,35 @@ type inspectionPromptRepository struct {
err error
calls int
id string
version string
}
type promptMetadataRepository struct {
inspection domain.PromptInspection
inspectionErr error
lookupID string
lookupVersion string
}
func (r *inspectionPromptRepository) GetPromptDefinition(
_ context.Context,
id string,
version string,
) (*domain.PromptDefinition, error) {
r.calls++
r.id = id
r.version = version
if r.err != nil {
return nil, r.err
}
return r.definition, nil
}
func (r *promptMetadataRepository) GetPromptDefinition(context.Context, string, string) (*domain.PromptDefinition, error) {
func (r *promptMetadataRepository) GetPromptDefinition(context.Context, 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
@@ -74,7 +68,7 @@ func TestRunnerInspectPromptResolvesOneDefinitionWithoutExecutionCollaborators(t
repository := &inspectionPromptRepository{definition: definition}
runner := &Runner{promptDefs: repository}
inspection, err := runner.InspectPrompt(context.Background(), " prompt-id ", " version ")
inspection, err := runner.InspectPrompt(context.Background(), " prompt-id ")
if err != nil {
t.Fatalf("inspect prompt: %v", err)
}
@@ -82,8 +76,8 @@ func TestRunnerInspectPromptResolvesOneDefinitionWithoutExecutionCollaborators(t
if err != nil {
t.Fatalf("hash prompt definition: %v", err)
}
if repository.calls != 1 || repository.id != " prompt-id " || repository.version != " version " {
t.Fatalf("prompt lookup=(calls=%d id=%q version=%q), want one unchanged lookup", repository.calls, repository.id, repository.version)
if repository.calls != 1 || repository.id != " prompt-id " {
t.Fatalf("prompt lookup=(calls=%d id=%q), want one unchanged ID lookup", repository.calls, repository.id)
}
if inspection.PromptID != definition.ID ||
inspection.PromptVersion != definition.Version ||
@@ -95,7 +89,7 @@ func TestRunnerInspectPromptResolvesOneDefinitionWithoutExecutionCollaborators(t
}
inspection.Inputs[0].Name = "changed"
second, err := runner.InspectPrompt(context.Background(), " prompt-id ", " version ")
second, err := runner.InspectPrompt(context.Background(), " prompt-id ")
if err != nil {
t.Fatalf("inspect prompt again: %v", err)
}
@@ -112,16 +106,16 @@ func TestRunnerInspectPromptUsesOwnedMetadataWhenRepositorySupportsIt(t *testing
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, err := runner.InspectPrompt(context.Background(), " requested-id ")
if err != nil || repository.lookupID != " requested-id " ||
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)
t.Fatalf("metadata inspection=(%+v, %v), lookup=%q", inspection, err, repository.lookupID)
}
inspection.Inputs[0].Name = "caller mutation"
inspection.OutputContract.SchemaPath = "caller mutation"
second, err := runner.InspectPrompt(context.Background(), "requested-id", "requested-version")
second, err := runner.InspectPrompt(context.Background(), "requested-id")
if err != nil || second.Inputs[0].Name != "document" || second.OutputContract.SchemaPath != "" {
t.Fatalf("metadata inspection was not caller-owned: (%+v, %v)", second, err)
}
@@ -133,7 +127,7 @@ func TestRunnerInspectPromptUsesCapturedHashWhenMetadataCapabilityIsAbsent(t *te
ID: "captured.prompt", Version: "v1", Inputs: []domain.PromptInput{{Name: "document"}},
},
}
inspection, err := (&Runner{promptDefs: repository}).InspectPrompt(context.Background(), " requested-id ", " requested-version ")
inspection, err := (&Runner{promptDefs: repository}).InspectPrompt(context.Background(), " requested-id ")
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)
@@ -143,7 +137,7 @@ func TestRunnerInspectPromptUsesCapturedHashWhenMetadataCapabilityIsAbsent(t *te
func TestRunnerInspectPromptClassifiesFailuresWithoutRepositoryWorkAfterCancellation(t *testing.T) {
t.Run("blank ID", func(t *testing.T) {
repository := &inspectionPromptRepository{}
_, err := (&Runner{promptDefs: repository}).InspectPrompt(context.Background(), " \t ", "version")
_, err := (&Runner{promptDefs: repository}).InspectPrompt(context.Background(), " \t ")
if !errors.Is(err, ErrInvalidRequest) || repository.calls != 0 {
t.Fatalf("blank inspection=(%v, calls=%d), want invalid request without lookup", err, repository.calls)
}
@@ -153,7 +147,7 @@ func TestRunnerInspectPromptClassifiesFailuresWithoutRepositoryWorkAfterCancella
ctx, cancel := context.WithCancel(context.Background())
cancel()
repository := &inspectionPromptRepository{}
_, err := (&Runner{promptDefs: repository}).InspectPrompt(ctx, "prompt", "version")
_, err := (&Runner{promptDefs: repository}).InspectPrompt(ctx, "prompt")
if !errors.Is(err, ErrPromptLoad) || !errors.Is(err, context.Canceled) || repository.calls != 0 {
t.Fatalf("canceled inspection=(%v, calls=%d), want prompt load and context identities without lookup", err, repository.calls)
}
@@ -161,7 +155,7 @@ func TestRunnerInspectPromptClassifiesFailuresWithoutRepositoryWorkAfterCancella
t.Run("missing prompt", func(t *testing.T) {
repository := &inspectionPromptRepository{err: promptdef.ErrPromptDefinitionNotFound}
_, err := (&Runner{promptDefs: repository}).InspectPrompt(context.Background(), "missing", "version")
_, err := (&Runner{promptDefs: repository}).InspectPrompt(context.Background(), "missing")
if !errors.Is(err, ErrPromptLoad) || !errors.Is(err, promptdef.ErrPromptDefinitionNotFound) {
t.Fatalf("missing prompt error=%v, want prompt load and not-found identities", err)
}
@@ -179,7 +173,7 @@ func TestRunnerInspectPromptClassifiesFailuresWithoutRepositoryWorkAfterCancella
}
for _, tc := range cases {
t.Run(tc.name, func(t *testing.T) {
_, err := tc.runner.InspectPrompt(context.Background(), "prompt", "version")
_, err := tc.runner.InspectPrompt(context.Background(), "prompt")
if !errors.Is(err, ErrPromptLoad) {
t.Fatalf("inspection error=%v, want prompt load", err)
}
@@ -202,11 +196,11 @@ func TestRunnerPrepareUsesThePromptInspectionSelectionAndHash(t *testing.T) {
nil,
)
inspection, err := runner.InspectPrompt(context.Background(), definition.ID, definition.Version)
inspection, err := runner.InspectPrompt(context.Background(), definition.ID)
if err != nil {
t.Fatalf("inspect prompt: %v", err)
}
prepared, err := runner.Prepare(context.Background(), domain.RunRequest{PromptID: definition.ID, PromptVersion: definition.Version, ProfileID: "exec"})
prepared, err := runner.Prepare(context.Background(), domain.RunRequest{PromptID: definition.ID, ProfileID: "exec"})
if err != nil {
t.Fatalf("prepare prompt: %v", err)
}

View File

@@ -12,15 +12,14 @@ import (
// RequirementInspectionRequest selects a captured prompt and supplies the
// context used for dependency classification.
type RequirementInspectionRequest struct {
PromptID string
PromptVersion string
ProfileID string
Vars map[string]string
SessionID string
PromptID string
ProfileID string
Vars map[string]string
SessionID string
}
type requirementSnapshotRepository interface {
GetRequirementSnapshot(id, version string) (prompt.RequirementSnapshot, bool)
GetRequirementSnapshot(id string) (prompt.RequirementSnapshot, bool)
}
// InspectRequirements discovers prompt inputs and caller variables without
@@ -40,7 +39,7 @@ func (r *Runner) InspectRequirements(
return nil, fmt.Errorf("%w: %w", ErrPromptLoad, err)
}
selection, err := r.resolvePromptInspection(ctx, req.PromptID, req.PromptVersion)
selection, err := r.resolvePromptInspection(ctx, req.PromptID)
if err != nil {
return nil, err
}
@@ -66,7 +65,7 @@ func (r *Runner) InspectRequirements(
if !ok {
return nil, fmt.Errorf("%w: prompt repository does not provide captured requirement snapshots", ErrPromptLoad)
}
snapshot, ok := repository.GetRequirementSnapshot(selection.PromptID, selection.PromptVersion)
snapshot, ok := repository.GetRequirementSnapshot(selection.PromptID)
if !ok {
return nil, fmt.Errorf("%w: captured requirement snapshot is unavailable", ErrPromptLoad)
}

View File

@@ -12,23 +12,20 @@ import (
)
type requirementInspectionPromptRepository struct {
definition *domain.PromptDefinition
snapshot prompt.RequirementSnapshot
lookupErr error
snapshotFound bool
lookupCalls int
snapshotCalls int
lookupID string
lookupVersion string
snapshotID string
snapshotVersion string
definition *domain.PromptDefinition
snapshot prompt.RequirementSnapshot
lookupErr error
snapshotFound bool
lookupCalls int
snapshotCalls int
lookupID string
snapshotID string
}
type requirementPromptMetadataRepository struct {
*requirementInspectionPromptRepository
inspection domain.PromptInspection
lookupID string
lookupVersion string
inspection domain.PromptInspection
lookupID string
}
type inspectionProfileIdentityRepository struct {
@@ -51,7 +48,6 @@ func (repository *inspectionProfileIdentityRepository) GetProfileIdentity(
func (repository *requirementInspectionPromptRepository) GetPromptDefinition(
context.Context,
string,
string,
) (*domain.PromptDefinition, error) {
return repository.definition, repository.lookupErr
}
@@ -59,10 +55,8 @@ func (repository *requirementInspectionPromptRepository) GetPromptDefinition(
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
@@ -71,21 +65,17 @@ func (repository *requirementPromptMetadataRepository) GetPromptInspection(
func (repository *requirementInspectionPromptRepository) GetPromptSnapshot(
_ context.Context,
id string,
version string,
) (*domain.PromptDefinition, string, error) {
repository.lookupCalls++
repository.lookupID = id
repository.lookupVersion = version
return repository.definition, "captured-hash", repository.lookupErr
}
func (repository *requirementInspectionPromptRepository) GetRequirementSnapshot(
id string,
version string,
) (prompt.RequirementSnapshot, bool) {
repository.snapshotCalls++
repository.snapshotID = id
repository.snapshotVersion = version
return repository.snapshot, repository.snapshotFound
}
@@ -111,16 +101,16 @@ func TestRunnerInspectRequirementsUsesCapturedSelectionWithoutExecutionWork(t *t
}}
runner := &Runner{promptDefs: repository, profiles: profiles}
inspection, err := runner.InspectRequirements(context.Background(), RequirementInspectionRequest{
PromptID: " requested ", PromptVersion: " exact-version ", ProfileID: "partial-profile",
PromptID: " requested ", ProfileID: "partial-profile",
Vars: map[string]string{"caller": ""}, SessionID: " direct-session ",
})
if err != nil {
t.Fatalf("inspect requirements: %v", err)
}
if repository.lookupCalls != 1 || repository.lookupID != " requested " || repository.lookupVersion != " exact-version " ||
repository.snapshotCalls != 1 || repository.snapshotID != definition.ID || repository.snapshotVersion != definition.Version {
t.Fatalf("selection lookup=(%d,%q,%q), snapshot=(%d,%q,%q)", repository.lookupCalls, repository.lookupID,
repository.lookupVersion, repository.snapshotCalls, repository.snapshotID, repository.snapshotVersion)
if repository.lookupCalls != 1 || repository.lookupID != " requested " ||
repository.snapshotCalls != 1 || repository.snapshotID != definition.ID {
t.Fatalf("selection lookup=(%d,%q), snapshot=(%d,%q)", repository.lookupCalls, repository.lookupID,
repository.snapshotCalls, repository.snapshotID)
}
if profiles.calls != 1 || profiles.id != "partial-profile" || inspection.PromptID != definition.ID ||
inspection.PromptVersion != definition.Version || inspection.ProfileID != "partial-profile" || !inspection.Complete ||
@@ -158,19 +148,18 @@ func TestRunnerInspectRequirementsUsesPromptMetadataAndExactRequirementSnapshot(
}
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 ",
PromptID: " requested-id ",
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" ||
if err != nil || promptRepository.lookupID != " requested-id " ||
baseRepository.snapshotID != "captured-id" ||
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)
t.Fatalf("metadata-based requirement inspection=(%+v, %v), prompt lookup=%q, snapshot=%q, profile=%q",
inspection, err, promptRepository.lookupID, baseRepository.snapshotID, profiles.identityID)
}
}
@@ -322,12 +311,12 @@ func TestRunnerInspectRequirementsClassifiesSelectionAndSnapshotFailures(t *test
}
})
t.Run("ambiguous prompt selection", func(t *testing.T) {
ambiguous := errors.New("ambiguous omitted version")
repository := &requirementInspectionPromptRepository{lookupErr: ambiguous}
t.Run("prompt lookup failure", func(t *testing.T) {
lookupFailure := errors.New("prompt lookup failed")
repository := &requirementInspectionPromptRepository{lookupErr: lookupFailure}
_, err := (&Runner{promptDefs: repository}).InspectRequirements(context.Background(), RequirementInspectionRequest{PromptID: "selected"})
if !errors.Is(err, ErrPromptLoad) || !errors.Is(err, ambiguous) || repository.lookupVersion != "" {
t.Fatalf("ambiguous selection error=%v version=%q", err, repository.lookupVersion)
if !errors.Is(err, ErrPromptLoad) || !errors.Is(err, lookupFailure) {
t.Fatalf("prompt lookup error=%v", err)
}
})

View File

@@ -315,7 +315,7 @@ func (r *Runner) resolvePreparation(
return nil, fmt.Errorf("%w: session_id: %v", ErrInvalidRequest, err)
}
promptSelection, err := r.resolvePromptDefinition(ctx, req.PromptID, req.PromptVersion)
promptSelection, err := r.resolvePromptDefinition(ctx, req.PromptID)
if err != nil {
return nil, err
}
@@ -517,22 +517,15 @@ func structuredOutputSpec(def *domain.PromptDefinition, schemaDocument any) *dom
return &domain.StructuredOutputSpec{
Type: domain.StructuredOutputJSONSchema,
JSONSchema: &domain.StructuredOutputJSONSpec{
Name: deriveStructuredSchemaName(def.ID, def.Version),
Name: deriveStructuredSchemaName(def.ID),
Strict: true,
Schema: schemaDocument,
},
}
}
func deriveStructuredSchemaName(promptID string, promptVersion string) string {
func deriveStructuredSchemaName(promptID string) string {
raw := strings.TrimSpace(promptID)
if v := strings.TrimSpace(promptVersion); v != "" {
if raw == "" {
raw = v
} else {
raw = raw + "_" + v
}
}
var b strings.Builder
for _, r := range raw {

View File

@@ -24,10 +24,9 @@ import (
)
type fakePromptRepo struct {
def *domain.PromptDefinition
err error
lastID string
lastVersion string
def *domain.PromptDefinition
err error
lastID string
}
type fakeExecutionProfileRepo struct {
@@ -43,7 +42,6 @@ type staticPromptRepo struct {
func (r staticPromptRepo) GetPromptDefinition(
context.Context,
string,
string,
) (*domain.PromptDefinition, error) {
return r.def, nil
}
@@ -94,9 +92,8 @@ func (f *fakeExecutionProfileRepo) GetProfile(ctx context.Context, id string) (*
return nil, errors.New("profile not found")
}
func (f *fakePromptRepo) GetPromptDefinition(ctx context.Context, id string, version string) (*domain.PromptDefinition, error) {
func (f *fakePromptRepo) GetPromptDefinition(ctx context.Context, id string) (*domain.PromptDefinition, error) {
f.lastID = id
f.lastVersion = version
if f.err != nil {
return nil, f.err
}
@@ -358,9 +355,8 @@ func TestRunnerPrepareWithExplicitProfileSelection(t *testing.T) {
runner := NewRunner(promptRepo, execRepo, reader, renderer, llmClient, nil, nil)
prepared, err := runner.Prepare(context.Background(), domain.RunRequest{
PromptID: "p",
PromptVersion: "1",
ProfileID: "exec",
PromptID: "p",
ProfileID: "exec",
Inputs: map[string]domain.ArtifactRef{
"transcript": {Type: domain.ArtifactRefFile, URI: "a://t"},
"glossary": {Type: domain.ArtifactRefFile, URI: "a://g"},
@@ -956,8 +952,8 @@ func TestRunnerPrepareJSONSchemaBuildsStructuredOutputSpec(t *testing.T) {
if prepared.StructuredOutput.JSONSchema == nil {
t.Fatal("expected structured output json_schema payload")
}
if prepared.StructuredOutput.JSONSchema.Name != "p_1" {
t.Fatalf("expected derived schema name p_1, got %q", prepared.StructuredOutput.JSONSchema.Name)
if prepared.StructuredOutput.JSONSchema.Name != "p" {
t.Fatalf("expected derived schema name p, got %q", prepared.StructuredOutput.JSONSchema.Name)
}
if prepared.StructuredOutput.JSONSchema.Strict != true {
t.Fatalf("expected strict=true, got %v", prepared.StructuredOutput.JSONSchema.Strict)
@@ -1022,28 +1018,25 @@ func TestRunnerRunJSONSchemaSchemaLoadFailureFailsBeforeLLM(t *testing.T) {
func TestDeriveStructuredSchemaName(t *testing.T) {
tests := []struct {
name string
id string
version string
want string
name string
id string
want string
}{
{
name: "sanitizes punctuation and keeps dashes",
id: "prompt.id/alpha",
version: "1.0.0-beta",
want: "prompt_id_alpha_1_0_0-beta",
name: "sanitizes punctuation and keeps dashes",
id: "prompt.id/alpha",
want: "prompt_id_alpha",
},
{
name: "fallback when empty",
id: "",
version: "",
want: "promptkit_schema",
name: "fallback when empty",
id: "",
want: "promptkit_schema",
},
}
for _, tc := range tests {
t.Run(tc.name, func(t *testing.T) {
got := deriveStructuredSchemaName(tc.id, tc.version)
got := deriveStructuredSchemaName(tc.id)
if got != tc.want {
t.Fatalf("expected %q, got %q", tc.want, got)
}
@@ -1253,9 +1246,8 @@ func TestRunnerRunSuccessful(t *testing.T) {
runner := NewRunner(promptRepo, execRepo, reader, renderer, llmClient, nil, nil)
res, err := runner.Run(context.Background(), domain.RunRequest{
PromptID: "p",
PromptVersion: "1",
ProfileID: "exec",
PromptID: "p",
ProfileID: "exec",
Inputs: map[string]domain.ArtifactRef{
"transcript": {Type: domain.ArtifactRefFile, URI: "a://t"},
"glossary": {Type: domain.ArtifactRefFile, URI: "a://g"},
@@ -2325,8 +2317,8 @@ func TestRunnerRepairStateMachine(t *testing.T) {
t.Fatalf("initial structured output = %+v, want present %v", initialRequest.StructuredOutput, tc.structured)
}
if tc.structured && (initialRequest.StructuredOutput.JSONSchema == nil ||
initialRequest.StructuredOutput.JSONSchema.Name != "p_1") {
t.Fatalf("initial JSON Schema metadata = %+v, want derived schema name p_1", initialRequest.StructuredOutput)
initialRequest.StructuredOutput.JSONSchema.Name != "p") {
t.Fatalf("initial JSON Schema metadata = %+v, want derived schema name p", initialRequest.StructuredOutput)
}
for index, req := range repairer.reqs {

View File

@@ -35,13 +35,9 @@ func (r *Runner) resolveSmokeTestTarget(ctx context.Context, req domain.SmokeTes
return nil, fmt.Errorf("%w: %w", ErrInvalidRequest, err)
}
if req.PromptID == "" && req.PromptVersion != "" {
return nil, fmt.Errorf("%w: prompt version requires a prompt id", ErrInvalidRequest)
}
var promptInspection *domain.PromptInspection
if req.PromptID != "" {
promptInspection, err = r.resolvePromptInspection(ctx, req.PromptID, req.PromptVersion)
promptInspection, err = r.resolvePromptInspection(ctx, req.PromptID)
if err != nil {
return nil, err
}

View File

@@ -88,7 +88,7 @@ func TestResolveSmokeTestTargetSelectionAndRouting(t *testing.T) {
{
name: "prompt default",
request: domain.SmokeTestRequest{
Kind: domain.SmokeTestTextInference, PromptID: "selection.prompt", PromptVersion: "v1",
Kind: domain.SmokeTestTextInference, PromptID: "selection.prompt",
},
profileID: "prompt-profile",
backendID: "beta",
@@ -100,7 +100,7 @@ func TestResolveSmokeTestTargetSelectionAndRouting(t *testing.T) {
{
name: "explicit profile overrides prompt default",
request: domain.SmokeTestRequest{
Kind: domain.SmokeTestTextInference, PromptID: "selection.prompt", PromptVersion: "v1",
Kind: domain.SmokeTestTextInference, PromptID: "selection.prompt",
ProfileID: "alpha-profile", BackendID: "beta",
},
profileID: "alpha-profile",
@@ -138,7 +138,7 @@ func TestResolveSmokeTestTargetSelectionAndRouting(t *testing.T) {
{
name: "prompt profile supplies backend-only target over backend hint",
request: domain.SmokeTestRequest{
Kind: domain.SmokeTestReachability, PromptID: "selection.prompt", PromptVersion: "v1", BackendID: "alpha",
Kind: domain.SmokeTestReachability, PromptID: "selection.prompt", BackendID: "alpha",
},
profileID: "prompt-profile",
backendID: "beta",
@@ -150,7 +150,7 @@ func TestResolveSmokeTestTargetSelectionAndRouting(t *testing.T) {
{
name: "backend-only probe uses backend when prompt has no profile default",
request: domain.SmokeTestRequest{
Kind: domain.SmokeTestReachability, PromptID: "backend.prompt", PromptVersion: "v1", BackendID: "delta",
Kind: domain.SmokeTestReachability, PromptID: "backend.prompt", BackendID: "delta",
},
backendID: "delta",
selectionSource: smokeSelectionSourceBackend,
@@ -171,7 +171,7 @@ func TestResolveSmokeTestTargetSelectionAndRouting(t *testing.T) {
selected.target.EffectiveSettings.Model != test.wantModel {
t.Fatalf("unexpected target: %+v", selected.target)
}
if test.request.PromptID != "" && (selected.target.PromptID != test.request.PromptID || selected.target.PromptVersion != test.request.PromptVersion) {
if test.request.PromptID != "" && selected.target.PromptID != test.request.PromptID {
t.Fatalf("prompt identity was not retained: %+v", selected.target)
}
})
@@ -276,13 +276,6 @@ func TestResolveSmokeTestTargetSelectionAndSettingsErrors(t *testing.T) {
},
wantErr: ErrInvalidRequest,
},
{
name: "version cannot be supplied without prompt",
request: domain.SmokeTestRequest{
Kind: domain.SmokeTestTextInference, PromptVersion: " ", BackendID: "epsilon",
},
wantErr: ErrInvalidRequest,
},
{
name: "dangling backend default fails only when selected",
request: domain.SmokeTestRequest{Kind: domain.SmokeTestTextInference, BackendID: "delta"},