kaxil opened a new pull request, #74767: URL: https://github.com/apache/airflow/pull/74767
Teams that build agents with the [OpenAI Agents SDK](https://openai.github.io/openai-agents-python/) can now give them common.ai's connection-backed toolsets (`SQLToolset`, `HookToolset`, `ObjectStorageToolset`, sandboxes) without rewriting the agent for `AgentOperator`. It is the fourth adapter on the framework-neutral tool interface, next to Strands, Google ADK and the Anthropic tool runner, and keeps their guarantees: every result goes through Airflow's secret masker, a failure the model can correct comes back to it within the tool's retry limit, and anything else raises `ToolCallError` out of `Runner.run`, so the task fails and Airflow retries it. ```python agent = Agent(name="analyst", model=model, tools=AirflowTools(SQLToolset("warehouse"))) answer = Runner.run_sync(agent, question).final_output ``` The guide is `docs/frameworks/openai_agents.rst`, with a runnable example Dag. Everything ships experimental. First of four stacked PRs: the next ones add the CI job, OpenTelemetry tracing, and durable replay on retry. ## Design rationale **Why common.ai and not the OpenAI provider.** The adapter consumes common.ai's tool interface (`AirflowTool`, `ToolProvider`, the masker, the `common_ai.tool_calls` metric), and the OpenAI provider does not depend on common.ai. The SDK is also not tied to OpenAI's service: it runs other vendors' models through LiteLLM or any OpenAI-compatible endpoint, so it is an agent framework like Strands rather than an OpenAI API client. Operators for OpenAI's hosted APIs, such as `OpenAIAgentSessionOperator`, stay in the OpenAI provider. **`AirflowTools` is a `list[Tool]`.** The SDK has no toolset or plugin object; `Agent(tools=...)` takes a list. Subclassing `list[Tool]` keeps the class name the other adapters use and passes type checking as `Agent.tools` without a cast (a function returning `list[FunctionTool]` does not, since `list` is invariant). **A tool failure reaches the task as `ToolCallError`.** The runner wraps any exception a `FunctionTool` raises in `UserError("Error running tool ...")` unless it is one of the SDK's own types, so the adapter raises a private class that is both a `ToolCallError` and an `AgentsException`. `except ToolCallError` works in user code, and the task log shows the tool's error rather than a generic one. **`strict_json_schema=False`.** The SDK's strict mode marks every property required and rejects existing `additionalProperties` values, which would turn the toolsets' optional parameters into required ones. The schema goes to the model as the toolset wrote it. **Retry budget per run.** The SDK gives each run its own `Usage` object and passes it to every tool call, so the adapter keys the budget on that object's identity (`Usage` compares by value). It does not identify the model turn, so failures of calls that run at the same time count once, as in the ADK adapter. ## Gotchas - There is no `[openai-agents]` extra. `openai-agents` 0.21 and later require `openai>=3`, while the workspace holds `openai` below 3 through the root `override-dependencies`, so installing with Airflow's constraints gives 0.20. The adapter is tested on 0.20.0 (`openai` 2.x) and 0.23.1 (`openai` 3). - The SDK exports traces to OpenAI's backend by default, even for non-OpenAI models. The guide says so and shows how to turn it off; the tracing PR in this stack routes them to the task's OpenTelemetry trace instead. - An agent holding these tools that another agent calls through `Agent.as_tool()` needs `failure_error_function=None`, or the SDK hands the failure to the outer model as text. The guide and docstring say so, and a test covers it. - The adapter's tests skip without the SDK; the next PR in the stack runs them in the agent-framework CI job. --- * Read the **[Pull Request Guidelines](https://github.com/apache/airflow/blob/main/contributing-docs/05_pull_requests.rst#pull-request-guidelines)** for more information. Note: commit author/co-author name and email in commits become permanently public when merged. * For fundamental code changes, an Airflow Improvement Proposal ([AIP](https://cwiki.apache.org/confluence/display/AIRFLOW/Airflow+Improvement+Proposals)) is needed. * When adding dependency, check compliance with the [ASF 3rd Party License Policy](https://www.apache.org/legal/resolved.html#category-x). * For significant user-facing changes create newsfragment: `{pr_number}.significant.rst`, in [airflow-core/newsfragments](https://github.com/apache/airflow/tree/main/airflow-core/newsfragments). You can add this file in a follow-up commit after the PR is created so you know the PR number. -- This is an automated message from the Apache Git Service. To respond to the message, please log on to GitHub and use the URL above to go to the specific comment. To unsubscribe, e-mail: [email protected] For queries about this service, please contact Infrastructure at: [email protected]
