Reconcile prompt execution provenance
This commit is contained in:
@@ -70,6 +70,90 @@ func TestExecutePreparedProfileBoundsOversizedExecutorOutput(t *testing.T) {
|
||||
}
|
||||
}
|
||||
|
||||
func TestExecutePreparedProfileRejectsInconsistentProvenance(t *testing.T) {
|
||||
tests := []struct {
|
||||
name string
|
||||
mutate func(*preparedReport, *PromptInspectionResult, *promptexec.ProfileInspection, *generationExecutor)
|
||||
invoked bool
|
||||
}{
|
||||
{
|
||||
name: "prepared definition", mutate: func(prepared *preparedReport, _ *PromptInspectionResult, _ *promptexec.ProfileInspection, _ *generationExecutor) {
|
||||
prepared.resolved.Definition.PromptVersion = "different-version"
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "missing callback", mutate: func(_ *preparedReport, _ *PromptInspectionResult, _ *promptexec.ProfileInspection, executor *generationExecutor) {
|
||||
executor.skipPreparation = true
|
||||
}, invoked: true,
|
||||
},
|
||||
{
|
||||
name: "duplicate callback", mutate: func(_ *preparedReport, _ *PromptInspectionResult, _ *promptexec.ProfileInspection, executor *generationExecutor) {
|
||||
executor.preparationCalls = 2
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "callback prompt hash", mutate: func(_ *preparedReport, _ *PromptInspectionResult, _ *promptexec.ProfileInspection, executor *generationExecutor) {
|
||||
executor.prepare = func(value *promptexec.Preparation) { value.PromptHash = "different-hash" }
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "callback output schema", mutate: func(_ *preparedReport, _ *PromptInspectionResult, _ *promptexec.ProfileInspection, executor *generationExecutor) {
|
||||
executor.prepare = func(value *promptexec.Preparation) { value.Output.SchemaPath = "other.generated_text.schema.json" }
|
||||
},
|
||||
},
|
||||
{
|
||||
name: "completed profile", mutate: func(_ *preparedReport, _ *PromptInspectionResult, _ *promptexec.ProfileInspection, executor *generationExecutor) {
|
||||
executor.complete = func(value *promptexec.Execution) { value.ProfileID = "different-profile" }
|
||||
}, invoked: true,
|
||||
},
|
||||
{
|
||||
name: "completed rendered prompt hash", mutate: func(_ *preparedReport, _ *PromptInspectionResult, _ *promptexec.ProfileInspection, executor *generationExecutor) {
|
||||
executor.complete = func(value *promptexec.Execution) { value.RenderedPromptHash = "different-rendered-hash" }
|
||||
}, invoked: true,
|
||||
},
|
||||
{
|
||||
name: "completed input hashes", mutate: func(_ *preparedReport, _ *PromptInspectionResult, _ *promptexec.ProfileInspection, executor *generationExecutor) {
|
||||
executor.prepare = func(value *promptexec.Preparation) {
|
||||
value.InputHashes = map[string]string{"data_package": "prepared-hash"}
|
||||
}
|
||||
executor.complete = func(value *promptexec.Execution) {
|
||||
value.InputHashes = map[string]string{"data_package": "completed-hash"}
|
||||
}
|
||||
}, invoked: true,
|
||||
},
|
||||
{
|
||||
name: "completed validation mode", mutate: func(_ *preparedReport, _ *PromptInspectionResult, _ *promptexec.ProfileInspection, executor *generationExecutor) {
|
||||
executor.complete = func(value *promptexec.Execution) { value.Validation.Mode = "other" }
|
||||
}, invoked: true,
|
||||
},
|
||||
{
|
||||
name: "completed validation schema", mutate: func(_ *preparedReport, _ *PromptInspectionResult, _ *promptexec.ProfileInspection, executor *generationExecutor) {
|
||||
executor.complete = func(value *promptexec.Execution) { value.Validation.SchemaPath = "other.generated_text.schema.json" }
|
||||
}, invoked: true,
|
||||
},
|
||||
}
|
||||
|
||||
for _, tt := range tests {
|
||||
t.Run(tt.name, func(t *testing.T) {
|
||||
prepared, inspection := preparedDailyProfile(t)
|
||||
profile := promptexec.ProfileInspection{ProfileID: inspection.ProfileID, BackendID: inspection.BackendID, ModelName: inspection.ModelName}
|
||||
executor := &generationExecutor{}
|
||||
tt.mutate(&prepared, &inspection, &profile, executor)
|
||||
|
||||
outcome, rendered, err := executePreparedProfile(context.Background(), profileExecutionRequest{Prepared: prepared, Prompt: inspection, Profile: profile, Executor: executor})
|
||||
if err == nil || promptexec.CategoryOf(err) != promptexec.InvalidConfiguration || len(rendered) != 0 {
|
||||
t.Fatalf("outcome/rendered/error = %#v/%q/%v", outcome, rendered, err)
|
||||
}
|
||||
if outcome.ProfileID != profile.ProfileID || outcome.BackendID != profile.BackendID || outcome.ModelName != profile.ModelName || outcome.ValidationStatus != "" {
|
||||
t.Fatalf("outcome retained unverified provenance: %#v", outcome)
|
||||
}
|
||||
if (executor.executeCalls == 1) != tt.invoked {
|
||||
t.Fatalf("executor calls = %d, want invoked=%t", executor.executeCalls, tt.invoked)
|
||||
}
|
||||
})
|
||||
}
|
||||
}
|
||||
|
||||
func preparedDailyProfile(t *testing.T) (preparedReport, PromptInspectionResult) {
|
||||
t.Helper()
|
||||
cfg := generationConfig()
|
||||
@@ -85,5 +169,5 @@ func preparedDailyProfile(t *testing.T) (preparedReport, PromptInspectionResult)
|
||||
if err != nil {
|
||||
t.Fatalf("prepareReport() error = %v", err)
|
||||
}
|
||||
return prepared, PromptInspectionResult{PromptID: resolved.Definition.PromptID, PromptVersion: resolved.Definition.PromptVersion, PromptHash: "prompt-hash", ProfileID: "fixture", BackendID: "fixture", ModelName: "fixture-model"}
|
||||
return prepared, PromptInspectionResult{PromptID: resolved.Definition.PromptID, PromptVersion: resolved.Definition.PromptVersion, PromptHash: generationPromptHash, ProfileID: "fixture", BackendID: "fixture", ModelName: "fixture-model"}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user