feature: 新增API调用日志统计,首字,总耗时,token消耗等

This commit is contained in:
xiamuceer
2026-03-18 12:35:13 +08:00
parent 4e3fb6766e
commit a6e6df5073
9 changed files with 491 additions and 69 deletions
@@ -58,10 +58,19 @@ class AnthropicClient:
elif block.type == "text":
content += block.text
usage = getattr(response, "usage", None)
return {
"content": content,
"tool_calls": tool_calls if tool_calls else None,
"finish_reason": response.stop_reason,
"usage": {
"prompt_tokens": getattr(usage, "input_tokens", None),
"completion_tokens": getattr(usage, "output_tokens", None),
"total_tokens": (
(getattr(usage, "input_tokens", 0) or 0) +
(getattr(usage, "output_tokens", 0) or 0)
) if usage else None,
},
}
async def chat_completion_stream(
@@ -98,10 +98,19 @@ class GeminiClient:
"function": {"name": fc["name"], "arguments": fc.get("args", {})}
})
usage = data.get("usageMetadata") or {}
prompt_tokens = usage.get("promptTokenCount")
completion_tokens = usage.get("candidatesTokenCount")
total_tokens = usage.get("totalTokenCount")
return {
"content": text,
"tool_calls": tool_calls if tool_calls else None,
"finish_reason": "tool_calls" if tool_calls else "stop"
"finish_reason": "tool_calls" if tool_calls else "stop",
"usage": {
"prompt_tokens": prompt_tokens,
"completion_tokens": completion_tokens,
"total_tokens": total_tokens,
}
}
async def chat_completion_stream(
@@ -148,6 +157,15 @@ class GeminiClient:
import json
try:
data = json.loads(line[6:])
usage = data.get("usageMetadata") or {}
if usage:
yield {
"usage": {
"prompt_tokens": usage.get("promptTokenCount"),
"completion_tokens": usage.get("candidatesTokenCount"),
"total_tokens": usage.get("totalTokenCount"),
}
}
candidates = data.get("candidates", [])
if candidates and len(candidates) > 0:
parts = candidates[0].get("content", {}).get("parts", [])
@@ -74,10 +74,16 @@ class OpenAIClient(BaseAIClient):
choice = choices[0]
message = choice.get("message", {})
usage = data.get("usage") or {}
return {
"content": message.get("content", ""),
"tool_calls": message.get("tool_calls"),
"finish_reason": choice.get("finish_reason"),
"usage": {
"prompt_tokens": usage.get("prompt_tokens"),
"completion_tokens": usage.get("completion_tokens"),
"total_tokens": usage.get("total_tokens"),
},
}
async def chat_completion_stream(
@@ -138,6 +144,16 @@ class OpenAIClient(BaseAIClient):
existing["function"].get("arguments", "") +
tc["function"]["arguments"]
)
usage = data.get("usage")
if usage:
yield {
"usage": {
"prompt_tokens": usage.get("prompt_tokens"),
"completion_tokens": usage.get("completion_tokens"),
"total_tokens": usage.get("total_tokens"),
}
}
if content:
yield {"content": content}