97 lines
2.8 KiB
Go
97 lines
2.8 KiB
Go
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
|
|
}
|