Run the OpenAI Agents SDK loop for *question*. Args: question: Natural-language question to answer. Returns: AgentResult with the final answer and full execution trajectory.
(self, question: str)
| 203 | self._max_turns = max_turns |
| 204 | |
| 205 | async def run(self, question: str) -> AgentResult: |
| 206 | """Run the OpenAI Agents SDK loop for *question*. |
| 207 | |
| 208 | Args: |
| 209 | question: Natural-language question to answer. |
| 210 | |
| 211 | Returns: |
| 212 | AgentResult with the final answer and full execution trajectory. |
| 213 | """ |
| 214 | with agent_run_span( |
| 215 | "openai-agent", model=self._model_id, question=question |
| 216 | ) as span: |
| 217 | run_started = time.perf_counter() |
| 218 | started_at = _dt.datetime.now(_dt.UTC).isoformat() |
| 219 | mcp_servers = _build_mcp_servers(self._server_paths) |
| 220 | |
| 221 | # AsyncExitStack enters every server and closes them in LIFO order |
| 222 | # on exit (success or exception). |
| 223 | async with AsyncExitStack() as stack: |
| 224 | active_servers = [ |
| 225 | await stack.enter_async_context(s) for s in mcp_servers |
| 226 | ] |
| 227 | agent = Agent( |
| 228 | name="AssetOps Assistant", |
| 229 | instructions=AGENT_SYSTEM_PROMPT, |
| 230 | mcp_servers=active_servers, |
| 231 | model=self._model, |
| 232 | ) |
| 233 | |
| 234 | _log.info( |
| 235 | "OpenAIAgentRunner: starting query (model=%s, servers=%d)", |
| 236 | self._model, |
| 237 | len(active_servers), |
| 238 | ) |
| 239 | |
| 240 | run_kwargs: dict = dict(max_turns=self._max_turns) |
| 241 | if self._run_config is not None: |
| 242 | run_kwargs["run_config"] = self._run_config |
| 243 | |
| 244 | result = await Runner.run( |
| 245 | agent, |
| 246 | question, |
| 247 | **run_kwargs, |
| 248 | ) |
| 249 | |
| 250 | answer = result.final_output or "" |
| 251 | trajectory = _build_trajectory(result) |
| 252 | trajectory.started_at = started_at |
| 253 | |
| 254 | _log.info( |
| 255 | "OpenAIAgentRunner: done (turns=%d, input_tokens=%d, " |
| 256 | "output_tokens=%d)", |
| 257 | len(trajectory.turns), |
| 258 | trajectory.total_input_tokens, |
| 259 | trajectory.total_output_tokens, |
| 260 | ) |
| 261 | |
| 262 | span.set_attribute("agent.answer.length", len(answer)) |