Skip to content

Commit ee44db4

Browse files
committed
azure and bedrock test case fixes
1 parent b767356 commit ee44db4

File tree

6 files changed

+64
-48
lines changed

6 files changed

+64
-48
lines changed

.github/workflows/scripts/release-core.sh

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -55,7 +55,7 @@ echo "✅ MCP test servers built"
5555
# Run core tests with coverage
5656
echo "🔧 Running core tests with coverage..."
5757
cd core
58-
go test -race -v -timeout 20m -coverprofile=coverage.txt -coverpkg=./... ./...
58+
go test -race -timeout 20m -coverprofile=coverage.txt -coverpkg=./... ./...
5959

6060
# Upload coverage to Codecov
6161
if [ -n "${CODECOV_TOKEN:-}" ]; then

core/internal/llmtests/batch.go

Lines changed: 17 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,11 @@ func getFakeBatchID(provider schemas.ModelProvider) string {
1818
case schemas.OpenAI, schemas.Azure:
1919
return "batch_test-batch-id"
2020
case schemas.Bedrock:
21-
// Bedrock uses ARNs for batch IDs
22-
return "arn:aws:bedrock:us-east-1:791152688819:model-invocation-job/test-batch-id"
21+
// Bedrock uses ARNs for batch IDs - job ID must be exactly 12 lowercase alphanumeric chars
22+
return "arn:aws:bedrock:us-east-1:791152688819:model-invocation-job/aaaaaaaaaaaa"
2323
case schemas.Gemini:
24-
// Gemini uses "batches/" prefix for batch IDs
25-
return "batches/test-batch-id"
24+
// Gemini uses "batches/" prefix with alphanumeric batch IDs
25+
return "batches/aaaaaaaaaaaa"
2626
default:
2727
return "batch_test-batch-id"
2828
}
@@ -464,23 +464,30 @@ func RunBatchResultsTest(t *testing.T, client *bifrost.Bifrost, ctx context.Cont
464464
}
465465
}
466466

467-
// Check error type/message for "not found" indicators
468-
isNotFoundError := false
467+
// Check error type/message for "not found" or validation error indicators
468+
// Providers may return "not found" errors OR validation errors for fake batch IDs
469+
isExpectedError := false
469470
if err.Error != nil {
470471
if err.Error.Type != nil {
471472
errType := strings.ToLower(*err.Error.Type)
472473
if strings.Contains(errType, "not_found") || strings.Contains(errType, "notfound") {
473-
isNotFoundError = true
474+
isExpectedError = true
474475
}
475476
}
476477
errMsg := strings.ToLower(err.Error.Message)
478+
// Check for "not found" style errors
477479
if strings.Contains(errMsg, "not found") || strings.Contains(errMsg, "does not exist") || strings.Contains(errMsg, "could not find") {
478-
isNotFoundError = true
480+
isExpectedError = true
481+
}
482+
// Check for validation/parsing errors (providers validate batch ID format before lookup)
483+
if strings.Contains(errMsg, "could not parse") || strings.Contains(errMsg, "validation error") ||
484+
strings.Contains(errMsg, "failed to satisfy constraint") || strings.Contains(errMsg, "invalid") {
485+
isExpectedError = true
479486
}
480487
}
481488

