Harden public ownership and diagnostic contracts
This commit is contained in:
96
llm_adapter_internal_test.go
Normal file
96
llm_adapter_internal_test.go
Normal file
@@ -0,0 +1,96 @@
|
||||
package promptkit
|
||||
|
||||
import (
|
||||
"context"
|
||||
"reflect"
|
||||
"strconv"
|
||||
"sync"
|
||||
"testing"
|
||||
|
||||
"gitea.maximumdirect.net/eric/promptkit/internal/domain"
|
||||
)
|
||||
|
||||
func TestPublicLLMClientAdapterGivesClientOwnedNestedValues(t *testing.T) {
|
||||
source := adapterOwnershipRequest()
|
||||
want := adapterOwnershipRequest()
|
||||
client := &retainingMutatingLLMClient{}
|
||||
adapter := publicLLMClientAdapter{client: client}
|
||||
|
||||
if _, err := adapter.Generate(context.Background(), source); err != nil {
|
||||
t.Fatalf("generate: %v", err)
|
||||
}
|
||||
if !reflect.DeepEqual(source, want) {
|
||||
t.Fatalf("client mutation changed prepared source:\ngot %#v\nwant %#v", source, want)
|
||||
}
|
||||
|
||||
var mutations sync.WaitGroup
|
||||
mutations.Add(1)
|
||||
go func() {
|
||||
defer mutations.Done()
|
||||
for i := 0; i < 10_000; i++ {
|
||||
mutateGenerateRequest(&client.retained, strconv.Itoa(i))
|
||||
}
|
||||
}()
|
||||
for i := 0; i < 10_000; i++ {
|
||||
laterRequest := fromDomainGenerateRequest(source)
|
||||
if laterRequest.Prompt.Messages[0].Content != "source-message" ||
|
||||
laterRequest.Prompt.Messages[0].CacheControl.TTL != "source-ttl" ||
|
||||
laterRequest.Target.ExtraParams["nested"].([]any)[0] != "source-extra" ||
|
||||
laterRequest.StructuredOutput.JSONSchema.Schema.(map[string]any)["enum"].([]any)[0] != "source-schema" {
|
||||
t.Fatal("retained client mutation reached a later execution request")
|
||||
}
|
||||
}
|
||||
mutations.Wait()
|
||||
|
||||
if !reflect.DeepEqual(source, want) {
|
||||
t.Fatalf("retained client mutation changed prepared source:\ngot %#v\nwant %#v", source, want)
|
||||
}
|
||||
}
|
||||
|
||||
type retainingMutatingLLMClient struct {
|
||||
retained GenerateRequest
|
||||
}
|
||||
|
||||
func (c *retainingMutatingLLMClient) Generate(_ context.Context, request GenerateRequest) (*GenerateResponse, error) {
|
||||
c.retained = request
|
||||
mutateGenerateRequest(&c.retained, "client-mutation")
|
||||
return &GenerateResponse{Content: "generated"}, nil
|
||||
}
|
||||
|
||||
func adapterOwnershipRequest() domain.GenerateRequest {
|
||||
return domain.GenerateRequest{
|
||||
Prompt: domain.RenderedPrompt{
|
||||
SessionID: "source-session",
|
||||
Messages: []domain.RenderedMessage{{
|
||||
Role: "user",
|
||||
Content: "source-message",
|
||||
CacheControl: &domain.CacheControl{
|
||||
Type: domain.CacheControlEphemeral,
|
||||
TTL: "source-ttl",
|
||||
},
|
||||
}},
|
||||
},
|
||||
Target: domain.ExecutionTarget{
|
||||
Model: "source-model",
|
||||
APIKey: "source-api-key",
|
||||
ExtraParams: map[string]any{
|
||||
"nested": []any{"source-extra"},
|
||||
},
|
||||
},
|
||||
StructuredOutput: &domain.StructuredOutputSpec{
|
||||
Type: domain.StructuredOutputJSONSchema,
|
||||
JSONSchema: &domain.StructuredOutputJSONSpec{
|
||||
Name: "source-schema-name",
|
||||
Strict: true,
|
||||
Schema: map[string]any{"enum": []any{"source-schema"}},
|
||||
},
|
||||
},
|
||||
}
|
||||
}
|
||||
|
||||
func mutateGenerateRequest(request *GenerateRequest, value string) {
|
||||
request.Prompt.Messages[0].Content = value
|
||||
request.Prompt.Messages[0].CacheControl.TTL = value
|
||||
request.Target.ExtraParams["nested"].([]any)[0] = value
|
||||
request.StructuredOutput.JSONSchema.Schema.(map[string]any)["enum"].([]any)[0] = value
|
||||
}
|
||||
Reference in New Issue
Block a user