mirror of
https://github.com/zhayujie/chatgpt-on-wechat.git
synced 2026-07-20 13:47:15 +08:00
refactor(openai): drop SDK dependency and switch to native HTTP client
This commit is contained in:
@@ -8,11 +8,11 @@ This includes: OpenAI, LinkAI, Azure OpenAI, and many third-party providers.
|
||||
"""
|
||||
|
||||
import json
|
||||
import openai
|
||||
import requests
|
||||
from typing import Optional
|
||||
from common.log import logger
|
||||
from agent.protocol.message_utils import drop_orphaned_tool_results_openai
|
||||
from models.openai.openai_http_client import OpenAIHTTPClient, OpenAIHTTPError
|
||||
|
||||
|
||||
class OpenAICompatibleBot:
|
||||
@@ -135,49 +135,87 @@ class OpenAICompatibleBot:
|
||||
"status_code": 500
|
||||
}
|
||||
|
||||
def _get_http_client(self) -> OpenAIHTTPClient:
|
||||
"""Build an HTTP client honoring the global proxy config.
|
||||
|
||||
Subclasses can override this for custom auth headers (e.g. Azure's
|
||||
``api-key`` header) by returning a pre-configured client.
|
||||
"""
|
||||
from config import conf
|
||||
proxy = conf().get("proxy") or None
|
||||
return OpenAIHTTPClient(proxy=proxy)
|
||||
|
||||
def _handle_sync_response(self, request_params, api_key, api_base):
|
||||
"""Handle synchronous OpenAI API response"""
|
||||
"""Handle synchronous chat-completion via HTTP."""
|
||||
params = dict(request_params)
|
||||
params.pop("stream", None)
|
||||
# Translate legacy SDK timeout kwarg to our HTTP client kwarg.
|
||||
timeout = params.pop("request_timeout", None) or params.pop("timeout", None)
|
||||
try:
|
||||
# Build kwargs with explicit API configuration
|
||||
kwargs = dict(request_params)
|
||||
if api_key:
|
||||
kwargs["api_key"] = api_key
|
||||
if api_base:
|
||||
kwargs["api_base"] = api_base
|
||||
|
||||
response = openai.ChatCompletion.create(**kwargs)
|
||||
return response
|
||||
|
||||
client = self._get_http_client()
|
||||
return client.chat_completions(
|
||||
api_key=api_key,
|
||||
api_base=api_base,
|
||||
timeout=timeout,
|
||||
stream=False,
|
||||
**params,
|
||||
)
|
||||
except OpenAIHTTPError as e:
|
||||
logger.error(
|
||||
f"[{self.__class__.__name__}] sync response error: "
|
||||
f"HTTP {e.status_code}: {e.message}"
|
||||
)
|
||||
return {
|
||||
"error": True,
|
||||
"message": e.message,
|
||||
"status_code": e.status_code or 500,
|
||||
}
|
||||
except Exception as e:
|
||||
logger.error(f"[{self.__class__.__name__}] sync response error: {e}")
|
||||
return {
|
||||
"error": True,
|
||||
"message": str(e),
|
||||
"status_code": 500
|
||||
"status_code": 500,
|
||||
}
|
||||
|
||||
|
||||
def _handle_stream_response(self, request_params, api_key, api_base):
|
||||
"""Handle streaming OpenAI API response"""
|
||||
"""Handle streaming chat-completion via HTTP (SSE).
|
||||
|
||||
Yields dict chunks in OpenAI's standard streaming shape:
|
||||
{"choices": [{"delta": {...}, "finish_reason": ...}], ...}
|
||||
On error, yields a single ``{"error": ..., "status_code": ...}`` chunk
|
||||
— the same contract :mod:`agent.protocol.agent_stream` already handles.
|
||||
"""
|
||||
params = dict(request_params)
|
||||
params.pop("stream", None)
|
||||
timeout = params.pop("request_timeout", None) or params.pop("timeout", None)
|
||||
try:
|
||||
# Build kwargs with explicit API configuration
|
||||
kwargs = dict(request_params)
|
||||
if api_key:
|
||||
kwargs["api_key"] = api_key
|
||||
if api_base:
|
||||
kwargs["api_base"] = api_base
|
||||
|
||||
stream = openai.ChatCompletion.create(**kwargs)
|
||||
|
||||
# Stream chunks to caller
|
||||
client = self._get_http_client()
|
||||
stream = client.chat_completions(
|
||||
api_key=api_key,
|
||||
api_base=api_base,
|
||||
timeout=timeout,
|
||||
stream=True,
|
||||
**params,
|
||||
)
|
||||
for chunk in stream:
|
||||
yield chunk
|
||||
|
||||
except OpenAIHTTPError as e:
|
||||
logger.error(
|
||||
f"[{self.__class__.__name__}] stream response error: "
|
||||
f"HTTP {e.status_code}: {e.message}"
|
||||
)
|
||||
yield {
|
||||
"error": True,
|
||||
"message": e.message,
|
||||
"status_code": e.status_code or 500,
|
||||
}
|
||||
except Exception as e:
|
||||
logger.error(f"[{self.__class__.__name__}] stream response error: {e}")
|
||||
yield {
|
||||
"error": True,
|
||||
"message": str(e),
|
||||
"status_code": 500
|
||||
"status_code": 500,
|
||||
}
|
||||
|
||||
def _convert_tools_to_openai_format(self, tools):
|
||||
|
||||
Reference in New Issue
Block a user