| 114 | self._client = OpenAI(api_key=api_key, base_url=base_url, timeout=timeout) |
| 115 | |
| 116 | def generate( |
| 117 | self, |
| 118 | prompt: str, |
| 119 | *, |
| 120 | system: Optional[str] = None, |
| 121 | temperature: float = 0.0, |
| 122 | max_tokens: int = 1024, |
| 123 | ) -> LLMResponse: |
| 124 | messages: list[dict[str, str]] = [] |
| 125 | if system: |
| 126 | messages.append({"role": "system", "content": system}) |
| 127 | messages.append({"role": "user", "content": prompt}) |
| 128 | |
| 129 | kwargs = { |
| 130 | "model": self.model, |
| 131 | "messages": messages, |
| 132 | "temperature": temperature, |
| 133 | "max_tokens": max_tokens, |
| 134 | } |
| 135 | efforts = _reasoning_effort_candidates() |
| 136 | response = None |
| 137 | last_reasoning_error: Optional[Exception] = None |
| 138 | for effort in efforts: |
| 139 | try: |
| 140 | response = self._client.chat.completions.create(**{**kwargs, "reasoning_effort": effort}) |
| 141 | break |
| 142 | except Exception as exc: |
| 143 | if not _is_unsupported_reasoning_error(exc): |
| 144 | raise |
| 145 | last_reasoning_error = exc |
| 146 | if response is None: |
| 147 | try: |
| 148 | response = self._client.chat.completions.create(**kwargs) |
| 149 | except Exception: |
| 150 | if last_reasoning_error is not None: |
| 151 | raise |
| 152 | raise |
| 153 | |
| 154 | choice = response.choices[0].message.content or "" |
| 155 | usage = getattr(response, "usage", None) |
| 156 | return LLMResponse( |
| 157 | text=choice, |
| 158 | model=self.model, |
| 159 | provider=self.name, |
| 160 | prompt_tokens=getattr(usage, "prompt_tokens", 0) or 0, |
| 161 | completion_tokens=getattr(usage, "completion_tokens", 0) or 0, |
| 162 | ) |
| 163 | |
| 164 | def stream_generate( |
| 165 | self, |