Observed since 20 Oct, 22:00 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
Oracle AI Database native vector stores for Microsoft Agent Framework.
An alpha connector for storing and searching native VECTOR columns in Oracle
AI Database 26ai. OracleCollection implements async batch CRUD and vector
search; OracleStore shares a client across collections; OracleSettings
describes the connection and pool settings resolved through Agent Framework.
pip install agent-framework-oracle --pre
Requires Python 3.10+, Oracle AI Database 26ai with COMPATIBLE set to
23.4.0 or higher, python-oracledb 2.2.x or 3.x, and permission to
create/drop tables in the connected user's schema. The connector uses the
driver's async Thin-mode API; it does not initialize the Thick client or
provision a database.
It does not create or alter schemas, vector indexes, or existing tables.
For username/password authentication, set ORACLE_DSN (for example
localhost:1521/FREEPDB1), ORACLE_USER, and ORACLE_PASSWORD, or pass
dsn, user, and password to either constructor. Typed driver settings can
also be supplied with the pool_parameters mapping. Settings are resolved in
order: named dsn/user/password argument > pool_parameters > selected
.env file > process environment > connector pool defaults. A .env file is
read only when env_file_path is specified; the selected file must exist, and
env_file_encoding overrides UTF-8. password accepts str or Agent Framework
SecretString and is unwrapped only when opening a connection.
Named connection values must be nonempty when supplied, but their presence is
not required by the connector. Authentication and connection-descriptor
completeness are validated by python-oracledb, allowing alternatives such as
access_token, externalauth, or host with service_name/sid.
Explicit pool_parameters keys are forwarded when they are accepted by the
installed python-oracledb version, including newly added driver options not
yet declared by the open OracleSettings typed dictionary. This preserves
editor discovery for known options while allowing forward-compatible keys.
Unsupported names and typos raise an error; unrecognized ORACLE_ environment
variables remain ignored.
Recognized scalar oracledb.create_pool_async() options can also be supplied as
ORACLE_ settings. The prefix is removed, the remainder is converted to the
driver's lowercase keyword name, and boolean, integer, and floating-point
values are converted before the pool is created. Password-like values remain
masked until they are passed to the driver. For example:
ORACLE_DSN=localhost:1521/FREEPDB1
ORACLE_USER=example
ORACLE_PASSWORD=database-password
ORACLE_WALLET_LOCATION=/path/to/wallet
ORACLE_WALLET_PASSWORD=wallet-password
ORACLE_MIN=1
ORACLE_MAX=8
ORACLE_HOMOGENEOUS=false
The connector uses min=0 and max=4 when those options are not configured.
Unrecognized ORACLE_ variables are ignored. Options that require callbacks,
classes, collections, or SSL context objects are not loaded from text settings;
pass them through pool_parameters or use a configured client.
Alternatively, pass a configured oracledb.AsyncConnection or
oracledb.AsyncConnectionPool as client for advanced authentication. A
supplied client cannot be combined with connection settings and remains
caller-owned. A connector-created pool opens on first use and closes on
close() or async context exit. A collection obtained from a store borrows its
client; closing that collection does not close the store. The store must remain
open while its collections are used.
Writes on pooled connections (both connector-owned and caller-supplied pools)
are committed on success and rolled back on failure. Writes to a supplied
AsyncConnection are left in the caller's transaction; the caller must
commit or roll back. Oracle DDL commits independently of the surrounding
transaction. Batch upserts on a borrowed connection may leave partial pending
work on failure, so roll it back before reuse.
ensure_collection_exists() leaves an existing table unchanged and does not
validate its schema; use a matching definition or create a new table. It never
migrates data or changes existing indexes.
import asyncio
from dataclasses import dataclass
from typing import Annotated
from agent_framework import Filter, VectorStoreField, vectorstoremodel
from agent_framework_oracle import OracleStore
@vectorstoremodel(collection_name="articles")
@dataclass
class Article:
id: Annotated[str, VectorStoreField("key")]
text: Annotated[str, VectorStoreField("data")]
embedding: Annotated[list[float] | None, VectorStoreField("vector", dimensions=3)] = None
async def main() -> None:
async with OracleStore() as store:
collection = store.get_collection(Article)
await collection.ensure_collection_exists()
await collection.upsert([Article("one", "Oracle vector search", [1, 0, 0])], generate_vectors=False)
results = await collection.search(
vector=[1, 0, 0], filter=Filter("text", "contains_text", "Oracle"), top=3
)
async for result in results:
print(result["record"].text, result["score"])
asyncio.run(main())
Pass generate_vectors=False for precomputed vectors, or configure an
embedding_generator for local generation. get() excludes vector columns by
default; pass include_vectors=True to restore them. get(keys) preserves
requested key order and duplicates, omitting missing keys; filtered retrieval
supports top, skip, and order_by. Both get() and search() execute
portable filters and paging in Oracle. The
runnable sample
creates and deletes a unique test table.
float/float32 (Oracle FLOAT32), float64 (FLOAT64), or int8
(INT8); omitted element types use FLOAT32. Dimensions must be 1–65535.
Supplied vectors must be dense finite numeric sequences with the declared
dimensions. Binary and sparse vectors are not supported.str (up to 4000 UTF-8 bytes), int (signed
64-bit), float (BINARY_DOUBLE), and bool (stored as NUMBER(1,0)).
Oracle converts empty strings to NULL, so this connector rejects empty
string values rather than changing their meaning. JSON fields, nested
paths, provider annotations, data/full-text/vector indexes, and schema
migration are not supported.VECTOR_DISTANCE with an explicit metric. The default
is COSINE distance; cosine_similarity, Euclidean distance, dot
product, negative dot product, squared Euclidean distance, and Manhattan
distance are also available. Scores are native
metric values, not probabilities. For distances a score_threshold is
a maximum; for similarities/dot product it is a minimum. The cutoff is
applied in SQL before paging. No ANN indexes are created or managed;
Oracle may use an existing index if the table already has one. There is no
exact/approximate toggle, server-side embedding generation, or
keyword-hybrid search. Index-selected approximate searches may return fewer
than the requested number of results.NULL and boolean
distinctions), in/not_in, numeric ranges, is_null, is_not_null,
exists, literal text contains_text/starts_with/ends_with, and
AND/OR/NOT. Finite Decimal values are supported for exact numeric equality
and membership; malformed UUID filter values compare as unequal.
Collection membership and nested filters are rejected.
Ordered filters on integer fields reject non-integral float operands;
ordered Decimal operands are not supported.
String comparison follows the configured Oracle collation. Input values
are bound; identifiers are checked and quoted as individual names.The unit tests require no Oracle server. To run the live integration test,
provide all three ORACLE_TEST_DSN, ORACLE_TEST_USER, and
ORACLE_TEST_PASSWORD for an explicitly designated disposable Oracle AI
Database 26ai schema where the user can create and drop tables:
cd python
uv run --package agent-framework-oracle pytest packages/oracle/tests \
-m integration
Without those variables, the integration test skips; it never falls back to ordinary application credentials. The fixture creates a unique table and deletes only that table.
Download counts and popularity will appear here as the collector receives them.
| Version | Published | Direct dependencies | Open version |
|---|---|---|---|
| 1.0.0a261015 | 15 Oct 2026 | 2 |
This describes our collected data; it is not a security assessment.
Observed since 20 Oct, 22:00 UTC
No superseded metadata states collected. Unchanged observations do not create new revisions.
package:1d693b6c4dac9410b9d7343844ba998bd8b7859cb1fec7d0318a0b78e70e9cef