Silence annoying OpenAI client shutdown error (#4157)
This commit is contained in:
committed by
GitHub
parent
7100b7e004
commit
4ac82ec25b
@@ -9,6 +9,7 @@ from openai import AsyncAzureOpenAI, AsyncOpenAI
|
||||
from skyvern.config import Settings
|
||||
from skyvern.forge.agent import ForgeAgent
|
||||
from skyvern.forge.agent_functions import AgentFunction
|
||||
from skyvern.forge.forge_openai_client import ForgeAsyncHttpxClientWrapper
|
||||
from skyvern.forge.sdk.api.azure import AzureClientFactory
|
||||
from skyvern.forge.sdk.api.llm.api_handler_factory import LLMAPIHandlerFactory
|
||||
from skyvern.forge.sdk.api.llm.models import LLMAPIHandler
|
||||
@@ -95,7 +96,10 @@ def create_forge_app() -> ForgeApp:
|
||||
app.EXPERIMENTATION_PROVIDER = NoOpExperimentationProvider()
|
||||
|
||||
app.LLM_API_HANDLER = LLMAPIHandlerFactory.get_llm_api_handler(settings.LLM_KEY)
|
||||
app.OPENAI_CLIENT = AsyncOpenAI(api_key=settings.OPENAI_API_KEY or "")
|
||||
app.OPENAI_CLIENT = AsyncOpenAI(
|
||||
api_key=settings.OPENAI_API_KEY or "",
|
||||
http_client=ForgeAsyncHttpxClientWrapper(),
|
||||
)
|
||||
if settings.ENABLE_AZURE_CUA:
|
||||
app.OPENAI_CLIENT = AsyncAzureOpenAI(
|
||||
api_key=settings.AZURE_CUA_API_KEY,
|
||||
@@ -113,6 +117,7 @@ def create_forge_app() -> ForgeApp:
|
||||
app.UI_TARS_CLIENT = AsyncOpenAI(
|
||||
api_key=settings.VOLCENGINE_API_KEY,
|
||||
base_url=settings.VOLCENGINE_API_BASE,
|
||||
http_client=ForgeAsyncHttpxClientWrapper(),
|
||||
)
|
||||
|
||||
app.SECONDARY_LLM_API_HANDLER = LLMAPIHandlerFactory.get_llm_api_handler(
|
||||
|
||||
24
skyvern/forge/forge_openai_client.py
Normal file
24
skyvern/forge/forge_openai_client.py
Normal file
@@ -0,0 +1,24 @@
|
||||
import asyncio
|
||||
|
||||
from openai import DefaultAsyncHttpxClient
|
||||
|
||||
|
||||
class ForgeAsyncHttpxClientWrapper(DefaultAsyncHttpxClient):
|
||||
"""
|
||||
Wrapper around OpenAI's AsyncHttpxClientWrapper to mask teardown races.
|
||||
|
||||
The upstream `__del__` checks `self.is_closed`, but during interpreter
|
||||
shutdown httpx internals may already be None, which raises:
|
||||
|
||||
AttributeError: 'NoneType' object has no attribute 'CLOSED'
|
||||
|
||||
We defensively swallow that destructor error so shutdown logs stay clean.
|
||||
"""
|
||||
|
||||
def __del__(self) -> None:
|
||||
try:
|
||||
if self.is_closed:
|
||||
return
|
||||
asyncio.get_running_loop().create_task(self.aclose())
|
||||
except Exception:
|
||||
pass
|
||||
@@ -18,6 +18,7 @@ from pydantic import BaseModel
|
||||
from skyvern.config import settings
|
||||
from skyvern.exceptions import SkyvernContextWindowExceededError
|
||||
from skyvern.forge import app
|
||||
from skyvern.forge.forge_openai_client import ForgeAsyncHttpxClientWrapper
|
||||
from skyvern.forge.sdk.api.llm.config_registry import LLMConfigRegistry
|
||||
from skyvern.forge.sdk.api.llm.exceptions import (
|
||||
DuplicateCustomLLMProviderError,
|
||||
@@ -1100,7 +1101,11 @@ class LLMCaller:
|
||||
self.openai_client = None
|
||||
if self.llm_key.startswith("openrouter/"):
|
||||
self.llm_key = self.llm_key.replace("openrouter/", "")
|
||||
self.openai_client = AsyncOpenAI(api_key=settings.OPENROUTER_API_KEY, base_url=settings.OPENROUTER_API_BASE)
|
||||
self.openai_client = AsyncOpenAI(
|
||||
api_key=settings.OPENROUTER_API_KEY,
|
||||
base_url=settings.OPENROUTER_API_BASE,
|
||||
http_client=ForgeAsyncHttpxClientWrapper(),
|
||||
)
|
||||
|
||||
def add_tool_result(self, tool_result: dict[str, Any]) -> None:
|
||||
self.current_tool_results.append(tool_result)
|
||||
@@ -1513,7 +1518,8 @@ class LLMCaller:
|
||||
if isinstance(response, UITarsResponse):
|
||||
ui_tars_usage = response.usage
|
||||
return LLMCallStats(
|
||||
llm_cost=0, # TODO: calculate the cost according to the price: https://www.volcengine.com/docs/82379/1544106
|
||||
llm_cost=0,
|
||||
# TODO: calculate the cost according to the price: https://www.volcengine.com/docs/82379/1544106
|
||||
input_tokens=ui_tars_usage.get("prompt_tokens", 0),
|
||||
output_tokens=ui_tars_usage.get("completion_tokens", 0),
|
||||
cached_tokens=0, # only part of model support cached tokens
|
||||
|
||||
Reference in New Issue
Block a user