Repository: livekit/agents
File: livekit-plugins/livekit-plugins-openai/livekit/plugins/openai/responses/llm.py (Python)

Code before:
            self._client = client or openai.AsyncClient(
                api_key=api_key if is_given(api_key) else None,
                base_url=base_url if is_given(base_url) else None,
                max_retries=0,
                http_client=httpx.AsyncClient(
                    timeout=timeout
                    if timeout
                    else httpx.Timeout(connect=15.0, read=5.0, write=5.0, pool=5.0),
                    follow_redirects=True,
                    limits=httpx.Limits(
                        max_connections=50,
                        max_keepalive_connections=50,
                        keepalive_expiry=120,
                    ),
                ),
            )

    async def aclose(self) -> None:
        if self._ws:
            await self._ws.aclose()
        if self._owns_client and self._client:
            await self._client.close()

    async def _ensure_ws(self) -> _ResponsesWebsocket:
        async with self._ws_lock:
            if self._ws is not None:
                dead = self._ws._run_task is not None and self._ws._run_task.done()
                if self._ws._ws_conn is None or dead:
                    if dead and self._ws._ws_conn is not None:
                        await self._ws._ws_conn.close()
                        self._ws._ws_conn = None
                    await self._ws.connect()
        return self._ws  # type: ignore

    @property
    def model(self) -> str:
        return self._opts.model

    def chat(
        self,
        *,
        chat_ctx: ChatContext,
        tools: list[Tool] | None = None,
        conn_options: APIConnectOptions = DEFAULT_API_CONNECT_OPTIONS,
        parallel_tool_calls: NotGivenOr[bool] = NOT_GIVEN,
        tool_choice: NotGivenOr[ToolChoice] = NOT_GIVEN,
        extra_kwargs: NotGivenOr[dict[str, Any]] = NOT_GIVEN,
    ) -> LLMStream:
        extra = {}

        if is_given(extra_kwargs):

Review comment (suggestion):
`self._ws` is not None if it's using websocket and this method is only called in websocket mode, maybe raise an error when `self._ws` is None and remove the type ignore.

Code after:
            self._client = client or openai.AsyncClient(
                api_key=api_key if is_given(api_key) else None,
                base_url=base_url if is_given(base_url) else None,
                max_retries=0,
                http_client=httpx.AsyncClient(
                    timeout=timeout
                    if timeout
                    else httpx.Timeout(connect=15.0, read=5.0, write=5.0, pool=5.0),
                    follow_redirects=True,
                    limits=httpx.Limits(
                        max_connections=50,
                        max_keepalive_connections=50,
                        keepalive_expiry=120,
                    ),
                ),
            )

    async def aclose(self) -> None:
        if self._ws:
            await self._ws.aclose()
        if self._owns_client and self._client:
            await self._client.close()

    async def _ensure_ws(self) -> _ResponsesWebsocket:
        if self._ws is None:
            raise RuntimeError("_ensure_ws called but self._ws is None")
        async with self._ws_lock:
            dead = self._ws._run_task is not None and self._ws._run_task.done()
            if self._ws._ws_conn is None or dead:
                if dead and self._ws._ws_conn is not None:
                    await self._ws._ws_conn.close()
                    self._ws._ws_conn = None
                await self._ws.connect()
        return self._ws

    @property
    def model(self) -> str:
        return self._opts.model

    def chat(
        self,
        *,
        chat_ctx: ChatContext,
        tools: list[Tool] | None = None,
        conn_options: APIConnectOptions = DEFAULT_API_CONNECT_OPTIONS,
        parallel_tool_calls: NotGivenOr[bool] = NOT_GIVEN,
        tool_choice: NotGivenOr[ToolChoice] = NOT_GIVEN,
        extra_kwargs: NotGivenOr[dict[str, Any]] = NOT_GIVEN,
    ) -> LLMStream:
        extra = {}