feat: capture streaming token usage in QwenClient and QwenVLClient
Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
This commit is contained in:
@@ -140,8 +140,14 @@ class QwenClient(BaseLLMClient):
|
||||
max_tokens: Optional[int] = None,
|
||||
temperature: Optional[float] = None,
|
||||
**kwargs
|
||||
) -> Generator[str, None, None]:
|
||||
"""Stream chat for the Qwen Client instance."""
|
||||
) -> Generator[str, None, Optional[Dict[str, int]]]:
|
||||
"""Stream chat for the Qwen Client instance.
|
||||
|
||||
Returns the trailing token-usage dict as the generator's return value
|
||||
(read via StopIteration.value when manually driven with next()) when
|
||||
the gateway sends one via stream_options.include_usage, else None.
|
||||
"""
|
||||
usage: Optional[Dict[str, int]] = None
|
||||
try:
|
||||
# Keep provider-specific behavior explicit so debugging stays straightforward.
|
||||
payload = {
|
||||
@@ -150,7 +156,8 @@ class QwenClient(BaseLLMClient):
|
||||
"max_tokens": max_tokens or self.config.max_tokens,
|
||||
"temperature": temperature or self.config.temperature,
|
||||
"top_p": kwargs.get("top_p", self.config.top_p),
|
||||
"stream": True # Keep provider-specific behavior explicit so debugging stays straightforward.
|
||||
"stream": True, # Keep provider-specific behavior explicit so debugging stays straightforward.
|
||||
"stream_options": {"include_usage": True}
|
||||
}
|
||||
|
||||
# Keep provider-specific behavior explicit so debugging stays straightforward.
|
||||
@@ -167,6 +174,9 @@ class QwenClient(BaseLLMClient):
|
||||
data = json.loads(data_str)
|
||||
choices = data.get("choices", [])
|
||||
if not choices:
|
||||
if data.get("usage"):
|
||||
# Trailing usage-only chunk — capture it, nothing to yield.
|
||||
usage = data["usage"]
|
||||
continue # Keep provider-specific behavior explicit so debugging stays straightforward.
|
||||
delta = choices[0].get("delta", {})
|
||||
content = delta.get("content", "")
|
||||
@@ -183,6 +193,8 @@ class QwenClient(BaseLLMClient):
|
||||
logger.error(f"Qwen流式调用失败: {e}")
|
||||
yield f"[ERROR: {str(e)}]"
|
||||
|
||||
return usage
|
||||
|
||||
async def async_stream_chat(
|
||||
self,
|
||||
messages: List[Dict[str, str]],
|
||||
@@ -299,8 +311,14 @@ class QwenVLClient(BaseLLMClient):
|
||||
max_tokens: Optional[int] = None,
|
||||
temperature: Optional[float] = None,
|
||||
**kwargs
|
||||
) -> Generator[str, None, None]:
|
||||
"""Stream chat for the Qwen V L Client instance."""
|
||||
) -> Generator[str, None, Optional[Dict[str, int]]]:
|
||||
"""Stream chat for the Qwen V L Client instance.
|
||||
|
||||
Returns the trailing token-usage dict as the generator's return value
|
||||
(read via StopIteration.value when manually driven with next()) when
|
||||
the gateway sends one via stream_options.include_usage, else None.
|
||||
"""
|
||||
usage: Optional[Dict[str, int]] = None
|
||||
try:
|
||||
payload = {
|
||||
"model": self.config.model,
|
||||
@@ -308,7 +326,8 @@ class QwenVLClient(BaseLLMClient):
|
||||
"max_tokens": max_tokens or self.config.max_tokens,
|
||||
"temperature": temperature or self.config.temperature,
|
||||
"top_p": kwargs.get("top_p", self.config.top_p),
|
||||
"stream": True
|
||||
"stream": True,
|
||||
"stream_options": {"include_usage": True}
|
||||
}
|
||||
|
||||
with self._client.stream("POST", "/chat/completions", json=payload) as response:
|
||||
@@ -323,6 +342,9 @@ class QwenVLClient(BaseLLMClient):
|
||||
data = json.loads(data_str)
|
||||
choices = data.get("choices", [])
|
||||
if not choices:
|
||||
if data.get("usage"):
|
||||
# Trailing usage-only chunk — capture it, nothing to yield.
|
||||
usage = data["usage"]
|
||||
continue # Keep provider-specific behavior explicit so debugging stays straightforward.
|
||||
delta = choices[0].get("delta", {})
|
||||
content = delta.get("content", "")
|
||||
@@ -335,6 +357,8 @@ class QwenVLClient(BaseLLMClient):
|
||||
logger.error(f"QwenVL流式调用失败: {e}")
|
||||
yield f"[ERROR: {str(e)}]"
|
||||
|
||||
return usage
|
||||
|
||||
def get_available_models(self) -> List[str]:
|
||||
"""Return available models for the Qwen V L Client instance."""
|
||||
return self.SUPPORTED_MODELS
|
||||
|
||||
Reference in New Issue
Block a user