Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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
24 changes: 24 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
.git
.venv
.pytest_cache
.ruff_cache
__pycache__
*.py[cod]
*.egg-info
.coverage
htmlcov
build
dist
docs
tests
samples
.env
.env.*
wallet
wallets
*.pem
*.key
*.sso
*.p12
*.zip
build/
31 changes: 31 additions & 0 deletions .gcloudignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,31 @@
# Keep the Cloud Build source upload small and exclude local credentials.
#!include:.gitignore

.git
.gcloudignore
.venv
.venv*/
.env
.env.*
wallet/
wallets/
*.pem
*.key
*.sso
*.p12
*.zip
__pycache__/
.pytest_cache/
.ruff_cache/
build/
dist/
doc/
docs/
tests/
samples/
*.docx
*.pdf
*.png
*.jpg
*.jpeg
build/
2 changes: 1 addition & 1 deletion .github/workflows/test.yaml
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ jobs:
run: |
python -m pip install --upgrade pip setuptools
pip install pytest anyio
pip install -e .
pip install -e ".[cli]"

- name: Wait for ADB Free Container
run: |
Expand Down
1 change: 1 addition & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -23,3 +23,4 @@ sample_connect.py
async_pipeline_test.py
parquet.py
local_sample
build/
93 changes: 76 additions & 17 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,22 @@ Select AI for Python enables you to ask questions of your database data using na

Select AI for Python enables you to leverage the broader Python ecosystem in combination with generative AI and database functionality - bridging the gap between the DBMS_CLOUD_AI PL/SQL package and Python's rich ecosystem. It provides intuitive objects and methods for AI model interaction.

## Table of Contents

