first commit

This commit is contained in:
Beyhan Oğur
2026-04-26 21:52:23 +03:00
commit 880f412e2c
2662 changed files with 866266 additions and 0 deletions

View File

@@ -0,0 +1,179 @@
package llmtests
import (
"context"
"os"
"testing"
"github.com/bytedance/sonic"
bifrost "github.com/maximhq/bifrost/core"
"github.com/maximhq/bifrost/core/schemas"
)
// RunPassthroughExtraParamsTest executes the passthrough extraParams test scenario
// This test verifies that extraParams are properly propagated into the provider request body
// when the passthrough flag is set in the context.
// Note: This test only runs for providers that support arbitrary extra params at the root level
// of the request body. Providers like Anthropic have strict schema validation and don't accept
// unknown fields, so they should set PassThroughExtraParams: false in their test config.
func RunPassthroughExtraParamsTest(t *testing.T, client *bifrost.Bifrost, ctx context.Context, testConfig ComprehensiveTestConfig) {
// Guard: Check if ChatModel is configured
if testConfig.ChatModel == "" {
t.Logf("ChatModel not configured for provider %s, skipping passthrough test", testConfig.Provider)
return
}
if !testConfig.Scenarios.PassThroughExtraParams {
t.Logf("PassThroughExtraParams not supported for provider %s, skipping passthrough test", testConfig.Provider)
return
}
t.Run("PassthroughExtraParams", func(t *testing.T) {
if os.Getenv("SKIP_PARALLEL_TESTS") != "true" {
t.Parallel()
}
// Create a Bifrost context with passthrough extraParams enabled
bfCtx := schemas.NewBifrostContext(ctx, schemas.NoDeadline)
bfCtx.SetValue(schemas.BifrostContextKeyPassthroughExtraParams, true)
bfCtx.SetValue(schemas.BifrostContextKeySendBackRawRequest, true)
// Prepare chat request with extraParams
// custom_param will be at root level
// custom_nested will be a nested structure to test recursive merging
chatReq := &schemas.BifrostChatRequest{
Provider: testConfig.Provider,
Model: testConfig.ChatModel,
Input: []schemas.ChatMessage{
CreateBasicChatMessage("Say hello in one word"),
},
Params: &schemas.ChatParameters{
MaxCompletionTokens: bifrost.Ptr(10),
// Set extraParams with custom_param and nested structure
ExtraParams: map[string]interface{}{
"custom_param": "test_value_123",
"custom_nested": map[string]interface{}{
"custom_field": "nested_custom_value_456",
"another_nested": map[string]interface{}{
"deep_field": "deep_value_789",
},
},
},
},
Fallbacks: testConfig.Fallbacks,
}
// Make the request
response, err := client.ChatCompletionRequest(bfCtx, chatReq)
if err != nil {
t.Fatalf("❌ Chat completion request failed: %s", GetErrorMessage(err))
}
if response == nil {
t.Fatalf("❌ Chat completion response is nil")
}
// Verify the response is valid
chatContent := GetChatContent(response)
if chatContent == "" {
t.Fatalf("❌ Chat response content is empty")
}
t.Logf("✅ Chat completion request completed successfully")
t.Logf("Response content: %s", chatContent)
// Verify raw request is present in ExtraFields
if response.ExtraFields.RawRequest == nil {
t.Logf("⚠️ Raw request not found in ExtraFields - this may be provider-specific")
t.Logf(" Check Bifrost logs for the raw request body sent to provider")
t.Logf(" Expected in raw request:")
t.Logf(" - 'custom_param': 'test_value_123'")
t.Logf(" - 'custom_nested.custom_field': 'nested_custom_value_456'")
t.Logf(" - 'custom_nested.another_nested.deep_field': 'deep_value_789'")
return
}
// Parse raw request
var rawRequest map[string]interface{}
rawRequestBytes, marshalErr := sonic.Marshal(response.ExtraFields.RawRequest)
if marshalErr != nil {
t.Fatalf("❌ Failed to marshal raw request: %v", marshalErr)
}
if err := sonic.Unmarshal(rawRequestBytes, &rawRequest); err != nil {
t.Fatalf("❌ Failed to unmarshal raw request: %v", err)
}
t.Logf("✅ Found raw request in response ExtraFields")
t.Logf("Raw request keys: %v", getMapKeys(rawRequest))
// Verify custom_param is in raw request
if customParam, exists := rawRequest["custom_param"]; !exists {
t.Errorf("❌ custom_param not found in raw request")
} else {
if customParamStr, ok := customParam.(string); !ok || customParamStr != "test_value_123" {
t.Errorf("❌ custom_param value mismatch: expected 'test_value_123', got %v", customParam)
} else {
t.Logf("✅ Verified custom_param in raw request: %s", customParamStr)
}
}
// Verify nested custom_nested structure
if customNested, exists := rawRequest["custom_nested"]; !exists {
t.Errorf("❌ custom_nested not found in raw request")
} else {
customNestedMap, ok := customNested.(map[string]interface{})
if !ok {
t.Errorf("❌ custom_nested is not a map: %T", customNested)
} else {
// Verify custom_field
if customField, exists := customNestedMap["custom_field"]; !exists {
t.Errorf("❌ custom_field not found in custom_nested")
} else {
if customFieldStr, ok := customField.(string); !ok || customFieldStr != "nested_custom_value_456" {
t.Errorf("❌ custom_field value mismatch: expected 'nested_custom_value_456', got %v", customField)
} else {
t.Logf("✅ Verified custom_field in custom_nested: %s", customFieldStr)
}
}
// Verify deeply nested another_nested.deep_field
if anotherNested, exists := customNestedMap["another_nested"]; !exists {
t.Errorf("❌ another_nested not found in custom_nested")
} else {
anotherNestedMap, ok := anotherNested.(map[string]interface{})
if !ok {
t.Errorf("❌ another_nested is not a map: %T", anotherNested)
} else {
if deepField, exists := anotherNestedMap["deep_field"]; !exists {
t.Errorf("❌ deep_field not found in another_nested")
} else {
if deepFieldStr, ok := deepField.(string); !ok || deepFieldStr != "deep_value_789" {
t.Errorf("❌ deep_field value mismatch: expected 'deep_value_789', got %v", deepField)
} else {
t.Logf("✅ Verified deep_field in another_nested: %s", deepFieldStr)
}
}
}
}
}
}
// Log the full raw request for debugging (pretty printed)
rawRequestJSON, marshalErr := sonic.MarshalIndent(rawRequest, "", " ")
if marshalErr == nil {
t.Logf("📋 Full raw request body:\n%s", string(rawRequestJSON))
}
t.Logf("🎉 PassthroughExtraParams test completed successfully!")
})
}
// getMapKeys returns all keys from a map as a slice of strings
func getMapKeys(m map[string]interface{}) []string {
keys := make([]string, 0, len(m))
for k := range m {
keys = append(keys, k)
}
return keys
}