agent-framework-postgres 0.0.0a1__tar.gz → 1.0.0a260910__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,166 @@
1
+ Metadata-Version: 2.4
2
+ Name: agent-framework-postgres
3
+ Version: 1.0.0a260910
4
+ Summary: PostgreSQL and pgvector integration 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.18.0,<2
20
+ Requires-Dist: psycopg[binary, pool]>=3.3.5,<4
21
+ Requires-Dist: pgvector>=0.5.0,<0.6
22
+ Project-URL: homepage, https://aka.ms/agent-framework
23
+ Project-URL: issues, https://github.com/microsoft/agent-framework/issues
24
+ Project-URL: source, https://github.com/microsoft/agent-framework/tree/main/python
25
+
26
+ # Agent Framework PostgreSQL / pgvector
27
+
28
+ Store and search vector records in PostgreSQL with this alpha integration for
29
+ [Microsoft Agent Framework](https://learn.microsoft.com/agent-framework/).
30
+ The package uses Psycopg 3 and the official pgvector Python adapter.
31
+
32
+ - **`PostgresCollection`** provides batch upsert, retrieval, deletion, and vector similarity search.
33
+ - **`PostgresStore`** creates collection clients that share a connection pool.
34
+ - **`PostgresSettings`** describes connection settings resolved by Agent Framework.
35
+
36
+ ## Installation
37
+
38
+ ```bash
39
+ pip install agent-framework-postgres --pre
40
+ ```
41
+
42
+ Requires Python 3.10+, PostgreSQL 13+, and pgvector 0.8.0+.
43
+ Import the connector directly from `agent_framework_postgres`.
44
+
45
+ ## Connection setup
46
+
47
+ Have your database administrator install and enable the `vector` extension and
48
+ provide an existing schema. The extension must be visible through the connection's
49
+ `search_path`. The connector never creates schemas, enables extensions, or changes
50
+ server-wide configuration. `ensure_collection_exists()` explicitly creates the
51
+ table and requested indexes; it requires the corresponding permissions and does
52
+ not migrate existing tables.
53
+
54
+ Set `POSTGRES_CONNECTION_STRING` to a PostgreSQL URI or Psycopg conninfo string,
55
+ or pass `connection_string` to either constructor. Both accept a string or AF
56
+ `SecretString`. Settings precedence is **explicit argument > selected `.env`
57
+ file > environment**. Select a file with `env_file_path` and optional
58
+ `env_file_encoding`; missing or empty connection strings are rejected.
59
+ The `schema` argument defaults to `public`.
60
+
61
+ A connector-created pool is closed by `close()` or an async context manager.
62
+ Alternatively, inject an open Psycopg `AsyncConnection` or `AsyncConnectionPool`
63
+ using `client`; it remains caller-owned and bypasses settings loading.
64
+ Injected clients cannot be combined with connection-string or `.env` options.
65
+ Collections created by a store borrow its pool, so keep the store open while
66
+ using them.
67
+
68
+ ## Example
69
+
70
+ With `POSTGRES_CONNECTION_STRING` configured, create a typed collection and
71
+ search using precomputed embeddings:
72
+
73
+ ```python
74
+ import asyncio
75
+ from dataclasses import dataclass
76
+ from typing import Annotated
77
+
78
+ from agent_framework import Filter, VectorStoreField, vectorstoremodel
79
+ from agent_framework_postgres import PostgresStore
80
+
81
+
82
+ @vectorstoremodel(collection_name="articles")
83
+ @dataclass
84
+ class Article:
85
+ id: Annotated[str, VectorStoreField("key")]
86
+ text: Annotated[str, VectorStoreField("data")]
87
+ embedding: Annotated[list[float] | None, VectorStoreField("vector", dimensions=3)] = None
88
+
89
+
90
+ async def main() -> None:
91
+ async with PostgresStore() as store:
92
+ collection = store.get_collection(Article)
93
+ await collection.ensure_collection_exists()
94
+ await collection.upsert(
95
+ [
96
+ Article("1", "PostgreSQL supports vectors", [1, 0, 0]),
97
+ Article("2", "A travel journal", [0, 1, 0]),
98
+ ],
99
+ generate_vectors=False,
100
+ )
101
+ results = await collection.search(
102
+ vector=[1, 0, 0],
103
+ filter=Filter("text", "contains_text", "PostgreSQL"),
104
+ score_threshold=0.25,
105
+ top=3,
106
+ )
107
+ async for result in results:
108
+ print(result["record"].text, result["score"])
109
+
110
+
111
+ if __name__ == "__main__":
112
+ asyncio.run(main())
113
+ ```
114
+
115
+ Pass `generate_vectors=False` to preserve supplied embeddings. To generate them
116
+ locally, configure an `embedding_generator`. Retrieval excludes embeddings by
117
+ default; use `include_vectors=True` to return them.
118
+
119
+ ## Capabilities and limits
120
+
121
+ The connector supports typed models, string/integer/UUID keys (including generated
122
+ keys), multiple nullable vector columns, storage aliases, and database-side
123
+ filters and paging. Batch writes are transactional; an existing transaction on
124
+ an injected connection remains under the caller's commit control.
125
+
126
+ Vector fields support `float`, `float32`, and `float16` declarations. PostgreSQL
127
+ `vector` storage uses 32-bit floats; `float16` defaults to 16-bit `halfvec`.
128
+ The `postgres.vector_type` provider annotation explicitly selects either storage
129
+ type. Ordinary Python floats and integer-valued elements are accepted and rounded
130
+ to the selected precision; declared `int` and `float64` vector fields are rejected.
131
+
132
+ Storage precision does not determine the model's Python scalar type. The default
133
+ decoder returns ordinary Python floats: use `list[float]` annotations even with
134
+ explicit `float16` or `float32` field metadata. Models annotated with
135
+ `list[numpy.float16]` or `list[numpy.float32]` require a custom `decoder` passed to
136
+ `vectorstoremodel` or `register_vectorstoremodel`. That decoder must reconstruct
137
+ each component with the declared NumPy scalar type and handle omitted vector
138
+ fields when `include_vectors=False`. NumPy is not a connector runtime dependency.
139
+
140
+ Exact search is the default. HNSW and IVFFlat are optional approximate indexes;
141
+ selective filters can reduce their recall. Use
142
+ `operation_options={"exact": True}` when complete recall is required.
143
+ `exact=False` requires an HNSW or IVFFlat field. Result metadata's `approximate`
144
+ flag identifies ANN-permitted query mode, not proof that PostgreSQL used an ANN
145
+ index.
146
+ IVFFlat needs data before index creation: first call
147
+ `ensure_collection_exists(operation_options={"create_indexes": False})`, load
148
+ records, then call `ensure_collection_exists()` again.
149
+ Storage supports up to 16,000 dimensions; ANN indexes support up to 2,000 for
150
+ `vector` and 4,000 for `halfvec`.
151
+
152
+ Scores use the selected metric's units, not probabilities. The default is cosine
153
+ distance, where lower is better and `score_threshold` is a maximum. Cosine
154
+ similarity and dot product use minimum thresholds; negative dot product, L2, and
155
+ L1 distances use maximum thresholds. IVFFlat does not support L1.
156
+
157
+ Keyword/hybrid/full-text search, sparse/binary vectors, nested filter paths,
158
+ schema migration, and server-side embedding generation are not supported.
159
+
160
+ ## Documentation
161
+
162
+ - [Microsoft Agent Framework documentation](https://learn.microsoft.com/agent-framework/)
163
+ - [PostgreSQL documentation](https://www.postgresql.org/docs/current/)
164
+ - [pgvector setup, indexes, and distance functions](https://github.com/pgvector/pgvector)
165
+ - [Psycopg connection pools](https://www.psycopg.org/psycopg3/docs/advanced/pool.html)
166
+
@@ -0,0 +1,140 @@
1
+ # Agent Framework PostgreSQL / pgvector
2
+
3
+ Store and search vector records in PostgreSQL with this alpha integration for
4
+ [Microsoft Agent Framework](https://learn.microsoft.com/agent-framework/).
5
+ The package uses Psycopg 3 and the official pgvector Python adapter.
6
+
7
+ - **`PostgresCollection`** provides batch upsert, retrieval, deletion, and vector similarity search.
8
+ - **`PostgresStore`** creates collection clients that share a connection pool.
9
+ - **`PostgresSettings`** describes connection settings resolved by Agent Framework.
10
+
11
+ ## Installation
12
+
13
+ ```bash
14
+ pip install agent-framework-postgres --pre
15
+ ```
16
+
17
+ Requires Python 3.10+, PostgreSQL 13+, and pgvector 0.8.0+.
18
+ Import the connector directly from `agent_framework_postgres`.
19
+
20
+ ## Connection setup
21
+
22
+ Have your database administrator install and enable the `vector` extension and
23
+ provide an existing schema. The extension must be visible through the connection's
24
+ `search_path`. The connector never creates schemas, enables extensions, or changes
25
+ server-wide configuration. `ensure_collection_exists()` explicitly creates the
26
+ table and requested indexes; it requires the corresponding permissions and does
27
+ not migrate existing tables.
28
+
29
+ Set `POSTGRES_CONNECTION_STRING` to a PostgreSQL URI or Psycopg conninfo string,
30
+ or pass `connection_string` to either constructor. Both accept a string or AF
31
+ `SecretString`. Settings precedence is **explicit argument > selected `.env`
32
+ file > environment**. Select a file with `env_file_path` and optional
33
+ `env_file_encoding`; missing or empty connection strings are rejected.
34
+ The `schema` argument defaults to `public`.
35
+
36
+ A connector-created pool is closed by `close()` or an async context manager.
37
+ Alternatively, inject an open Psycopg `AsyncConnection` or `AsyncConnectionPool`
38
+ using `client`; it remains caller-owned and bypasses settings loading.
39
+ Injected clients cannot be combined with connection-string or `.env` options.
40
+ Collections created by a store borrow its pool, so keep the store open while
41
+ using them.
42
+
43
+ ## Example
44
+
45
+ With `POSTGRES_CONNECTION_STRING` configured, create a typed collection and
46
+ search using precomputed embeddings:
47
+
48
+ ```python
49
+ import asyncio
50
+ from dataclasses import dataclass
51
+ from typing import Annotated
52
+
53
+ from agent_framework import Filter, VectorStoreField, vectorstoremodel
54
+ from agent_framework_postgres import PostgresStore
55
+
56
+
57
+ @vectorstoremodel(collection_name="articles")
58
+ @dataclass
59
+ class Article:
60
+ id: Annotated[str, VectorStoreField("key")]
61
+ text: Annotated[str, VectorStoreField("data")]
62
+ embedding: Annotated[list[float] | None, VectorStoreField("vector", dimensions=3)] = None
63
+
64
+
65
+ async def main() -> None:
66
+ async with PostgresStore() as store:
67
+ collection = store.get_collection(Article)
68
+ await collection.ensure_collection_exists()
69
+ await collection.upsert(
70
+ [
71
+ Article("1", "PostgreSQL supports vectors", [1, 0, 0]),
72
+ Article("2", "A travel journal", [0, 1, 0]),
73
+ ],
74
+ generate_vectors=False,
75
+ )
76
+ results = await collection.search(
77
+ vector=[1, 0, 0],
78
+ filter=Filter("text", "contains_text", "PostgreSQL"),
79
+ score_threshold=0.25,
80
+ top=3,
81
+ )
82
+ async for result in results:
83
+ print(result["record"].text, result["score"])
84
+
85
+
86
+ if __name__ == "__main__":
87
+ asyncio.run(main())
88
+ ```
89
+
90
+ Pass `generate_vectors=False` to preserve supplied embeddings. To generate them
91
+ locally, configure an `embedding_generator`. Retrieval excludes embeddings by
92
+ default; use `include_vectors=True` to return them.
93
+
94
+ ## Capabilities and limits
95
+
96
+ The connector supports typed models, string/integer/UUID keys (including generated
97
+ keys), multiple nullable vector columns, storage aliases, and database-side
98
+ filters and paging. Batch writes are transactional; an existing transaction on
99
+ an injected connection remains under the caller's commit control.
100
+
101
+ Vector fields support `float`, `float32`, and `float16` declarations. PostgreSQL
102
+ `vector` storage uses 32-bit floats; `float16` defaults to 16-bit `halfvec`.
103
+ The `postgres.vector_type` provider annotation explicitly selects either storage
104
+ type. Ordinary Python floats and integer-valued elements are accepted and rounded
105
+ to the selected precision; declared `int` and `float64` vector fields are rejected.
106
+
107
+ Storage precision does not determine the model's Python scalar type. The default
108
+ decoder returns ordinary Python floats: use `list[float]` annotations even with
109
+ explicit `float16` or `float32` field metadata. Models annotated with
110
+ `list[numpy.float16]` or `list[numpy.float32]` require a custom `decoder` passed to
111
+ `vectorstoremodel` or `register_vectorstoremodel`. That decoder must reconstruct
112
+ each component with the declared NumPy scalar type and handle omitted vector
113
+ fields when `include_vectors=False`. NumPy is not a connector runtime dependency.
114
+
115
+ Exact search is the default. HNSW and IVFFlat are optional approximate indexes;
116
+ selective filters can reduce their recall. Use
117
+ `operation_options={"exact": True}` when complete recall is required.
118
+ `exact=False` requires an HNSW or IVFFlat field. Result metadata's `approximate`
119
+ flag identifies ANN-permitted query mode, not proof that PostgreSQL used an ANN
120
+ index.
121
+ IVFFlat needs data before index creation: first call
122
+ `ensure_collection_exists(operation_options={"create_indexes": False})`, load
123
+ records, then call `ensure_collection_exists()` again.
124
+ Storage supports up to 16,000 dimensions; ANN indexes support up to 2,000 for
125
+ `vector` and 4,000 for `halfvec`.
126
+
127
+ Scores use the selected metric's units, not probabilities. The default is cosine
128
+ distance, where lower is better and `score_threshold` is a maximum. Cosine
129
+ similarity and dot product use minimum thresholds; negative dot product, L2, and
130
+ L1 distances use maximum thresholds. IVFFlat does not support L1.
131
+
132
+ Keyword/hybrid/full-text search, sparse/binary vectors, nested filter paths,
133
+ schema migration, and server-side embedding generation are not supported.
134
+
135
+ ## Documentation
136
+
137
+ - [Microsoft Agent Framework documentation](https://learn.microsoft.com/agent-framework/)
138
+ - [PostgreSQL documentation](https://www.postgresql.org/docs/current/)
139
+ - [pgvector setup, indexes, and distance functions](https://github.com/pgvector/pgvector)
140
+ - [Psycopg connection pools](https://www.psycopg.org/psycopg3/docs/advanced/pool.html)
@@ -0,0 +1,16 @@
1
+ # Copyright (c) Microsoft. All rights reserved.
2
+
3
+ """Async PostgreSQL/pgvector vector collections and stores."""
4
+
5
+ from __future__ import annotations
6
+
7
+ import importlib.metadata
8
+
9
+ from ._vector_store import PostgresCollection, PostgresSettings, PostgresStore
10
+
11
+ try:
12
+ __version__ = importlib.metadata.version(__name__)
13
+ except importlib.metadata.PackageNotFoundError:
14
+ __version__ = "0.0.0"
15
+
16
+ __all__ = ["PostgresCollection", "PostgresSettings", "PostgresStore", "__version__"]