Metadata-Version: 2.4
Name: datarobot-genai
Version: 0.15.58
Summary: Generic helpers for GenAI
Author: DataRobot, Inc.
License: Apache-2.0
Project-URL: Homepage, https://github.com/datarobot-oss/datarobot-genai
Requires-Python: <3.14,>=3.11
Description-Content-Type: text/markdown
License-File: LICENSE
License-File: AUTHORS
Provides-Extra: core
Requires-Dist: requests<3.0.0,>=2.32.4; extra == "core"
Requires-Dist: datarobot<4.0.0,>=3.10.0; extra == "core"
Requires-Dist: datarobot-early-access==3.14.0.2026.3.18.162920; extra == "core"
Requires-Dist: datarobot-predict<2.0.0,>=1.13.2; extra == "core"
Requires-Dist: openai<3.0.0,>=2.0.0; extra == "core"
Requires-Dist: ragas<0.5.0,>=0.4.3; extra == "core"
Requires-Dist: pyjwt<3.0.0,>=2.12.0; extra == "core"
Requires-Dist: opentelemetry-instrumentation-requests<1.0.0,>=0.43b0; extra == "core"
Requires-Dist: opentelemetry-instrumentation-aiohttp-client<1.0.0,>=0.43b0; extra == "core"
Requires-Dist: opentelemetry-instrumentation-httpx<1.0.0,>=0.43b0; extra == "core"
Requires-Dist: opentelemetry-instrumentation-openai<1.0.0,>=0.40.5; extra == "core"
Requires-Dist: opentelemetry-instrumentation-threading<1.0.0,>=0.43b0; extra == "core"
Requires-Dist: datarobot-moderations[all]<12.0.0,>=11.2.29; extra == "core"
Requires-Dist: ag-ui-protocol==0.1.15; extra == "core"
Requires-Dist: pyarrow==21.0.0; extra == "core"
Requires-Dist: colorama<1.0.0,>=0.4.6; extra == "core"
Provides-Extra: crewai
Requires-Dist: requests<3.0.0,>=2.32.4; extra == "crewai"
Requires-Dist: datarobot<4.0.0,>=3.10.0; extra == "crewai"
Requires-Dist: datarobot-early-access==3.14.0.2026.3.18.162920; extra == "crewai"
Requires-Dist: datarobot-predict<2.0.0,>=1.13.2; extra == "crewai"
Requires-Dist: openai<3.0.0,>=2.0.0; extra == "crewai"
Requires-Dist: ragas<0.5.0,>=0.4.3; extra == "crewai"
Requires-Dist: pyjwt<3.0.0,>=2.12.0; extra == "crewai"
Requires-Dist: opentelemetry-instrumentation-requests<1.0.0,>=0.43b0; extra == "crewai"
Requires-Dist: opentelemetry-instrumentation-aiohttp-client<1.0.0,>=0.43b0; extra == "crewai"
Requires-Dist: opentelemetry-instrumentation-httpx<1.0.0,>=0.43b0; extra == "crewai"
Requires-Dist: opentelemetry-instrumentation-openai<1.0.0,>=0.40.5; extra == "crewai"
Requires-Dist: opentelemetry-instrumentation-threading<1.0.0,>=0.43b0; extra == "crewai"
Requires-Dist: datarobot-moderations[all]<12.0.0,>=11.2.29; extra == "crewai"
Requires-Dist: ag-ui-protocol==0.1.15; extra == "crewai"
Requires-Dist: pyarrow==21.0.0; extra == "crewai"
Requires-Dist: colorama<1.0.0,>=0.4.6; extra == "crewai"
Requires-Dist: anthropic<1.0.0,~=0.71.0; extra == "crewai"
Requires-Dist: azure-ai-inference<2.0.0,>=1.0.0b9; extra == "crewai"
Requires-Dist: crewai[litellm]>=1.11.0; extra == "crewai"
Requires-Dist: litellm<2.0.0,>=1.83.0; extra == "crewai"
Requires-Dist: crewai-tools[mcp]<0.77.0,>=0.69.0; extra == "crewai"
Requires-Dist: nvidia-nat-crewai==1.6.0; extra == "crewai"
Requires-Dist: opentelemetry-instrumentation-crewai<1.0.0,>=0.40.5; extra == "crewai"
Requires-Dist: pybase64<2.0.0,>=1.4.2; extra == "crewai"
Provides-Extra: langgraph
Requires-Dist: requests<3.0.0,>=2.32.4; extra == "langgraph"
Requires-Dist: datarobot<4.0.0,>=3.10.0; extra == "langgraph"
Requires-Dist: datarobot-early-access==3.14.0.2026.3.18.162920; extra == "langgraph"
Requires-Dist: datarobot-predict<2.0.0,>=1.13.2; extra == "langgraph"
Requires-Dist: openai<3.0.0,>=2.0.0; extra == "langgraph"
Requires-Dist: ragas<0.5.0,>=0.4.3; extra == "langgraph"
Requires-Dist: pyjwt<3.0.0,>=2.12.0; extra == "langgraph"
Requires-Dist: opentelemetry-instrumentation-requests<1.0.0,>=0.43b0; extra == "langgraph"
Requires-Dist: opentelemetry-instrumentation-aiohttp-client<1.0.0,>=0.43b0; extra == "langgraph"
Requires-Dist: opentelemetry-instrumentation-httpx<1.0.0,>=0.43b0; extra == "langgraph"
Requires-Dist: opentelemetry-instrumentation-openai<1.0.0,>=0.40.5; extra == "langgraph"
Requires-Dist: opentelemetry-instrumentation-threading<1.0.0,>=0.43b0; extra == "langgraph"
Requires-Dist: datarobot-moderations[all]<12.0.0,>=11.2.29; extra == "langgraph"
Requires-Dist: ag-ui-protocol==0.1.15; extra == "langgraph"
Requires-Dist: pyarrow==21.0.0; extra == "langgraph"
Requires-Dist: colorama<1.0.0,>=0.4.6; extra == "langgraph"
Requires-Dist: langchain-mcp-adapters<0.2.0,>=0.1.12; extra == "langgraph"
Requires-Dist: langgraph<2.0.0,>=1.0.0; extra == "langgraph"
Requires-Dist: langgraph-prebuilt<2.0.0,>=1.0.0; extra == "langgraph"
Requires-Dist: litellm<2.0.0,>=1.83.0; extra == "langgraph"
Requires-Dist: nvidia-nat-langchain==1.6.0; extra == "langgraph"
Requires-Dist: opentelemetry-instrumentation-langchain<1.0.0,>=0.40.5; extra == "langgraph"
Provides-Extra: llamaindex
Requires-Dist: requests<3.0.0,>=2.32.4; extra == "llamaindex"
Requires-Dist: datarobot<4.0.0,>=3.10.0; extra == "llamaindex"
Requires-Dist: datarobot-early-access==3.14.0.2026.3.18.162920; extra == "llamaindex"
Requires-Dist: datarobot-predict<2.0.0,>=1.13.2; extra == "llamaindex"
Requires-Dist: openai<3.0.0,>=2.0.0; extra == "llamaindex"
Requires-Dist: ragas<0.5.0,>=0.4.3; extra == "llamaindex"
Requires-Dist: pyjwt<3.0.0,>=2.12.0; extra == "llamaindex"
Requires-Dist: opentelemetry-instrumentation-requests<1.0.0,>=0.43b0; extra == "llamaindex"
Requires-Dist: opentelemetry-instrumentation-aiohttp-client<1.0.0,>=0.43b0; extra == "llamaindex"
Requires-Dist: opentelemetry-instrumentation-httpx<1.0.0,>=0.43b0; extra == "llamaindex"
Requires-Dist: opentelemetry-instrumentation-openai<1.0.0,>=0.40.5; extra == "llamaindex"
Requires-Dist: opentelemetry-instrumentation-threading<1.0.0,>=0.43b0; extra == "llamaindex"
Requires-Dist: datarobot-moderations[all]<12.0.0,>=11.2.29; extra == "llamaindex"
Requires-Dist: ag-ui-protocol==0.1.15; extra == "llamaindex"
Requires-Dist: pyarrow==21.0.0; extra == "llamaindex"
Requires-Dist: colorama<1.0.0,>=0.4.6; extra == "llamaindex"
Requires-Dist: llama-index<0.15.0,>=0.14.0; extra == "llamaindex"
Requires-Dist: llama-index-core<0.15.0,>=0.14.0; extra == "llamaindex"
Requires-Dist: llama-index-llms-langchain<1.0.0,>=0.8.0; extra == "llamaindex"
Requires-Dist: llama-index-llms-litellm<0.7.0,>=0.4.1; extra == "llamaindex"
Requires-Dist: litellm<2.0.0,>=1.83.0; extra == "llamaindex"
Requires-Dist: llama-index-llms-openai<0.7.0,>=0.6.0; extra == "llamaindex"
Requires-Dist: llama-index-tools-mcp<0.5.0,>=0.1.0; extra == "llamaindex"
Requires-Dist: nvidia-nat-llama-index==1.6.0; extra == "llamaindex"
Requires-Dist: opentelemetry-instrumentation-llamaindex<1.0.0,>=0.40.5; extra == "llamaindex"
Requires-Dist: pypdf<7.0.0,>=6.10.1; extra == "llamaindex"
Provides-Extra: nat
Requires-Dist: requests<3.0.0,>=2.32.4; extra == "nat"
Requires-Dist: datarobot<4.0.0,>=3.10.0; extra == "nat"
Requires-Dist: datarobot-early-access==3.14.0.2026.3.18.162920; extra == "nat"
Requires-Dist: datarobot-predict<2.0.0,>=1.13.2; extra == "nat"
Requires-Dist: openai<3.0.0,>=2.0.0; extra == "nat"
Requires-Dist: ragas<0.5.0,>=0.4.3; extra == "nat"
Requires-Dist: pyjwt<3.0.0,>=2.12.0; extra == "nat"
Requires-Dist: opentelemetry-instrumentation-requests<1.0.0,>=0.43b0; extra == "nat"
Requires-Dist: opentelemetry-instrumentation-aiohttp-client<1.0.0,>=0.43b0; extra == "nat"
Requires-Dist: opentelemetry-instrumentation-httpx<1.0.0,>=0.43b0; extra == "nat"
Requires-Dist: opentelemetry-instrumentation-openai<1.0.0,>=0.40.5; extra == "nat"
Requires-Dist: opentelemetry-instrumentation-threading<1.0.0,>=0.43b0; extra == "nat"
Requires-Dist: datarobot-moderations[all]<12.0.0,>=11.2.29; extra == "nat"
Requires-Dist: ag-ui-protocol==0.1.15; extra == "nat"
Requires-Dist: pyarrow==21.0.0; extra == "nat"
Requires-Dist: colorama<1.0.0,>=0.4.6; extra == "nat"
Requires-Dist: litellm<2.0.0,>=1.83.0; extra == "nat"
Requires-Dist: nvidia-nat==1.6.0; extra == "nat"
Requires-Dist: nvidia-nat-a2a==1.6.0; extra == "nat"
Requires-Dist: nvidia-nat-opentelemetry==1.6.0; extra == "nat"
Requires-Dist: nvidia-nat-langchain==1.6.0; extra == "nat"
Requires-Dist: nvidia-nat-mcp==1.6.0; extra == "nat"
Requires-Dist: anyio==4.11.0; extra == "nat"
Provides-Extra: auth
Requires-Dist: datarobot[auth]<4.0.0,>=3.10.0; extra == "auth"
Requires-Dist: aiohttp<4.0.0,>=3.13.3; extra == "auth"
Requires-Dist: pydantic<3.0.0,>=2.6.1; extra == "auth"
Requires-Dist: httpx<1.0.0,>=0.28.1; extra == "auth"
Requires-Dist: pyjwt[crypto]<3.0.0,>=2.12.0; extra == "auth"
Requires-Dist: okta-client-python<1.0.0,>=0.2.0; extra == "auth"
Provides-Extra: drmcp
Requires-Dist: datarobot[auth]<4.0.0,>=3.10.0; extra == "drmcp"
Requires-Dist: aiohttp<4.0.0,>=3.13.3; extra == "drmcp"
Requires-Dist: pydantic<3.0.0,>=2.6.1; extra == "drmcp"
Requires-Dist: httpx<1.0.0,>=0.28.1; extra == "drmcp"
Requires-Dist: pyjwt[crypto]<3.0.0,>=2.12.0; extra == "drmcp"
Requires-Dist: okta-client-python<1.0.0,>=0.2.0; extra == "drmcp"
Requires-Dist: beautifulsoup4<5.0.0,>=4.12.0; extra == "drmcp"
Requires-Dist: httpx<1.0.0,>=0.28.1; extra == "drmcp"
Requires-Dist: tavily-python<1.0.0,>=0.7.20; extra == "drmcp"
Requires-Dist: perplexityai<1.0,>=0.27; extra == "drmcp"
Requires-Dist: pypdf<7.0.0,>=6.10.1; extra == "drmcp"
Requires-Dist: polars<2.0.0,>=1.0.0; extra == "drmcp"
Requires-Dist: pyarrow<22.0.0,>=21.0.0; extra == "drmcp"
Requires-Dist: python-dateutil<3.0.0,>=2.9.0; extra == "drmcp"
Requires-Dist: datarobot-predict<2.0.0,>=1.13.2; extra == "drmcp"
Requires-Dist: pydantic<3.0.0,>=2.6.1; extra == "drmcp"
Requires-Dist: datarobot<4.0.0,>=3.10.0; extra == "drmcp"
Requires-Dist: aiohttp<4.0.0,>=3.13.3; extra == "drmcp"
Requires-Dist: fastmcp<4.0.0,>=3.2.0; extra == "drmcp"
Requires-Dist: requests<3.0.0,>=2.32.4; extra == "drmcp"
Requires-Dist: openai<3.0.0,>=2.0.0; extra == "drmcp"
Requires-Dist: pyjwt<3.0.0,>=2.12.0; extra == "drmcp"
Requires-Dist: opentelemetry-instrumentation-requests<1.0.0,>=0.43b0; extra == "drmcp"
Requires-Dist: opentelemetry-instrumentation-aiohttp-client<1.0.0,>=0.43b0; extra == "drmcp"
Requires-Dist: opentelemetry-instrumentation-httpx<1.0.0,>=0.43b0; extra == "drmcp"
Requires-Dist: rich<16.0.0,>=13.0.0; extra == "drmcp"
Requires-Dist: datarobot-asgi-middleware<1.0.0,>=0.2.0; extra == "drmcp"
Requires-Dist: python-dotenv<2.0.0,>=1.1.0; extra == "drmcp"
Requires-Dist: boto3<2.0.0,>=1.34.0; extra == "drmcp"
Requires-Dist: pydantic-settings<3.0.0,>=2.1.0; extra == "drmcp"
Requires-Dist: opentelemetry-api<2.0.0,>=1.22.0; extra == "drmcp"
Requires-Dist: opentelemetry-sdk<2.0.0,>=1.22.0; extra == "drmcp"
Requires-Dist: opentelemetry-exporter-otlp<2.0.0,>=1.22.0; extra == "drmcp"
Requires-Dist: opentelemetry-exporter-otlp-proto-http<2.0.0,>=1.22.0; extra == "drmcp"
Requires-Dist: aiohttp-retry<3.0.0,>=2.8.3; extra == "drmcp"
Requires-Dist: datarobot-early-access==3.14.0.2026.3.18.162920; extra == "drmcp"
Provides-Extra: drtools
Requires-Dist: datarobot[auth]<4.0.0,>=3.10.0; extra == "drtools"
Requires-Dist: aiohttp<4.0.0,>=3.13.3; extra == "drtools"
Requires-Dist: pydantic<3.0.0,>=2.6.1; extra == "drtools"
Requires-Dist: httpx<1.0.0,>=0.28.1; extra == "drtools"
Requires-Dist: pyjwt[crypto]<3.0.0,>=2.12.0; extra == "drtools"
Requires-Dist: okta-client-python<1.0.0,>=0.2.0; extra == "drtools"
Requires-Dist: beautifulsoup4<5.0.0,>=4.12.0; extra == "drtools"
Requires-Dist: httpx<1.0.0,>=0.28.1; extra == "drtools"
Requires-Dist: tavily-python<1.0.0,>=0.7.20; extra == "drtools"
Requires-Dist: perplexityai<1.0,>=0.27; extra == "drtools"
Requires-Dist: pypdf<7.0.0,>=6.10.1; extra == "drtools"
Requires-Dist: polars<2.0.0,>=1.0.0; extra == "drtools"
Requires-Dist: pyarrow<22.0.0,>=21.0.0; extra == "drtools"
Requires-Dist: python-dateutil<3.0.0,>=2.9.0; extra == "drtools"
Requires-Dist: datarobot-predict<2.0.0,>=1.13.2; extra == "drtools"
Requires-Dist: pydantic<3.0.0,>=2.6.1; extra == "drtools"
Requires-Dist: datarobot<4.0.0,>=3.10.0; extra == "drtools"
Requires-Dist: aiohttp<4.0.0,>=3.13.3; extra == "drtools"
Provides-Extra: dragent
Requires-Dist: requests<3.0.0,>=2.32.4; extra == "dragent"
Requires-Dist: datarobot<4.0.0,>=3.10.0; extra == "dragent"
Requires-Dist: datarobot-early-access==3.14.0.2026.3.18.162920; extra == "dragent"
Requires-Dist: datarobot-predict<2.0.0,>=1.13.2; extra == "dragent"
Requires-Dist: openai<3.0.0,>=2.0.0; extra == "dragent"
Requires-Dist: ragas<0.5.0,>=0.4.3; extra == "dragent"
Requires-Dist: pyjwt<3.0.0,>=2.12.0; extra == "dragent"
Requires-Dist: opentelemetry-instrumentation-requests<1.0.0,>=0.43b0; extra == "dragent"
Requires-Dist: opentelemetry-instrumentation-aiohttp-client<1.0.0,>=0.43b0; extra == "dragent"
Requires-Dist: opentelemetry-instrumentation-httpx<1.0.0,>=0.43b0; extra == "dragent"
Requires-Dist: opentelemetry-instrumentation-openai<1.0.0,>=0.40.5; extra == "dragent"
Requires-Dist: opentelemetry-instrumentation-threading<1.0.0,>=0.43b0; extra == "dragent"
Requires-Dist: datarobot-moderations[all]<12.0.0,>=11.2.29; extra == "dragent"
Requires-Dist: ag-ui-protocol==0.1.15; extra == "dragent"
Requires-Dist: pyarrow==21.0.0; extra == "dragent"
Requires-Dist: colorama<1.0.0,>=0.4.6; extra == "dragent"
Requires-Dist: litellm<2.0.0,>=1.83.0; extra == "dragent"
Requires-Dist: nvidia-nat==1.6.0; extra == "dragent"
Requires-Dist: nvidia-nat-a2a==1.6.0; extra == "dragent"
Requires-Dist: nvidia-nat-opentelemetry==1.6.0; extra == "dragent"
Requires-Dist: nvidia-nat-langchain==1.6.0; extra == "dragent"
Requires-Dist: nvidia-nat-mcp==1.6.0; extra == "dragent"
Requires-Dist: anyio==4.11.0; extra == "dragent"
Requires-Dist: fastapi<0.133.0; extra == "dragent"
Requires-Dist: starlette<1.0.0; extra == "dragent"
Provides-Extra: memory
Requires-Dist: mem0ai<2.0.0,>=1.0.4; extra == "memory"
Dynamic: license-file
Dynamic: provides-extra

