Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
41 commits
Select commit Hold shift + click to select a range
9abc918
docs: clarify local shell approval scope across handoffs (#5385)
seratch Oct 17, 2026
970db99
fix: raise MCP minimum to 1.21.2 for Pydantic and OAuth compatibility…
td-oai Oct 19, 2026
12ce34d
feat(sandbox): remove Runloop provider (#5369)
td-oai Oct 19, 2026
64cd5df
docs(sandbox): remove Runloop provider guidance (#5370)
td-oai Oct 19, 2026
841dfdd
[sandbox-hardening] Avoid loading startup files during workspace oper…
dhavalkapil-oai Oct 22, 2026
97c8288
fix(deps): bump mcp from 2.0.0 to 2.2.0 (#5393)
dependabot[bot] Oct 22, 2026
452c5bd
fix(deps): update twilio requirement from <10,>=9.11.2 to >=9.12.0,<1…
dependabot[bot] Oct 22, 2026
0e54e4b
fix(deps): update openai requirement from <4,>=3.26.0 to >=3.29.0,<4 …
dependabot[bot] Oct 22, 2026
6bfa5ff
fix(deps): update fastapi requirement from >=0.142.2 to >=0.143.0 in …
dependabot[bot] Oct 22, 2026
442d0ea
fix(deps-dev): bump aiohttp from 3.14.3 to 3.14.5 (#5403)
dependabot[bot] Oct 22, 2026
e2de6a8
fix(deps): bump mcp from 2.0.0 to 2.3.0 (#5404)
dependabot[bot] Oct 22, 2026
0dc4cf1
fix(deps-dev): bump playwright from 1.50.0 to 1.63.0 (#5402)
dependabot[bot] Oct 22, 2026
e00ea5c
docs(mcp): clarify timeouts and constructor options (#5417)
jbeckwith-oai Oct 26, 2026
963d032
fix: preserve empty structured shell results (#5423)
jbeckwith-oai Oct 26, 2026
455ce7c
docs: clarify approved tool recovery after a crash (#5424)
jbeckwith-oai Oct 26, 2026
275108a
docs: clarify streaming consumer ownership and cleanup (#5422)
jbeckwith-oai Oct 26, 2026
dda19f9
perf: avoid repeatedly fingerprinting completed tool calls (#5421)
jbeckwith-oai Oct 26, 2026
3396dca
fix: default GPT-6 Chat Completions tool requests to non-reasoning (#…
jbeckwith-oai Oct 26, 2026
a6ed84f
fix: add opt-in handoff error recovery (#5418)
jbeckwith-oai Oct 26, 2026
28c29bc
fix: replay ID-less assistant output in Chat Completions sessions (#5…
jbeckwith-oai Oct 26, 2026
addc737
fix(realtime): honor explicit interruption with automatic VAD (#5427)
jbeckwith-oai Oct 26, 2026
16fdb20
feat: expose utilities for third-party session adapters (#5428)
jbeckwith-oai Oct 26, 2026
9de261b
docs: Add external sandbox provider guide and runnable package (#5426)
jbeckwith-oai Oct 26, 2026
a88d291
fix: align implicit settings with provider-selected models (#5425)
jbeckwith-oai Oct 27, 2026
b235388
fix: require patched MCP dependency versions (#5431)
seratch Oct 27, 2026
b040da5
fix: preserve nested handoff record boundaries (#5430)
seratch Oct 27, 2026
bc4c6e1
fix: preserve Pydantic run context snapshots (#5444)
jbeckwith-oai Oct 27, 2026
5bb6fb7
fix(deps-dev): bump ruff from 0.16.8 to 0.17.1 (#5439)
dependabot[bot] Oct 27, 2026
56df6b4
fix(deps): update fastapi requirement from >=0.143.0 to >=0.150.0 in …
dependabot[bot] Oct 27, 2026
2350082
fix(deps): update openai requirement from <4,>=3.29.0 to >=3.35.1,<4 …
dependabot[bot] Oct 27, 2026
0c55458
fix(deps): bump httpx2 from 2.12.0 to 2.14.0 (#5438)
dependabot[bot] Oct 27, 2026
2964f77
fix(deps): bump opentelemetry-api from 1.40.0 to 1.45.1 (#5410)
dependabot[bot] Oct 27, 2026
26c762a
fix(deps): update starlette requirement from >=1.7.0 to >=1.9.0 in /e…
dependabot[bot] Oct 27, 2026
a91f0bf
fix(deps): update httpx2 requirement from >=2.13.1 to >=2.15.1 in /ex…
dependabot[bot] Oct 27, 2026
6295010
fix(deps): require certifi 2026.10.19 or later (#5429)
dependabot[bot] Oct 27, 2026
4134643
fix(deps): update httpx2 requirement from >=2.13.1 to >=2.15.1 in /ex…
dependabot[bot] Oct 27, 2026
b6966fa
fix(deps): update starlette requirement from >=1.7.0 to >=1.9.0 in /e…
dependabot[bot] Oct 27, 2026
57027de
fix(deps): require pymongo 4.18.3 or later (#5445)
dependabot[bot] Oct 27, 2026
cd26bbb
fix: stop native tool queues during function failure cleanup (#5446)
jbeckwith-oai Oct 27, 2026
e355d69
fix: improve missing stream completion diagnostics (#5457)
jbeckwith-oai Oct 30, 2026
19b1df3
docs: list Databricks as a community-maintained sandbox provider
HsingTang Nov 2, 2026
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions .github/scripts/run_examples.sh
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ set -euo pipefail
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/../.." && pwd)"
PID_FILE="$ROOT/.tmp/examples-auto-run.pid"
LOG_DIR="$ROOT/.tmp/examples-start-logs"
DEFAULT_UV_EXTRAS="litellm any-llm sqlalchemy redis blaxel modal runloop temporal"
DEFAULT_UV_EXTRAS="litellm any-llm sqlalchemy redis blaxel modal temporal"

build_uv_prefix() {
UV_RUN=(uv run)
Expand Down Expand Up @@ -169,7 +169,7 @@ Commands:
Environment overrides:
EXAMPLES_INTERACTIVE_MODE (default auto)
EXAMPLES_INCLUDE_SERVER/INTERACTIVE/AUDIO/EXTERNAL (defaults: 0/1/0/0)
EXAMPLES_UV_EXTRAS (default: litellm any-llm sqlalchemy redis blaxel modal runloop temporal; set empty to disable)
EXAMPLES_UV_EXTRAS (default: litellm any-llm sqlalchemy redis blaxel modal temporal; set empty to disable)
APPLY_PATCH_AUTO_APPROVE, AUTO_APPROVE_MCP (default 1 in auto mode)
EOF
}
Expand Down
3 changes: 2 additions & 1 deletion .github/scripts/run_integration_tests.py
Original file line number Diff line number Diff line change
Expand Up @@ -486,7 +486,8 @@ def main() -> None:
print(f"[integration] wheel={wheel.name} sdist={sdist.name} profile={args.profile}")

if args.profile == "mcp-v1":
for mcp_version in ("1.19.0", "1.29.0"):
# MCP 1.30.0 is the patched v1 floor for GHSA-rwrf-2pqf-9j8j.
for mcp_version in ("1.30.0",):
environment_kind = f"mcp-v1-{mcp_version}"
python = create_environment(
environment_kind,
Expand Down
3 changes: 2 additions & 1 deletion .github/workflows/tests.yml
Original file line number Diff line number Diff line change
Expand Up @@ -118,7 +118,8 @@ jobs:

tests:
runs-on: ubuntu-latest
timeout-minutes: 10
# Python 3.14 also runs coverage and installs Chromium with system dependencies.
timeout-minutes: ${{ matrix.python-version == '3.14' && 30 || 10 }}
strategy:
fail-fast: false
matrix:
Expand Down
26 changes: 22 additions & 4 deletions docs/human_in_the_loop.md
Original file line number Diff line number Diff line change
Expand Up @@ -49,12 +49,22 @@ For `ComputerTool`, use `on_safety_check` to accept or reject safety checks retu
## How the approval flow works

1. When the model emits a tool call, the runner evaluates its approval rule (`needs_approval`, `require_approval`, or the hosted MCP equivalent).
2. If an approval decision for that tool call is already stored in the [`RunContextWrapper`][agents.run_context.RunContextWrapper], the runner proceeds without prompting. Per-call approvals are scoped to the specific call ID; pass `always_approve=True` or `always_reject=True` to persist the same decision for future calls to the same tool identity during the rest of the run.
2. If an approval decision for that tool call is already stored in the [`RunContextWrapper`][agents.run_context.RunContextWrapper], the runner proceeds without prompting. Per-call approvals are scoped to the specific call ID; pass `always_approve=True` or `always_reject=True` to persist the same decision for future calls to the same tool identity.
3. If the approval rule requires approval and no decision for that tool call is stored, execution pauses, and `RunResult.interruptions` (or `RunResultStreaming.interruptions`) contains [`ToolApprovalItem`][agents.items.ToolApprovalItem] entries with details such as `agent.name`, `tool_name`, and `arguments`. This includes approvals raised after a handoff or inside nested `Agent.as_tool()` executions.
4. Convert the result to a `RunState` with `result.to_state()`, call `state.approve(...)` or `state.reject(...)`, and then resume with `Runner.run(agent, state)` or `Runner.run_streamed(agent, state)`, where `agent` is the original top-level agent for the run.
5. The resumed run continues where it left off and will re-enter this flow if new approvals are needed.

Sticky decisions created with `always_approve=True` or `always_reject=True` are stored in the run state, so they survive `state.to_string()` / `RunState.from_string(...)` and `state.to_json()` / `RunState.from_json(...)` when you resume the same paused run later.
Sticky decisions created with `always_approve=True` or `always_reject=True` remain active while the approval-bearing `RunContextWrapper` is reused, including across separate `Runner.run(...)` or `Runner.run_streamed(...)` calls. Passing a plain application context object to a new run creates a fresh wrapper; reusing that object alone does not carry approvals forward. `RunState` also stores sticky decisions, so they survive `state.to_string()` / `RunState.from_string(...)` and `state.to_json()` / `RunState.from_json(...)` when you resume the paused run later.

For function tools, sticky decisions are scoped to the agent that requested approval. A different agent's function tool does not inherit a decision merely because the tool has the same name.

!!! warning "Persistent shell and file-edit decisions are not agent-scoped"

For local [`ShellTool`][agents.tool.ShellTool] and [`ApplyPatchTool`][agents.tool.ApplyPatchTool], sticky decisions match the tool type and name, not the owning agent, executor, or editor. When agents share approval state, an `always_approve=True` decision can apply to another agent's tool of the same type and name after a handoff, even when the executors or editors have different permissions. The default names are `shell` and `apply_patch`, respectively. The SDK does not prompt again or re-evaluate the destination tool's `needs_approval` policy or `on_approval` callback when that sticky approval applies. `always_reject=True` decisions are shared in the same way.

When executors or editors have different permissions, use per-call decisions: call `state.approve(interruption)` or `state.reject(interruption)`, leaving `always_approve` and `always_reject` at their default `False` values. To require a human decision for every new shell or file-edit call, also set `needs_approval=True` and omit `on_approval`. A per-call decision does not clear an existing sticky decision.

When starting a new run with different execution permissions, use a fresh `RunContextWrapper` rather than reusing a wrapper that holds approvals. Resuming an existing `RunState` preserves its approvals, even if you pass a new context object or wrapper; a context override does not reset approval state.

For approval requests from [`HostedMCPTool`][agents.tool.HostedMCPTool], the Agents SDK identifies a sticky tool decision by the combination of `server_label` and tool name. An always-approve decision for `lookup_account` on one hosted MCP server does not approve a tool with the same name on another server. The Agents SDK persists an always-approve or always-reject decision only when the hosted MCP approval request includes both non-empty identity fields.

Expand Down Expand Up @@ -182,10 +192,10 @@ To use streaming in a run that may pause for approvals, call `Runner.run_streame
- **Streaming approvals**: `examples/agent_patterns/human_in_the_loop_stream.py` shows how to drain `stream_events()` and then approve pending tool calls before resuming with `Runner.run_streamed(agent, state)`.
- **Custom rejection text**: `examples/agent_patterns/human_in_the_loop_custom_rejection.py` shows how to combine run-level `tool_error_formatter` with per-call `rejection_message` overrides when approvals are rejected.
- **Agent as tool approvals**: `Agent.as_tool(..., needs_approval=...)` applies the same interruption flow when delegated agent tasks need review. Nested interruptions still surface on the outer run, so resume the original top-level agent rather than the nested one.
- **Local shell and apply_patch tools**: `ShellTool` and `ApplyPatchTool` also support `needs_approval`. Use `state.approve(interruption, always_approve=True)` or `state.reject(..., always_reject=True)` to cache the decision for future calls to that tool during the rest of the run. To resolve approval inside a callback, provide `on_approval`; `examples/tools/shell.py` demonstrates an interactive callback that prompts the operator by default. For an automatic policy that rejects every shell call, set `needs_approval=True` and `on_approval=lambda _context, _item: {"approve": False, "reason": "Disabled by policy"}` on `ShellTool`. To let the application review a paused run instead, handle interruptions (see `examples/tools/shell_human_in_the_loop.py`). Hosted shell environments do not support `needs_approval` or `on_approval`; see the [tools guide](tools.md).
- **Local shell and apply_patch tools**: `ShellTool` and `ApplyPatchTool` also support `needs_approval`. Use `state.approve(interruption)` or `state.reject(interruption)` for per-call decisions. The `always_approve=True` and `always_reject=True` options persist decisions in the `RunContextWrapper` and `RunState`; review the [approval scope warning](#how-the-approval-flow-works) before using these options. To resolve approval inside a callback, provide `on_approval`; `examples/tools/shell.py` demonstrates an interactive callback that prompts the operator by default. To automatically reject shell calls that have no existing approval decision, set `needs_approval=True` and `on_approval=lambda _context, _item: {"approve": False, "reason": "Disabled by policy"}` on `ShellTool`. To let the application review a paused run instead, handle interruptions (see `examples/tools/shell_human_in_the_loop.py`). Hosted shell environments do not support `needs_approval` or `on_approval`; see the [tools guide](tools.md).
- **Local MCP servers**: Use `require_approval` on `MCPServerStdio` / `MCPServerSse` / `MCPServerStreamableHttp` to gate MCP tool calls (see `examples/mcp/get_all_mcp_tools_example/main.py` and `examples/mcp/tool_filter_example/main.py`).
- **Hosted MCP servers**: Set `tool_config={"require_approval": "always"}` on `HostedMCPTool` to force HITL, optionally providing `on_approval_request` to auto-approve or reject (see `examples/hosted_mcp/human_in_the_loop.py` and `examples/hosted_mcp/on_approval.py`). Use `"never"` for trusted servers (`examples/hosted_mcp/simple.py`).
- **Sessions and memory**: Pass a session to `Runner.run` so approvals and conversation history survive multiple turns. SQLite and OpenAI Conversations session variants are in `examples/memory/memory_session_hitl_example.py` and `examples/memory/openai_session_hitl_example.py`.
- **Sessions and memory**: Pass a session to `Runner.run` to preserve conversation history across turns, and use `RunState` to preserve approval decisions when resuming a paused run. SQLite and OpenAI Conversations session variants are in `examples/memory/memory_session_hitl_example.py` and `examples/memory/openai_session_hitl_example.py`.
- **Realtime agents**: The realtime demo exposes WebSocket messages that approve or reject tool calls via `approve_tool_call` / `reject_tool_call` on the `RealtimeSession` (see `examples/realtime/app/server.py` for the server-side handlers and [Realtime guide](realtime/guide.md#tool-approvals) for the API surface).

## Long-running approvals
Expand All @@ -209,6 +219,14 @@ The [server-side approval example](https://github.com/openai/openai-agents-pytho

Replacing `context` with `context_override`, setting `strict_context=True`, or removing only the serialized approval records does not make an untrusted snapshot safe. Other fields still control resumed execution. If an application transports the complete snapshot through a client, the application must verify its integrity, bind it to the authorized user and run, and prevent replay before deserialization. Such verification does not encrypt the snapshot or hide its contents from the client.

### Recovering after a crash

Approval permits a tool call to execute; it does not guarantee exactly-once execution. If a tool performs an external action and the process stops before the application stores the updated run state, resuming from the older approved snapshot can execute the tool again. For example, a payment can complete even though the saved snapshot has no record of the payment result.

For tools with consequential side effects, the application should assign a stable idempotency key to each logical action and pass that key to a destination that atomically prevents duplicate effects. Reuse the same key and action parameters across retries, and respect the destination's key retention period and retry rules. An approval decision or a local completion flag alone cannot make the external action and the saved run state one atomic operation.

If destination-enforced idempotency is unavailable or no longer valid, reconcile the outcome with the destination before retrying. A missing result in an ordinary lookup is not proof that retrying is safe: reads can lag, and an earlier request can still complete. Retry only after authoritative reconciliation establishes that no earlier attempt performed the action or can still perform it. If the outcome remains uncertain, the application should record it as unknown and avoid automatic replay.

### Serialization options

Useful serialization options:
Expand Down
12 changes: 11 additions & 1 deletion docs/mcp.md
Original file line number Diff line number Diff line change
Expand Up @@ -250,13 +250,16 @@ asyncio.run(main())

The constructor accepts additional options:

- `client_session_timeout_seconds` controls MCP ClientSession read timeouts. Positive finite values representable by `datetime.timedelta` and at least one microsecond set a finite timeout; `None` and `0` disable it. Other values are rejected when the server is constructed.
- `client_session_timeout_seconds` controls MCP ClientSession read timeouts and defaults to `5` seconds on `MCPServerStdio`, `MCPServerSse`, and `MCPServerStreamableHttp`. Positive finite values representable by `datetime.timedelta` and at least one microsecond set a finite timeout; `None` and `0` disable it. Other values are rejected when the server is constructed.
- `use_structured_content` toggles whether `tool_result.structured_content` is preferred over textual output.
- `max_retry_attempts` and `retry_backoff_seconds_base` add automatic retries for `list_tools()` and `call_tool()`.
- `retry_backoff_seconds_max` caps the delay between retries in seconds; `None` (the default) leaves exponential backoff uncapped.
- `max_list_pages` limits successful pages per automatic `list_tools()` or `list_prompts()` call. `None` (the default) applies no page limit. With a positive integer limit, completion on the final permitted page succeeds; further continuation raises `UserError` without returning or caching a partial list.
- `tool_filter` lets you expose only a subset of tools (see [Tool filtering](#tool-filtering)).
- `require_approval` enables human-in-the-loop approval policies on local MCP tools.
- `failure_error_function` customizes model-visible MCP tool failure messages; set it to `None` to raise errors instead.
- `tool_meta_resolver` injects per-call MCP `_meta` payloads before `call_tool()`.
- `custom_data_extractor` receives `MCPToolCustomDataContext` and returns SDK-only custom data for emitted MCP tool output items.

### Approval policies for local MCP servers

Expand Down Expand Up @@ -366,6 +369,7 @@ async with MCPServerStdio(
"command": "npx",
"args": ["-y", "@modelcontextprotocol/server-filesystem", str(samples_dir)],
},
client_session_timeout_seconds=30,
) as server:
agent = Agent(
name="Assistant",
Expand All @@ -376,6 +380,12 @@ async with MCPServerStdio(
print(result.final_output)
```

!!! tip "Package runner cold starts"

Package runners such as `npx -y` and `uvx` may download packages before the MCP server starts. Install the package before connecting to avoid spending connection setup time on these downloads.

The example increases `client_session_timeout_seconds` to allow more time for initialization and subsequent session requests. With MCP Python SDK v1, this can also accommodate package downloads during initialization. With MCP Python SDK v2, the initial `server/discover` request has a separate timeout that this setting does not change. Preinstall the package for slow v2 cold starts; increasing the session timeout alone does not control every stage of connection setup.

## 5. MCP server manager

When you have multiple MCP servers, use `MCPServerManager` to connect them up front and expose the successfully connected subset of those servers to your agents. See the [MCPServerManager API reference](ref/mcp/manager.md) for constructor options and reconnect behavior.
Expand Down
3 changes: 0 additions & 3 deletions docs/ref/extensions/sandbox/runloop/mounts.md

This file was deleted.

3 changes: 0 additions & 3 deletions docs/ref/extensions/sandbox/runloop/sandbox.md

This file was deleted.

19 changes: 16 additions & 3 deletions docs/sandbox/clients.md
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,6 @@ For provider-specific setup notes and links for the checked-in extension example
| `DaytonaSandboxClient` | `openai-agents[daytona]` | [Daytona runner](https://github.com/openai/openai-agents-python/blob/main/examples/sandbox/extensions/daytona/daytona_runner.py) |
| `E2BSandboxClient` | `openai-agents[e2b]` | [E2B runner](https://github.com/openai/openai-agents-python/blob/main/examples/sandbox/extensions/e2b_runner.py) |
| `ModalSandboxClient` | `openai-agents[modal]` | [Modal runner](https://github.com/openai/openai-agents-python/blob/main/examples/sandbox/extensions/modal_runner.py) |
| `RunloopSandboxClient` | `openai-agents[runloop]` | [Runloop runner](https://github.com/openai/openai-agents-python/blob/main/examples/sandbox/extensions/runloop/runner.py) |
| `VercelSandboxClient` | `openai-agents[vercel]` | [Vercel runner](https://github.com/openai/openai-agents-python/blob/main/examples/sandbox/extensions/vercel_runner.py) |

</div>
Expand Down Expand Up @@ -182,7 +181,6 @@ Hosted sandbox clients expose provider-specific mount strategies. Choose the bac
| `BlaxelSandboxClient` | Supports cloud bucket mounts by pairing `BlaxelCloudBucketMountStrategy` with an `S3Mount`, `R2Mount`, or `GCSMount` entry. Also supports persistent Blaxel Drives with `BlaxelDriveMount` and `BlaxelDriveMountStrategy`, both available from `agents.extensions.sandbox.blaxel`. |
| `DaytonaSandboxClient` | Supports mounting cloud storage through `rclone` by using `DaytonaCloudBucketMountStrategy`; use it with `S3Mount`, `GCSMount`, `R2Mount`, `AzureBlobMount`, and `BoxMount`. |
| `E2BSandboxClient` | Supports mounting cloud storage through `rclone` by using `E2BCloudBucketMountStrategy`; use it with `S3Mount`, `GCSMount`, `R2Mount`, `AzureBlobMount`, and `BoxMount`. |
| `RunloopSandboxClient` | Supports mounting cloud storage through `rclone` by using `RunloopCloudBucketMountStrategy`; use it with `S3Mount`, `GCSMount`, `R2Mount`, `AzureBlobMount`, and `BoxMount`. |
| `VercelSandboxClient` | Supports create-time-only S3 and S3-compatible bucket mounts by pairing `VercelCloudBucketMountStrategy` with an `S3Mount` entry; mounted sessions cannot be resumed, and inline credentials require `allow_s3_credential_exposure=True`. |

</div>
Expand Down Expand Up @@ -217,9 +215,24 @@ The table below summarizes which remote storage entries each backend can mount d
| `BlaxelSandboxClient` | ✓ | ✓ | ✓ | - | - | - |
| `DaytonaSandboxClient` | ✓ | ✓ | ✓ | ✓ | ✓ | - |
| `E2BSandboxClient` | ✓ | ✓ | ✓ | ✓ | ✓ | - |
| `RunloopSandboxClient` | ✓ | ✓ | ✓ | ✓ | ✓ | - |
| `VercelSandboxClient` | ✓ | - | - | - | - | - |

</div>

For more runnable examples, browse [examples/sandbox/](https://github.com/openai/openai-agents-python/tree/main/examples/sandbox) for local, coding, memory, handoff, and agent-composition patterns, and [examples/sandbox/extensions/](https://github.com/openai/openai-agents-python/tree/main/examples/sandbox/extensions) for hosted sandbox clients.

## External providers

Applications can supply a sandbox client from a separately installed package through `SandboxRunConfig(client=...)`. See [Build a sandbox provider](custom-providers.md) for the authoring contract and a runnable external-package example.

### Community-maintained providers

These sandbox clients are maintained outside this repository and published as their own packages. Install the package, then pass the client to `SandboxRunConfig(client=...)`; the `SandboxAgent` definition stays the same.

<div class="sandbox-nowrap-first-column-table" markdown="1">

| Provider | Install | Client | Links |
| --- | --- | --- | --- |
| Databricks | `databricks-openai[sandbox]` | `DatabricksSandboxClient` | [PyPI](https://pypi.org/project/databricks-openai/) / [Source](https://github.com/databricks/databricks-ai-bridge/tree/main/integrations/openai) |

</div>
Loading
Loading