482-
if isNotFoundError {
483-
t.Logf("[INFO] BatchResults test completed (expected not found error with fake ID): %v", GetErrorMessage(err))
489+
if isExpectedError {
490+
t.Logf("[INFO] BatchResults test completed (expected error with fake ID): %v", GetErrorMessage(err))
484491
return
485492
}
486493

core/internal/llmtests/image_generation.go

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,11 @@ import (
1919

2020
// RunImageGenerationTest executes the end-to-end image generation test (non-streaming)
2121
func RunImageGenerationTest(t *testing.T, client *bifrost.Bifrost, ctx context.Context, testConfig ComprehensiveTestConfig) {
22+
if !testConfig.Scenarios.ImageGeneration {
23+
t.Logf("Image generation not supported for provider %s", testConfig.Provider)
24+
return
25+
}
26+
2227
if testConfig.ImageGenerationModel == "" {
2328
t.Logf("Image generation not configured for provider %s", testConfig.Provider)
2429
return

core/providers/azure/azure.go

Lines changed: 35 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -1105,41 +1105,50 @@ func (provider *AzureProvider) SpeechStream(ctx *schemas.BifrostContext, postHoo
11051105
audioData = event
11061106
}
11071107

1108-
// First, try to parse as JSON error response (these would be valid JSON text)
1109-
var bifrostErr schemas.BifrostError
1110-
if err := sonic.Unmarshal(audioData, &bifrostErr); err == nil {
1111-
if bifrostErr.Error != nil && bifrostErr.Error.Message != "" {
1112-
bifrostErr.ExtraFields = schemas.BifrostErrorExtraFields{
1113-
Provider: provider.GetProviderKey(),
1114-
ModelRequested: request.Model,
1115-
RequestType: schemas.SpeechStreamRequest,
1108+
// Skip empty data
1109+
if len(audioData) == 0 {
1110+
continue
1111+
}
1112+
1113+
// Azure sends JSON-wrapped responses for speech streaming
1114+
// Parse the JSON to extract the response type and audio data
1115+
var response schemas.BifrostSpeechStreamResponse
1116+
if err := sonic.Unmarshal(audioData, &response); err != nil {
1117+
// If JSON parsing fails, check if this might be an error response
1118+
var bifrostErr schemas.BifrostError
1119+
if errParseErr := sonic.Unmarshal(audioData, &bifrostErr); errParseErr == nil {
1120+
if bifrostErr.Error != nil && bifrostErr.Error.Message != "" {
1121+
bifrostErr.ExtraFields = schemas.BifrostErrorExtraFields{
1122+
Provider: provider.GetProviderKey(),
1123+
ModelRequested: request.Model,
1124+
RequestType: schemas.SpeechStreamRequest,
1125+
}
1126+
ctx.SetValue(schemas.BifrostContextKeyStreamEndIndicator, true)
1127+
providerUtils.ProcessAndSendBifrostError(ctx, postHookRunner, &bifrostErr, responseChan, provider.logger)
1128+
return
11161129
}
1117-
ctx.SetValue(schemas.BifrostContextKeyStreamEndIndicator, true)
1118-
providerUtils.ProcessAndSendBifrostError(ctx, postHookRunner, &bifrostErr, responseChan, provider.logger)
1119-
return
11201130
}
1131+
// If it's not valid JSON, log and skip
1132+
provider.logger.Warn("failed to parse speech stream response: %v", err)
1133+
continue
11211134
}
11221135

1123-
// Skip empty audio data
1124-
if len(audioData) == 0 {
1136+
// Check for completion event - skip if no audio data
1137+
if response.Type == schemas.SpeechStreamResponseTypeDone || len(response.Audio) == 0 {
1138+
// This is a control event or empty response - skip
11251139
continue
11261140
}
11271141

11281142
chunkIndex++
11291143

1130-
// Create response with raw audio data
1131-
// Azure sends raw binary MP3 frames (starting with 0xff 0xf3 or 0xff 0xfb)
1132-
response := schemas.BifrostSpeechStreamResponse{
1133-
Type: schemas.SpeechStreamResponseTypeDelta,
1134-
Audio: audioData,
1135-
ExtraFields: schemas.BifrostResponseExtraFields{
1136-
RequestType: schemas.SpeechStreamRequest,
1137-
Provider: provider.GetProviderKey(),
1138-
ModelRequested: request.Model,
1139-
ModelDeployment: deployment,
1140-
ChunkIndex: chunkIndex,
1141-
Latency: time.Since(lastChunkTime).Milliseconds(),
1142-
},
1144+
// Set extra fields for the response
1145+
response.ExtraFields = schemas.BifrostResponseExtraFields{
1146+
RequestType: schemas.SpeechStreamRequest,
1147+
Provider: provider.GetProviderKey(),
1148+
ModelRequested: request.Model,
1149+
ModelDeployment: deployment,
1150+
ChunkIndex: chunkIndex,
1151+
Latency: time.Since(lastChunkTime).Milliseconds(),
11431152
}
11441153
lastChunkTime = time.Now()
11451154

core/providers/bedrock/chat.go

Lines changed: 0 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -43,10 +43,6 @@ func ToBedrockChatCompletionRequest(ctx *schemas.BifrostContext, bifrostReq *sch
4343
// Ensure tool config is present when needed
4444
ensureChatToolConfigForConversation(bifrostReq, bedrockReq)
4545

46-
if bifrostReq.Params != nil {
47-
bedrockReq.ExtraParams = bifrostReq.Params.ExtraParams
48-
}
49-
5046
return bedrockReq, nil
5147
}
5248

core/providers/bedrock/utils.go

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -207,18 +207,15 @@ func convertChatParameters(ctx *schemas.BifrostContext, bifrostReq *schemas.Bifr
207207
config := &BedrockGuardrailConfig{}
208208

209209
if identifier, ok := gc["guardrailIdentifier"].(string); ok {
210-
delete(gc, "guardrailIdentifier")
211210
config.GuardrailIdentifier = identifier
212211
}
213212
if version, ok := gc["guardrailVersion"].(string); ok {
214-
delete(gc, "guardrailVersion")
215213
config.GuardrailVersion = version
216214
}
217215
if trace, ok := gc["trace"].(string); ok {
218-
delete(gc, "trace")
219216
config.Trace = &trace
220217
}
221-
bedrockReq.ExtraParams["guardrailConfig"] = gc
218+
delete(bedrockReq.ExtraParams, "guardrailConfig")
222219
bedrockReq.GuardrailConfig = config
223220
}
224221
}
@@ -253,13 +250,11 @@ func convertChatParameters(ctx *schemas.BifrostContext, bifrostReq *schemas.Bifr
253250
// Handle performance configuration
254251
if perfConfig, exists := bifrostReq.Params.ExtraParams["performanceConfig"]; exists {
255252
if pc, ok := perfConfig.(map[string]interface{}); ok {
256-
257253
config := &BedrockPerformanceConfig{}
258254
if latency, ok := pc["latency"].(string); ok {
259-
delete(pc, "latency")
260255
config.Latency = &latency
261256
}
262-
bedrockReq.ExtraParams["performanceConfig"] = pc
257+
delete(bedrockReq.ExtraParams, "performanceConfig")
263258
bedrockReq.PerformanceConfig = config
264259
}
265260
}
@@ -292,6 +287,10 @@ func convertChatParameters(ctx *schemas.BifrostContext, bifrostReq *schemas.Bifr
292287
}
293288
}
294289
}
290+
// Set ExtraParams to nil if all keys were extracted to dedicated fields
291+
if len(bedrockReq.ExtraParams) == 0 {
292+
bedrockReq.ExtraParams = nil
293+
}
295294
}
296295
return nil
297296
}

0 commit comments

Comments
 (0)