mirror of
https://github.com/QwenLM/qwen-code.git
synced 2025-12-20 16:57:46 +00:00
fix: relax chunk validation to avoid unnecessary retry
This commit is contained in:
@@ -50,9 +50,13 @@ const INVALID_CONTENT_RETRY_OPTIONS: ContentRetryOptions = {
|
||||
};
|
||||
/**
|
||||
* Returns true if the response is valid, false otherwise.
|
||||
*
|
||||
* The DashScope provider may return the last 2 chunks as:
|
||||
* 1. A choice(candidate) with finishReason and empty content
|
||||
* 2. Empty choices with usage metadata
|
||||
* We'll check separately for both of these cases.
|
||||
*/
|
||||
function isValidResponse(response: GenerateContentResponse): boolean {
|
||||
// The Dashscope provider returns empty content with usage metadata at the end of the stream
|
||||
if (response.usageMetadata) {
|
||||
return true;
|
||||
}
|
||||
@@ -61,6 +65,10 @@ function isValidResponse(response: GenerateContentResponse): boolean {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (response.candidates.some((candidate) => candidate.finishReason)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const content = response.candidates[0]?.content;
|
||||
return content !== undefined && isValidContent(content);
|
||||
}
|
||||
|
||||
@@ -18,6 +18,7 @@ import {
|
||||
ContentListUnion,
|
||||
ContentUnion,
|
||||
PartUnion,
|
||||
Candidate,
|
||||
} from '@google/genai';
|
||||
import OpenAI from 'openai';
|
||||
import { safeJsonParse } from '../../utils/safeJsonParse.js';
|
||||
@@ -652,19 +653,21 @@ export class OpenAIContentConverter {
|
||||
this.streamingToolCallParser.reset();
|
||||
}
|
||||
|
||||
response.candidates = [
|
||||
{
|
||||
content: {
|
||||
parts,
|
||||
role: 'model' as const,
|
||||
},
|
||||
finishReason: choice.finish_reason
|
||||
? this.mapOpenAIFinishReasonToGemini(choice.finish_reason)
|
||||
: FinishReason.FINISH_REASON_UNSPECIFIED,
|
||||
index: 0,
|
||||
safetyRatings: [],
|
||||
// Only include finishReason key if finish_reason is present
|
||||
const candidate: Candidate = {
|
||||
content: {
|
||||
parts,
|
||||
role: 'model' as const,
|
||||
},
|
||||
];
|
||||
index: 0,
|
||||
safetyRatings: [],
|
||||
};
|
||||
if (choice.finish_reason) {
|
||||
candidate.finishReason = this.mapOpenAIFinishReasonToGemini(
|
||||
choice.finish_reason,
|
||||
);
|
||||
}
|
||||
response.candidates = [candidate];
|
||||
} else {
|
||||
response.candidates = [];
|
||||
}
|
||||
|
||||
@@ -119,6 +119,7 @@ export class ContentGenerationPipeline {
|
||||
// Stage 2b: Filter empty responses to avoid downstream issues
|
||||
if (
|
||||
response.candidates?.[0]?.content?.parts?.length === 0 &&
|
||||
!response.candidates?.[0]?.finishReason &&
|
||||
!response.usageMetadata
|
||||
) {
|
||||
continue;
|
||||
|
||||
Reference in New Issue
Block a user