agent-framework-oracle 1.0.0a261008__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) Microsoft Corporation.
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE
@@ -0,0 +1,175 @@
1
+ Metadata-Version: 2.4
2
+ Name: agent-framework-oracle
3
+ Version: 1.0.0a261008
4
+ Summary: Oracle Database native vector stores for Microsoft Agent Framework.
5
+ Author-email: Microsoft <af-support@microsoft.com>
6
+ Requires-Python: >=3.10
7
+ Description-Content-Type: text/markdown
8
+ Classifier: License :: OSI Approved :: MIT License
9
+ Classifier: Development Status :: 3 - Alpha
10
+ Classifier: Intended Audience :: Developers
11
+ Classifier: Programming Language :: Python :: 3
12
+ Classifier: Programming Language :: Python :: 3.10
13
+ Classifier: Programming Language :: Python :: 3.11
14
+ Classifier: Programming Language :: Python :: 3.12
15
+ Classifier: Programming Language :: Python :: 3.13
16
+ Classifier: Programming Language :: Python :: 3.14
17
+ Classifier: Typing :: Typed
18
+ License-File: LICENSE
19
+ Requires-Dist: agent-framework-core>=1.19.0,<2
20
+ Requires-Dist: oracledb>=2.2.0,<4
21
+ Project-URL: homepage, https://aka.ms/agent-framework
22
+ Project-URL: issues, https://github.com/microsoft/agent-framework/issues
23
+ Project-URL: source, https://github.com/microsoft/agent-framework/tree/main/python
24
+
25
+ # Agent Framework Oracle vector store
26
+
27
+ An alpha connector for storing and searching native `VECTOR` columns in Oracle
28
+ Database 23ai or newer. `OracleCollection` implements async batch CRUD and
29
+ vector search; `OracleStore` shares a client across collections; `OracleSettings`
30
+ resolves connection configuration through Agent Framework.
31
+
32
+ ## Installation and setup
33
+
34
+ ```bash
35
+ pip install agent-framework-oracle --pre
36
+ ```
37
+
38
+ Requires Python 3.10+, Oracle Database 23ai or newer with `COMPATIBLE` set to
39
+ **23.4.0 or higher**, `python-oracledb` 2.2.x or 3.x, and permission to
40
+ create/drop tables in the connected user's schema. The connector uses the
41
+ driver's async Thin-mode API; it does not initialize the Thick client or
42
+ provision a database.
43
+ It does not create or alter schemas, vector indexes, or existing tables.
44
+
45
+ Set `ORACLE_DSN` (for example `localhost:1521/FREEPDB1`), `ORACLE_USER`, and
46
+ `ORACLE_PASSWORD`, or pass `dsn`, `user`, and `password` to either constructor.
47
+ Credentials are resolved in order: **explicit argument > selected `.env` file
48
+ > process environment**. A `.env` file is read only when `env_file_path` is
49
+ specified; `env_file_encoding` overrides UTF-8. `password` accepts `str` or
50
+ Agent Framework `SecretString` and is unwrapped only when opening a connection.
51
+ Missing or empty credentials are errors.
52
+
53
+ Alternatively, pass a configured `oracledb.AsyncConnection` or
54
+ `oracledb.AsyncConnectionPool` as `client` for advanced authentication. A
55
+ supplied client cannot be combined with connection settings and remains
56
+ caller-owned. A connector-created pool opens on first use and closes on
57
+ `close()` or async context exit. A collection obtained from a store borrows its
58
+ client; closing that collection does not close the store. The store must remain
59
+ open while its collections are used.
60
+
61
+ Writes on pooled connections (both connector-owned and caller-supplied pools)
62
+ are committed on success and rolled back on failure. Writes to a supplied
63
+ `AsyncConnection` are left in the caller's transaction; **the caller must
64
+ commit or roll back**. Oracle DDL commits independently of the surrounding
65
+ transaction. Batch upserts on a borrowed connection may leave partial pending
66
+ work on failure, so roll it back before reuse.
67
+
68
+ `ensure_collection_exists()` leaves an existing table unchanged and does not
69
+ validate its schema; use a matching definition or create a new table. It never
70
+ migrates data or changes existing indexes.
71
+
72
+ ## Usage
73
+
74
+ ```python
75
+ import asyncio
76
+ from dataclasses import dataclass
77
+ from typing import Annotated
78
+
79
+ from agent_framework import Filter, VectorStoreField, vectorstoremodel
80
+ from agent_framework_oracle import OracleStore
81
+
82
+
83
+ @vectorstoremodel(collection_name="articles")
84
+ @dataclass
85
+ class Article:
86
+ id: Annotated[str, VectorStoreField("key")]
87
+ text: Annotated[str, VectorStoreField("data")]
88
+ embedding: Annotated[list[float] | None, VectorStoreField("vector", dimensions=3)] = None
89
+
90
+
91
+ async def main() -> None:
92
+ async with OracleStore() as store:
93
+ collection = store.get_collection(Article)
94
+ await collection.ensure_collection_exists()
95
+ await collection.upsert([Article("one", "Oracle vector search", [1, 0, 0])], generate_vectors=False)
96
+ results = await collection.search(
97
+ vector=[1, 0, 0], filter=Filter("text", "contains_text", "Oracle"), top=3
98
+ )
99
+ async for result in results:
100
+ print(result["record"].text, result["score"])
101
+
102
+
103
+ asyncio.run(main())
104
+ ```
105
+
106
+ Pass `generate_vectors=False` for precomputed vectors, or configure an
107
+ `embedding_generator` for local generation. `get()` excludes vector columns by
108
+ default; pass `include_vectors=True` to restore them. `get(keys)` preserves
109
+ requested key order and duplicates, omitting missing keys; filtered retrieval
110
+ supports `top`, `skip`, and `order_by`. Both `get()` and `search()` execute
111
+ portable filters and paging in Oracle. The
112
+ [runnable sample](https://github.com/microsoft/agent-framework/blob/main/python/packages/oracle/samples/oracle_vectors.py)
113
+ creates and deletes a unique test table.
114
+
115
+ ## Capabilities and limits
116
+
117
+ - A collection is one table in the **current user's schema**. Keys are
118
+ application-provided strings (up to 512 UTF-8 bytes), signed 64-bit integers,
119
+ or UUIDs; automatically generated keys are not supported.
120
+ - Multiple nullable native vector columns are supported. Vector fields may
121
+ declare `float`/`float32` (Oracle `FLOAT32`), `float64` (`FLOAT64`), or `int8`
122
+ (`INT8`); omitted element types use `FLOAT32`. Dimensions must be 1–65535.
123
+ Supplied vectors must be dense finite numeric sequences with the declared
124
+ dimensions. Binary and sparse vectors are not supported.
125
+ - Scalar data fields support `str` (up to 4000 UTF-8 bytes), `int` (signed
126
+ 64-bit), `float` (`BINARY_DOUBLE`), and `bool` (stored as `NUMBER(1,0)`).
127
+ Oracle converts empty strings to `NULL`, so this connector rejects empty
128
+ string **values** rather than changing their meaning. JSON fields, nested
129
+ paths, provider annotations, data/full-text/vector indexes, and schema
130
+ migration are not supported.
131
+ - Search uses Oracle `VECTOR_DISTANCE` with an explicit metric. The default
132
+ is `COSINE` **distance**; `cosine_similarity`, Euclidean distance, dot
133
+ product, negative dot product, squared Euclidean distance, and Manhattan
134
+ distance are also available. Scores are native
135
+ metric values, **not probabilities**. For distances a `score_threshold` is
136
+ a maximum; for similarities/dot product it is a minimum. The cutoff is
137
+ applied in SQL **before** paging. No ANN indexes are created or managed;
138
+ Oracle may use an existing index if the table already has one. There is no
139
+ exact/approximate toggle, server-side embedding generation, or
140
+ keyword-hybrid search. Index-selected approximate searches may return fewer
141
+ than the requested number of results.
142
+ - Portable filters support scalar equality (including `NULL` and boolean
143
+ distinctions), `in`/`not_in`, numeric ranges, `is_null`, `is_not_null`,
144
+ `exists`, literal text `contains_text`/`starts_with`/`ends_with`, and
145
+ AND/OR/NOT. Finite `Decimal` values are supported for exact numeric equality
146
+ and membership; malformed UUID filter values compare as unequal.
147
+ Collection membership and nested filters are rejected.
148
+ Ordered filters on integer fields reject non-integral float operands;
149
+ ordered `Decimal` operands are not supported.
150
+ String comparison follows the configured Oracle collation. Input values
151
+ are bound; identifiers are checked and quoted as individual names.
152
+
153
+ ## Opt-in database tests
154
+
155
+ The unit tests require no Oracle server. To run the live integration test,
156
+ provide **all three** `ORACLE_TEST_DSN`, `ORACLE_TEST_USER`, and
157
+ `ORACLE_TEST_PASSWORD` for an explicitly designated disposable Oracle 23ai+
158
+ schema where the user can create and drop tables:
159
+
160
+ ```bash
161
+ cd python
162
+ uv run --package agent-framework-oracle pytest packages/oracle/tests \
163
+ -m integration
164
+ ```
165
+
166
+ Without those variables, the integration test skips; it never falls back to
167
+ ordinary application credentials. The fixture creates a unique table and
168
+ deletes only that table.
169
+
170
+ ## Documentation
171
+
172
+ - [Oracle Database AI Vector Search requirements](https://docs.oracle.com/en/database/oracle/oracle-database/26/vecse/overview-ai-vector-search.html)
173
+ - [python-oracledb 2.2 vector types](https://python-oracledb.readthedocs.io/en/v2.2.0/user_guide/vector_data_type.html)
174
+ - [Microsoft Agent Framework](https://learn.microsoft.com/agent-framework/)
175
+
@@ -0,0 +1,150 @@
1
+ # Agent Framework Oracle vector store
2
+
3
+ An alpha connector for storing and searching native `VECTOR` columns in Oracle
4
+ Database 23ai or newer. `OracleCollection` implements async batch CRUD and
5
+ vector search; `OracleStore` shares a client across collections; `OracleSettings`
6
+ resolves connection configuration through Agent Framework.
7
+
8
+ ## Installation and setup
9
+
10
+ ```bash
11
+ pip install agent-framework-oracle --pre
12
+ ```
13
+
14
+ Requires Python 3.10+, Oracle Database 23ai or newer with `COMPATIBLE` set to
15
+ **23.4.0 or higher**, `python-oracledb` 2.2.x or 3.x, and permission to
16
+ create/drop tables in the connected user's schema. The connector uses the
17
+ driver's async Thin-mode API; it does not initialize the Thick client or
18
+ provision a database.
19
+ It does not create or alter schemas, vector indexes, or existing tables.
20
+
21
+ Set `ORACLE_DSN` (for example `localhost:1521/FREEPDB1`), `ORACLE_USER`, and
22
+ `ORACLE_PASSWORD`, or pass `dsn`, `user`, and `password` to either constructor.
23
+ Credentials are resolved in order: **explicit argument > selected `.env` file
24
+ > process environment**. A `.env` file is read only when `env_file_path` is
25
+ specified; `env_file_encoding` overrides UTF-8. `password` accepts `str` or
26
+ Agent Framework `SecretString` and is unwrapped only when opening a connection.
27
+ Missing or empty credentials are errors.
28
+
29
+ Alternatively, pass a configured `oracledb.AsyncConnection` or
30
+ `oracledb.AsyncConnectionPool` as `client` for advanced authentication. A
31
+ supplied client cannot be combined with connection settings and remains
32
+ caller-owned. A connector-created pool opens on first use and closes on
33
+ `close()` or async context exit. A collection obtained from a store borrows its
34
+ client; closing that collection does not close the store. The store must remain
35
+ open while its collections are used.
36
+
37
+ Writes on pooled connections (both connector-owned and caller-supplied pools)
38
+ are committed on success and rolled back on failure. Writes to a supplied
39
+ `AsyncConnection` are left in the caller's transaction; **the caller must
40
+ commit or roll back**. Oracle DDL commits independently of the surrounding
41
+ transaction. Batch upserts on a borrowed connection may leave partial pending
42
+ work on failure, so roll it back before reuse.
43
+
44
+ `ensure_collection_exists()` leaves an existing table unchanged and does not
45
+ validate its schema; use a matching definition or create a new table. It never
46
+ migrates data or changes existing indexes.
47
+
48
+ ## Usage
49
+
50
+ ```python
51
+ import asyncio
52
+ from dataclasses import dataclass
53
+ from typing import Annotated
54
+
55
+ from agent_framework import Filter, VectorStoreField, vectorstoremodel
56
+ from agent_framework_oracle import OracleStore
57
+
58
+
59
+ @vectorstoremodel(collection_name="articles")
60
+ @dataclass
61
+ class Article:
62
+ id: Annotated[str, VectorStoreField("key")]
63
+ text: Annotated[str, VectorStoreField("data")]
64
+ embedding: Annotated[list[float] | None, VectorStoreField("vector", dimensions=3)] = None
65
+
66
+
67
+ async def main() -> None:
68
+ async with OracleStore() as store:
69
+ collection = store.get_collection(Article)
70
+ await collection.ensure_collection_exists()
71
+ await collection.upsert([Article("one", "Oracle vector search", [1, 0, 0])], generate_vectors=False)
72
+ results = await collection.search(
73
+ vector=[1, 0, 0], filter=Filter("text", "contains_text", "Oracle"), top=3
74
+ )
75
+ async for result in results:
76
+ print(result["record"].text, result["score"])
77
+
78
+
79
+ asyncio.run(main())
80
+ ```
81
+
82
+ Pass `generate_vectors=False` for precomputed vectors, or configure an
83
+ `embedding_generator` for local generation. `get()` excludes vector columns by
84
+ default; pass `include_vectors=True` to restore them. `get(keys)` preserves
85
+ requested key order and duplicates, omitting missing keys; filtered retrieval
86
+ supports `top`, `skip`, and `order_by`. Both `get()` and `search()` execute
87
+ portable filters and paging in Oracle. The
88
+ [runnable sample](https://github.com/microsoft/agent-framework/blob/main/python/packages/oracle/samples/oracle_vectors.py)
89
+ creates and deletes a unique test table.
90
+
91
+ ## Capabilities and limits
92
+
93
+ - A collection is one table in the **current user's schema**. Keys are
94
+ application-provided strings (up to 512 UTF-8 bytes), signed 64-bit integers,
95
+ or UUIDs; automatically generated keys are not supported.
96
+ - Multiple nullable native vector columns are supported. Vector fields may
97
+ declare `float`/`float32` (Oracle `FLOAT32`), `float64` (`FLOAT64`), or `int8`
98
+ (`INT8`); omitted element types use `FLOAT32`. Dimensions must be 1–65535.
99
+ Supplied vectors must be dense finite numeric sequences with the declared
100
+ dimensions. Binary and sparse vectors are not supported.
101
+ - Scalar data fields support `str` (up to 4000 UTF-8 bytes), `int` (signed
102
+ 64-bit), `float` (`BINARY_DOUBLE`), and `bool` (stored as `NUMBER(1,0)`).
103
+ Oracle converts empty strings to `NULL`, so this connector rejects empty
104
+ string **values** rather than changing their meaning. JSON fields, nested
105
+ paths, provider annotations, data/full-text/vector indexes, and schema
106
+ migration are not supported.
107
+ - Search uses Oracle `VECTOR_DISTANCE` with an explicit metric. The default
108
+ is `COSINE` **distance**; `cosine_similarity`, Euclidean distance, dot
109
+ product, negative dot product, squared Euclidean distance, and Manhattan
110
+ distance are also available. Scores are native
111
+ metric values, **not probabilities**. For distances a `score_threshold` is
112
+ a maximum; for similarities/dot product it is a minimum. The cutoff is
113
+ applied in SQL **before** paging. No ANN indexes are created or managed;
114
+ Oracle may use an existing index if the table already has one. There is no
115
+ exact/approximate toggle, server-side embedding generation, or
116
+ keyword-hybrid search. Index-selected approximate searches may return fewer
117
+ than the requested number of results.
118
+ - Portable filters support scalar equality (including `NULL` and boolean
119
+ distinctions), `in`/`not_in`, numeric ranges, `is_null`, `is_not_null`,
120
+ `exists`, literal text `contains_text`/`starts_with`/`ends_with`, and
121
+ AND/OR/NOT. Finite `Decimal` values are supported for exact numeric equality
122
+ and membership; malformed UUID filter values compare as unequal.
123
+ Collection membership and nested filters are rejected.
124
+ Ordered filters on integer fields reject non-integral float operands;
125
+ ordered `Decimal` operands are not supported.
126
+ String comparison follows the configured Oracle collation. Input values
127
+ are bound; identifiers are checked and quoted as individual names.
128
+
129
+ ## Opt-in database tests
130
+
131
+ The unit tests require no Oracle server. To run the live integration test,
132
+ provide **all three** `ORACLE_TEST_DSN`, `ORACLE_TEST_USER`, and
133
+ `ORACLE_TEST_PASSWORD` for an explicitly designated disposable Oracle 23ai+
134
+ schema where the user can create and drop tables:
135
+
136
+ ```bash
137
+ cd python
138
+ uv run --package agent-framework-oracle pytest packages/oracle/tests \
139
+ -m integration
140
+ ```
141
+
142
+ Without those variables, the integration test skips; it never falls back to
143
+ ordinary application credentials. The fixture creates a unique table and
144
+ deletes only that table.
145
+
146
+ ## Documentation
147
+
148
+ - [Oracle Database AI Vector Search requirements](https://docs.oracle.com/en/database/oracle/oracle-database/26/vecse/overview-ai-vector-search.html)
149
+ - [python-oracledb 2.2 vector types](https://python-oracledb.readthedocs.io/en/v2.2.0/user_guide/vector_data_type.html)
150
+ - [Microsoft Agent Framework](https://learn.microsoft.com/agent-framework/)
@@ -0,0 +1,16 @@
1
+ # Copyright (c) Microsoft. All rights reserved.
2
+
3
+ """Oracle Database 23ai native-vector collections and stores."""
4
+
5
+ from __future__ import annotations
6
+
7
+ import importlib.metadata
8
+
9
+ from ._vector_store import OracleCollection, OracleSettings, OracleStore
10
+
11
+ try:
12
+ __version__ = importlib.metadata.version(__name__)
13
+ except importlib.metadata.PackageNotFoundError:
14
+ __version__ = "0.0.0"
15
+
16
+ __all__ = ["OracleCollection", "OracleSettings", "OracleStore", "__version__"]