- [Installation](#installation)
- [Documentation](#documentation)
- [Getting Started](#getting-started)
- [Async Example](#async-example)
- [Command Line Interface](#command-line-interface)
- [Chat](#chat)
- [A2A Server](#a2a-server)
- [Cloud Run](#cloud-run)
- [Samples](#samples)
- [Help](#help)
- [Contributing](#contributing)
- [Security](#security)
- [License](#license)


## Installation

Expand All @@ -20,26 +36,13 @@ Install the optional command line interface:
python3 -m pip install 'select_ai[cli]'
```

The CLI extra includes A2A server support.

## Documentation

See [Select AI for Python documentation][documentation]

## Samples

Examples can be found in the [/samples][samples] directory

## Command Line Interface

The optional `select-ai` command provides an interactive chat REPL for Select AI
profiles:

```bash
select-ai chat --profile OCI_AI_PROFILE
```

![Select AI CLI demo](doc/source/image/select_ai_cli_demo.gif)

### Basic Example
## Getting Started

```python
import select_ai
Expand Down Expand Up @@ -81,6 +84,62 @@ async def main():
asyncio.run(main())

```

## Command Line Interface

The optional `select-ai` command provides interactive chat, SQL, profile
management, and A2A server tools for Select AI:

### Chat

```bash
select-ai chat --profile OCI_AI_PROFILE
```

![Select AI CLI demo](doc/source/image/select_ai_cli_demo.gif)

### A2A Server

Expose one Oracle Database AI agent team as an A2A JSON-RPC HTTP server:

```bash
select-ai a2a serve --team SALES_ANALYST --port 8000
```

![Select AI A2A server demo](doc/source/image/select_ai_a2a_server_demo.gif)

The command obtains database connection settings from its options or the
`SELECT_AI_*` environment variables. Its Agent Card is available at
`/.well-known/agent-card.json`, and its JSON-RPC endpoint is
`/a2a/jsonrpc/`. Set `--public-url` when the server is behind a proxy or load
balancer so that clients receive its externally reachable URL.

For Autonomous Database mTLS, also set `SELECT_AI_WALLET_LOCATION` to the
directory containing the unzipped wallet and set `SELECT_AI_WALLET_PASSWORD`.
The CLI passes both values to the Select AI SDK as `wallet_location` and
`wallet_password`.

The server accepts both A2A 1.x and the A2A v0.3 JSON-RPC streaming protocol
for compatibility with Gemini Enterprise.

Generate the A2A v0.3 Agent Card to paste into Gemini Enterprise after the
service has a public URL:

```bash
select-ai a2a agent-card \
--team ORACLE_AI_DATABASE_AGENT \
--public-url https://YOUR-SERVICE.run.app
```

#### Cloud Run

Deploy the A2A server to Cloud Run using the instructions in
[gcloud/README.md](https://github.com/oracle/python-select-ai/blob/main/gcloud/README.md).

## Samples

For in-depth examples, see the [/samples][samples] directory.

## Help

Questions can be asked in [GitHub Discussions][ghdiscussions].
Expand All @@ -97,7 +156,7 @@ Please consult the [security guide][security] for our responsible security vulne

## License

Copyright (c) 2025 Oracle and/or its affiliates.
Copyright (c) 2025, 2026 Oracle and/or its affiliates.

Released under the Universal Permissive License v1.0 as shown at
<https://oss.oracle.com/licenses/upl/>.
Expand Down
Binary file added doc/source/image/select_ai_a2a_server_demo.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
38 changes: 38 additions & 0 deletions doc/source/user_guide/agent.rst
Original file line number Diff line number Diff line change
Expand Up @@ -446,6 +446,44 @@ operations.

.. latex:clearpage::

*************
Agent history
*************

``TeamHistory``, ``TaskHistory``, and ``ToolHistory`` provide typed,
read-only access to the current user's Select AI Agent history views. They
query only ``USER_AI_AGENT_TEAM_HISTORY``, ``USER_AI_AGENT_TASK_HISTORY``,
and ``USER_AI_AGENT_TOOL_HISTORY`` respectively. Results are yielded newest
first. Tool ``input`` and ``output`` values are decoded to Python objects when
they contain valid JSON; other CLOB payloads are returned as strings.

.. code-block:: python

from select_ai.agent import TaskHistory, TeamHistory, ToolHistory

for run in TeamHistory.list(team_name="MOVIE_AGENT_TEAM", limit=10):
print(run.team_exec_id, run.state)

for run in TaskHistory.list(team_exec_id="<team execution id>"):
print(run.task_name, run.result)

for call in ToolHistory.list(tool_name="MOVIE_SQL_TOOL", limit=20):
print(call.input, call.output)

The sample retrieves a team's latest execution and uses its ``team_exec_id``
to retrieve the associated task and tool history.

.. autoclass:: select_ai.agent.TeamHistory
:members:

.. autoclass:: select_ai.agent.TaskHistory
:members:

.. autoclass:: select_ai.agent.ToolHistory
:members:

.. latex:clearpage::

*****************
AI agent examples
*****************
Expand Down
14 changes: 14 additions & 0 deletions doc/source/user_guide/async_agent.rst
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,20 @@
use ``asyncio`` and ``select_ai.async_connect()`` or
``select_ai.create_pool_async()``.

The history API follows the same pattern. ``AsyncTeamHistory``,
``AsyncTaskHistory``, and ``AsyncToolHistory`` query only the current user's
history views and yield typed events newest first.

.. code-block:: python

from select_ai.agent import AsyncToolHistory

async for call in AsyncToolHistory.list(limit=10):
print(call.tool_name, call.output)

The async sample retrieves a team's latest execution and uses its
``team_exec_id`` to retrieve the associated task and tool history.

The async agent object model mirrors the synchronous agent object model:

.. list-table:: Sync and async agent APIs
Expand Down
2 changes: 1 addition & 1 deletion doc/source/user_guide/cli.rst
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@ workflows will be added in upcoming releases as the CLI evolves.
:width: 100%

The package provides an optional ``select-ai`` command line tool. Install the
CLI extra to use it:
CLI extra to use it, including the A2A server commands:

.. code-block:: bash

Expand Down
4 changes: 2 additions & 2 deletions doc/source/user_guide/installation.rst
Original file line number Diff line number Diff line change
Expand Up @@ -72,8 +72,8 @@ are isolated from your system Python installation.

python -m pip install --upgrade "select_ai[cli]"

This installs the ``select-ai`` command. See :ref:`Command Line Interface
<cli>`.
This installs the ``select-ai`` command and its A2A server support. See
:ref:`Command Line Interface <cli>`.

6. If you are behind a proxy, use the ``--proxy`` option. For example:

Expand Down
5 changes: 5 additions & 0 deletions doc/source/user_guide/profile_attributes.rst
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,11 @@ Attribute groups
- Tunes model generation behavior.
* - ``conversation``
- Enables conversation history for context-aware chat workflows.
* - ``source_language``, ``target_language``
- Set default languages for ``Profile.translate()`` and
``AsyncProfile.translate()``. If no source language is configured or
supplied per call, the provider detects it. A target language must be
supplied either per call or in the profile.
* - ``vector_index_name``, ``enable_sources``,
``enable_source_offsets``, ``enable_custom_source_uri``
- Configures retrieval-augmented generation and source reporting for
Expand Down
4 changes: 3 additions & 1 deletion doc/source/user_guide/synthetic_data.rst
Original file line number Diff line number Diff line change
Expand Up @@ -72,7 +72,9 @@ Use ``SyntheticDataParams`` to control how generation is performed:
``sample_rows`` controls how many existing rows are used as examples for the
model. ``table_statistics`` and ``comments`` include additional table metadata.
``priority`` controls resource priority for generation work; supported values
are ``HIGH``, ``MEDIUM``, and ``LOW``.
are ``HIGH``, ``MEDIUM``, and ``LOW``. All parameters are optional. Parameters
that are not supplied are omitted from the request, allowing the database to
apply its defaults.

Sync and async APIs
===================
Expand Down
29 changes: 29 additions & 0 deletions docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
# -----------------------------------------------------------------------------
# Copyright (c) 2026, Oracle and/or its affiliates.
#
# Licensed under the Universal Permissive License v 1.0 as shown at
# http://oss.oracle.com/licenses/upl.
# -----------------------------------------------------------------------------

FROM oraclelinux:10-slim

ENV PATH=/opt/venv/bin:$PATH

RUN microdnf update -y \
&& microdnf install -y python3 python3-pip ca-certificates unzip \
&& microdnf clean all

WORKDIR /app

COPY pyproject.toml README.md LICENSE.txt ./
COPY src ./src

RUN python3 -m venv /opt/venv \
&& python -m pip install --no-cache-dir --upgrade pip setuptools wheel \
&& python -m pip install --no-cache-dir '.[a2a]'

COPY docker/a2a-entrypoint.sh /app/docker/a2a-entrypoint.sh

RUN chmod 0555 /app/docker/a2a-entrypoint.sh

ENTRYPOINT ["select-ai"]
40 changes: 40 additions & 0 deletions docker/a2a-entrypoint.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
#!/usr/bin/env bash

# -----------------------------------------------------------------------------
# Copyright (c) 2026, Oracle and/or its affiliates.
#
# Licensed under the Universal Permissive License v 1.0 as shown at
# http://oss.oracle.com/licenses/upl.
# -----------------------------------------------------------------------------

# Cloud Run-only A2A launcher. It expands the optional wallet archive mounted
# by deploy.sh, then starts the generic select-ai CLI in A2A server mode.

set -eu

wallet_archive=/var/run/secrets/select-ai-wallet/wallet.zip
wallet_root=/tmp/select-ai-wallet

if [ -f "$wallet_archive" ]; then
mkdir -p "$wallet_root"
chmod 700 "$wallet_root"
unzip -q "$wallet_archive" -d "$wallet_root"

wallet_file="$(find "$wallet_root" -type f -name ewallet.pem -print -quit)"
if [ -z "$wallet_file" ]; then
echo "Wallet ZIP does not contain ewallet.pem" >&2
exit 1
fi
export SELECT_AI_WALLET_LOCATION="$(dirname "$wallet_file")"
fi

: "${SELECT_AI_A2A_TEAM:?SELECT_AI_A2A_TEAM is required}"
: "${PUBLIC_URL:?PUBLIC_URL is required}"
: "${SELECT_AI_POOL_MAX_SIZE:=10}"

exec select-ai a2a serve \
--team "$SELECT_AI_A2A_TEAM" \
--host 0.0.0.0 \
--port "${PORT:-8080}" \
--pool-max-size "$SELECT_AI_POOL_MAX_SIZE" \
--public-url "$PUBLIC_URL"
Loading