Files
2026-08-23 22:03:57 +02:00

75 lines
2.6 KiB
Go

package aiprovider
import (
"context"
"testing"
"github.com/descrybe/descrybe-v2/apps/api/internal/aiaudit"
"github.com/descrybe/descrybe-v2/apps/api/internal/processing"
"github.com/google/uuid"
)
type optionsStub struct{ withOptions, plain int }
func (s *optionsStub) Complete(context.Context, string, string) (processing.Completion, error) {
s.plain++
return processing.Completion{Text: "{}"}, nil
}
func (s *optionsStub) CompleteWithOptions(context.Context, string, string, processing.CompleteOptions) (processing.Completion, error) {
s.withOptions++
return processing.Completion{Text: "{}"}, nil
}
// Regression: processing.CompleteOnce prefers CompleterWithOptions and only falls
// back to Complete. A wrapper that does not forward the options interface silently
// drops MaxTokens / Temperature / ReasoningEffort for every enhance call.
func TestAuditingCompleter_forwardsCompleteWithOptions(t *testing.T) {
t.Parallel()
inner := &optionsStub{}
svc := &Service{Audit: &aiaudit.Recorder{}}
wrapped := svc.WrapAudit(inner, uuid.New(), RoleProcessing, "internal")
if _, ok := wrapped.(processing.CompleterWithOptions); !ok {
t.Fatal("wrapped completer must still satisfy CompleterWithOptions")
}
if _, err := processing.CompleteOnce(context.Background(), wrapped, "sys", "user",
processing.CompleteOptions{MaxTokens: 1234}); err != nil {
t.Fatal(err)
}
if inner.withOptions != 1 || inner.plain != 0 {
t.Fatalf("options path not forwarded: withOptions=%d plain=%d", inner.withOptions, inner.plain)
}
}
// A plain Completer must not gain the options interface just by being wrapped —
// that would send options to a client that cannot honour them.
func TestAuditingCompleter_plainCompleterStaysPlain(t *testing.T) {
t.Parallel()
inner := plainStub{}
svc := &Service{Audit: &aiaudit.Recorder{}}
wrapped := svc.WrapAudit(inner, uuid.New(), RoleProcessing, "internal")
if _, ok := wrapped.(processing.CompleterWithOptions); ok {
t.Fatal("plain completer must not advertise CompleterWithOptions")
}
}
type plainStub struct{}
func (plainStub) Complete(context.Context, string, string) (processing.Completion, error) {
return processing.Completion{Text: "{}"}, nil
}
func TestWrapAudit_noopWhenCaptureOff(t *testing.T) {
t.Parallel()
inner := plainStub{}
var svc *Service
if got := svc.WrapAudit(inner, uuid.Nil, RoleProcessing, ""); got != processing.Completer(inner) {
t.Fatal("nil service must return the completer untouched")
}
svc = &Service{}
if got := svc.WrapAudit(inner, uuid.Nil, RoleProcessing, ""); got != processing.Completer(inner) {
t.Fatal("capture off must return the completer untouched")
}
}