<p align="center">
  <a href="https://github.com/datarobot-oss/datarobot-genai">
    <img src="docs/img/datarobot_logo.avif" width="600px" alt="DataRobot Logo"/>
  </a>
</p>
<h3 align="center">DataRobot GenAI Library</h3>

<p align="center">
  <a href="https://www.datarobot.com/">Homepage</a>
  ·
  <a href="https://pypi.org/project/datarobot-genai/">PyPI</a>
  ·
  <a href="https://docs.datarobot.com/en/docs/get-started/troubleshooting/general-help.html">Support</a>
</p>

<p align="center">
  <a href="/LICENSE">
    <img src="https://img.shields.io/github/license/datarobot-oss/datarobot-genai" alt="License">
  </a>
  <a href="https://pypi.org/project/datarobot-genai/">
    <img src="https://img.shields.io/pypi/v/datarobot-genai" alt="PyPI version">
  </a>
</p>

A toolkit for building agents on DataRobot.

- **Unified LLM layer (DataRobot-compatible)**&mdash;you use one **`get_llm()`** entry point per integration (**LangGraph**, **LlamaIndex**, **CrewAI**, **NAT**), all backed by the same **LiteLLM**-based routing to the **DataRobot LLM Gateway**, **LLM deployments**, **NIM**, or external providers.
- **Library of agentic tools and DataRobot-compatible MCP server**&mdash;use `drtools` and `drmcp` to give your agent first-class capabilities to interact with the world.
- **AG-UI integration**&mdash;your agents expose a standard **AG-UI** event stream (`RunAgentInput` in, lifecycle + text + tool-call events out), so your UIs and the DataRobot platform render runs consistently without bespoke adapters per framework.
- **Multi-agent systems out of the box**&mdash;you get first-class patterns for **planner/writer crews**, **LangGraph** multi-node graphs, and **LlamaIndex** `AgentWorkflow` handoffs; wrap them with one helper and keep the same streaming contract.
- **Orchestration**&mdash;you build agents from universal pieces in the low-code `workflow.yaml` interface. Combine and reuse LLMs, tools, agents, and evaluators. The design stays compatible with and draws inspiration from [NeMo Agentic Toolkit](https://github.com/NVIDIA/NeMo-Agent-Toolkit).
- **Serving and evaluating with DRAgent**&mdash;you run a front-end server to plug your agent into a real-world application. DRAgent supports distributed tracing, generation and evaluation endpoints, async generations, and two-way communication over WebSockets.

# Use

## Installation
- You need Python 3.11–3.13.
- Install the extra that matches the framework you use:
```bash
pip install "datarobot-genai[crewai]"
pip install "datarobot-genai[langgraph]"
pip install "datarobot-genai[llamaindex]"
pip install "datarobot-genai[nat]"
```

You can also install:
* `datarobot-genai[dragent]`&mdash;serve and orchestrate your agent with `DRAgent`.
* `datarobot-genai[drtools]`&mdash;use the standard library of agentic tools DataRobot provides.
* `datarobot-genai[drmcp]`&mdash;host a custom MCP server in DataRobot.
* `datarobot-genai[memory]`&mdash;use the Mem0-backed memory client and NAT memory provider.

## Credentials
You need a DataRobot account to use DataRobot-backed features. Export these environment variables:

```bash
# Set your DataRobot API token (replace the placeholder).
export DATAROBOT_API_TOKEN=YOUR_DATAROBOT_API_TOKEN
export DATAROBOT_ENDPOINT=https://app.datarobot.com/api/v2
```

## Standalone end-to-end examples
Follow [quickstart.ipynb](e2e-tests/examples/quickstart.ipynb) to walk through an experience of setting a LangGraph agent with DataRobot:
* LLM Gateway
* `drtools`
* Prompt Management
* Conversion to DataRobot agent format
* Running the agent with an AG-UI interface.

## In-depth documentation
See [docs/README.md](docs/README.md) for guides on every framework and feature in `datarobot-genai`.

# Develop
You need Python 3.11–3.13, uv, Task CLI, and pre-commit.
```bash
uv sync --all-extras --dev
pre-commit install
task test
```

### Semantic versioning
When you change the library, bump the patch version and add an entry to `CHANGELOG.md`.
When you introduce a backward-incompatible change, bump the minor version.

### TestPyPI
Comment `/build` on your PR to build and publish a dev version of the package to TestPyPI.

## Excluded Upstream Dependencies

Several transitive dependencies pulled in by upstream packages are not used by this library at runtime.
These are explicitly excluded via `[tool.uv] exclude-dependencies` in `pyproject.toml` to reduce install size and CVE surface area.

| Package | Pulled in by | Reason excluded |
|---------|-------------|-----------------|
| `build` | `crewai` | Python build system; runtime unnecessary |
| `diskcache` | `ragas` | Optional disk caching backend; not used |
| `flask` | `nvidia-nat 1.6.0` | Web framework; not used |
| `kubernetes` | `crewai-tools` | K8s client; not used |
| `lancedb` | `crewai` | Optional vector DB backend; not used |
| `langchain-milvus` | `nvidia-nat-langchain` | Milvus vector DB adapter; not used |
| `llama-index-cli` | `llama-index` | CLI tool; not needed at runtime |
| `openpyxl` | `crewai-tools` | Excel parser; not used |
| `pymilvus` | `langchain-milvus` | Milvus client; not used |
| `python-docx` | `crewai-tools` | Word doc parser; not used |
| `pytube` | `crewai-tools` | YouTube downloader; not used |
| `scikit-network` | `ragas` | Graph analysis library; not used |
| `stagehand` | `crewai-tools` | Playwright web automation; not used |
| `uv` | `crewai` | Package manager bundled as a runtime dep; not needed |
| `youtube-transcript-api` | `crewai-tools` | YouTube transcripts; not used |

## Publishing

- **Same-repo PRs**&mdash;comment `/build` on your PR to publish dev builds to TestPyPI (`.devN`).
- **Merge to `main`**&mdash;the release flow creates tag `v{version}` and publishes to PyPI automatically.
- **Version tags**&mdash;when you push a `v*` tag, PyPI publish runs as well.
- **Local release**&mdash;optionally run `task release:tag-and-push` to create and push `v{version}` from your machine.

## Links

- [Repository](https://github.com/datarobot-oss/datarobot-genai)&mdash;source and issues.
- [PyPI](https://pypi.org/project/datarobot-genai/)&mdash;released packages.
- [TestPyPI](https://test.pypi.org/project/datarobot-genai/)&mdash;dev builds.

## License

Apache-2.0&mdash;see [LICENSE](LICENSE).
