* feat(python): Add embedding abstractions and OpenAI implementation (Phase 1) This PR contains two parts: 1. **Overall migration plan** for porting vector stores and embeddings from Semantic Kernel to Agent Framework (docs/features/vector-stores-and-embeddings/README.md) covering all 10 phases from core abstractions through connectors and TextSearch. 2. **Phase 1 implementation** — core embedding abstractions and OpenAI/Azure OpenAI embedding clients: Core types (_types.py): - EmbeddingGenerationOptions TypedDict (total=False) - Embedding[EmbeddingT] generic class with model_id, dimensions, created_at - GeneratedEmbeddings[EmbeddingT, EmbeddingOptionsT] list container with options, usage - EmbeddingInputT (default str) and EmbeddingT (default list[float]) TypeVars Protocol + base class (_clients.py): - SupportsGetEmbeddings protocol — Generic[EmbeddingInputT, EmbeddingT, OptionsContraT] - BaseEmbeddingClient ABC — Generic[EmbeddingInputT, EmbeddingT, OptionsCoT] Telemetry (observability.py): - EmbeddingTelemetryLayer with gen_ai.operation.name = "embeddings" OpenAI implementation (openai/_embedding_client.py): - RawOpenAIEmbeddingClient, OpenAIEmbeddingClient, OpenAIEmbeddingOptions - Uses _ensure_client() factory pattern Azure OpenAI implementation (azure/_embedding_client.py): - AzureOpenAIEmbeddingClient following AzureOpenAIChatClient pattern - Supports API key, Entra ID credentials, env var configuration Tests: - 47 unit tests for types, protocol, base class, OpenAI, and Azure clients - 6 integration tests (gated behind RUN_INTEGRATION_TESTS + credentials) Samples: - samples/02-agents/embeddings/openai_embeddings.py - samples/02-agents/embeddings/azure_openai_embeddings.py Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix: Add AzureOpenAIEmbeddingClient to azure __init__.pyi stub Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * ci: Add embedding env vars to Python integration tests Map OPENAI_EMBEDDING_MODEL_ID and AZURE_OPENAI_EMBEDDING_DEPLOYMENT_NAME from GitHub vars to the integration test environment. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix: Handle base64 encoding_format in OpenAI embedding client When encoding_format='base64' is used, the OpenAI API returns base64-encoded floats instead of a JSON array. Decode these automatically to list[float] so the return type stays consistent regardless of encoding format. Also adds a unit test for base64 decoding and fixes minor docstring/import issues. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix: Only record INPUT_TOKENS for embedding telemetry Embeddings have no output/completion tokens. Remove OUTPUT_TOKENS recording which was double-counting prompt_tokens via the total_tokens fallback. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix: Resolve mypy variance error and lint warning Use contravariant/covariant TypeVars for SupportsGetEmbeddings Protocol. Combine nested if into single statement in telemetry layer. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix: Make EmbeddingCoT invariant for mypy compatibility GeneratedEmbeddings is invariant in its type param, so the Protocol TypeVar cannot be covariant. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix: Address PR review - empty values guard, service_url for telemetry - Add early return for empty values in get_embeddings to avoid unnecessary API calls - Add service_url() method to RawOpenAIEmbeddingClient for proper telemetry endpoint reporting - Add test for empty values behavior Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Python: Fix OpenAI chat client compatibility with third-party endpoints and OTel 0.4.14 (#4161) * Fix system message content sent as list instead of string Some OpenAI-compatible endpoints (e.g. NVIDIA NIM) reject system messages when content is a list of content parts. This change flattens system and developer message content to a plain string in the Chat Completions client. Fixes https://github.com/microsoft/agent-framework/issues/1407 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fix compatibility with opentelemetry-semantic-conventions-ai 0.4.14 Version 0.4.14 removed several LLM_* attributes from SpanAttributes (LLM_SYSTEM, LLM_REQUEST_MODEL, LLM_RESPONSE_MODEL, LLM_REQUEST_MAX_TOKENS, LLM_REQUEST_TEMPERATURE, LLM_REQUEST_TOP_P, LLM_TOKEN_TYPE). Move these to the OtelAttr enum with their well-known gen_ai.* string values and update all references in observability.py and tests. Fixes https://github.com/microsoft/agent-framework/issues/4160 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Flatten text-only message content to string for all roles Extend the system/developer fix to all message roles. Text-only content lists are now post-processed into plain strings, while multimodal content (text + images/audio) remains as a list. This fixes compatibility with OpenAI-like endpoints that cannot deserialize list content (e.g. Foundry Local's Neutron backend). Partially fixes https://github.com/microsoft/agent-framework/issues/4084 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fix streaming text lost when usage data in same chunk Some providers (e.g. Gemini) include both usage data and text content in the same streaming chunk. The early return on chunk.usage caused text and tool call parsing to be skipped entirely. Remove the early return and process usage alongside text/tool calls. Fixes https://github.com/microsoft/agent-framework/issues/3434 Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * Fix mypy errors in _chat_client.py Rename shadowed variable 'args' in system/developer branch to 'sys_args' and rename loop variable 'content' to 'msg_content' to avoid type conflict. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * reorder imports * fix: Use OtelAttr.REQUEST_MODEL instead of removed SpanAttributes.LLM_REQUEST_MODEL Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * docs: Add score_threshold to vector store plan Reference SK .NET PR #13501 for score threshold filtering semantics. Include score_threshold in SearchOptions from Phase 3. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * docs: Add reference to roji's SK .NET MEVD work for SQL connectors Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> * fix: Clear env vars in construction tests to avoid CI leakage Tests for missing API key / model ID now use monkeypatch.delenv to ensure env vars from the integration test environment don't prevent the expected ValueError from being raised. Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com> --------- Co-authored-by: Copilot <223556219+Copilot@users.noreply.github.com>
Vector Stores and Embeddings
Overview
This feature ports the vector store abstractions, embedding generator abstractions, and their implementations from Semantic Kernel into Agent Framework. The ported code follows AF's coding standards, feels native to AF, and is structured to allow data models/schemas to be reusable across both frameworks. The embedding abstraction combines the best of SK's EmbeddingGeneratorBase and MEAI's IEmbeddingGenerator<TInput, TEmbedding>.
| Capability | Description |
|---|---|
| Embedding generation | Generic embedding client abstraction supporting text, image, and audio inputs |
| Vector store collections | CRUD operations on vector store collections (upsert, get, delete) |
| Vector search | Unified search interface with search_type parameter ("vector", "keyword_hybrid") |
| Data model decorator | @vectorstoremodel decorator for defining vector store data models (supports Pydantic, dataclasses, plain classes, dicts) |
| Agent tools | create_search_tool, create_upsert_tool, create_get_tool, create_delete_tool for agent-usable vector store operations |
| In-memory store | Zero-dependency vector store for testing and development |
| 13+ connectors | Azure AI Search, Qdrant, Redis, PostgreSQL, MongoDB, Cosmos DB, Pinecone, Chroma, Weaviate, Oracle, SQL Server, FAISS |
Key Design Decisions
Embedding Abstractions (combining SK + MEAI)
- Both Protocol and Base class (matching AF's
SupportsChatGetResponse+BaseChatClientpattern):SupportsGetEmbeddings— Protocol for duck-typingBaseEmbeddingClient— ABC base class for implementations (similar toBaseChatClient)
- Generic input type (
EmbeddingInputT, defaultstr) from MEAI — allows image/audio embeddings in the future - Generic output type (
EmbeddingT, defaultlist[float]) from MEAI — supportslist[float],list[int],bytes, etc. - Generic order:
[EmbeddingInputT, EmbeddingT, EmbeddingOptionsT]— options last, matching MEAI'sIEmbeddingGenerator<TInput, TEmbedding>with options appended - TypeVar naming convention: Use
SuffixTper AF standard (e.g.,EmbeddingInputT,EmbeddingT,ModelT,KeyT) EmbeddingGenerationOptionsTypedDict (inspired by MEAI, matching AF'sChatOptionspattern) —total=False, includesdimensions,model_id. Noadditional_propertiessince each implementation extends with its own fields.- Protocol and base class are generic over input, output, and options:
SupportsGetEmbeddings[EmbeddingInputT, EmbeddingT, OptionsContraT],BaseEmbeddingClient[EmbeddingInputT, EmbeddingT, OptionsCoT] Embedding[EmbeddingT]type in_types.py— a lightweight generic class (not Pydantic) withvector: EmbeddingT,model_id: str | None,dimensions: int | None(explicit or computed from vector),created_at: datetime | None,additional_properties: dict[str, Any]GeneratedEmbeddings[EmbeddingT, EmbeddingOptionsT]type — a list-like container ofEmbedding[EmbeddingT]objects withoptions: EmbeddingOptionsT | None(stores the options used to generate),usage: dict[str, Any] | None,additional_properties: dict[str, Any]- No numpy dependency — return
list[float]by default; users cast as needed
Vector Store Abstractions
- Port core abstractions without Pydantic for internal classes — use plain classes
- Both Protocol and Base class for vector store operations (matching AF pattern):
SupportsVectorUpsert/SupportsVectorSearch— Protocols for duck-typing (followsSupports<Capability>naming convention)BaseVectorCollection/BaseVectorSearch— ABC base classes for implementationsBaseVectorStore— ABC base class for store operations (factory for collections, no protocol needed)
- TypeVar naming convention:
ModelT,KeyT,FilterT(suffix T, per AF standard) - Support Pydantic for user-facing data models — the
@vectorstoremodeldecorator andVectorStoreCollectionDefinitionshould work with Pydantic models, dataclasses, plain classes, and dicts - Remove SK-specific dependencies — no
KernelBaseModel,KernelFunction,KernelParameterMetadata,kernel_function,PromptExecutionSettings - Embedding types in
_types.py, embedding protocol/base class in_clients.py - All vector store specific types, enums, protocols, base classes in
_vectors.py - Error handling uses AF's exception hierarchy (e.g.,
IntegrationExceptionvariants)
Package Structure
- Embedding types (
Embedding,GeneratedEmbeddings,EmbeddingGenerationOptions) inagent_framework/_types.py - Embedding protocol + base class (
SupportsGetEmbeddings,BaseEmbeddingClient) inagent_framework/_clients.py - All vector store specific code in a new
agent_framework/_vectors.pymodule — this includes:- Enums:
FieldTypes,IndexKind,DistanceFunction VectorStoreField,VectorStoreCollectionDefinitionSearchOptions,SearchResponse,RecordFilterOptions@vectorstoremodeldecorator- Serialization/deserialization protocols
VectorStoreRecordHandler,BaseVectorCollection,BaseVectorStore,BaseVectorSearchSupportsVectorUpsert,SupportsVectorSearchprotocols
- Enums:
- OpenAI embeddings in
agent_framework/openai/(built into core, like OpenAI chat) - Azure OpenAI embeddings in
agent_framework/azure/(built into core, followsAzureOpenAIChatClientpattern) - Each vector store connector in its own AF package under
packages/ - In-memory store in core (no external deps)
- TextSearch and its implementations (Brave, Google) — last phase, separate work
Naming: SK → AF
Names that change
| SK Name | AF Name | Rationale |
|---|---|---|
VectorStoreCollection |
BaseVectorCollection |
Drop redundant Store, add Base prefix per AF pattern |
VectorStore |
BaseVectorStore |
Add Base prefix per AF pattern |
VectorSearch |
BaseVectorSearch |
Add Base prefix per AF pattern |
VectorSearchOptions |
SearchOptions |
Shorter — context is already vector search |
VectorSearchResult |
SearchResponse |
Align with ChatResponse/AgentResponse |
GetFilteredRecordOptions |
RecordFilterOptions |
Shorter, more natural |
EmbeddingGeneratorBase |
BaseEmbeddingClient |
Matches AF BaseChatClient pattern |
VectorStoreCollectionProtocol |
SupportsVectorUpsert |
AF Supports* naming convention |
VectorSearchProtocol |
SupportsVectorSearch |
AF Supports* naming convention |
__kernel_vectorstoremodel__ |
__vectorstoremodel__ |
Drop SK kernel prefix |
__kernel_vectorstoremodel_definition__ |
__vectorstoremodel_definition__ |
Drop SK kernel prefix |
search() + hybrid_search() |
search(search_type=...) |
Single method with Literal parameter |
SearchType enum |
Literal["vector", "keyword_hybrid"] |
No enum, just a literal |
KernelSearchResults |
SearchResults |
Drop SK Kernel prefix (plural — container of SearchResponse items) |
Names that stay the same
| Name | Location |
|---|---|
@vectorstoremodel |
_vectors.py |
VectorStoreField |
_vectors.py |
VectorStoreCollectionDefinition |
_vectors.py |
VectorStoreRecordHandler |
_vectors.py |
FieldTypes |
_vectors.py |
IndexKind |
_vectors.py |
DistanceFunction |
_vectors.py |
DISTANCE_FUNCTION_DIRECTION_HELPER |
_vectors.py |
Embedding |
_types.py |
GeneratedEmbeddings |
_types.py |
EmbeddingGenerationOptions |
_types.py |
SupportsGetEmbeddings |
_clients.py |
New AF-only names (no SK equivalent)
| Name | Location | Purpose |
|---|---|---|
BaseEmbeddingClient |
_clients.py |
ABC base for embedding implementations |
EmbeddingInputT |
_types.py |
TypeVar for generic embedding input (default str) |
EmbeddingTelemetryLayer |
observability.py |
MRO-based OTel tracing for embeddings |
SupportsVectorUpsert |
_vectors.py |
Protocol for collection CRUD |
SupportsVectorSearch |
_vectors.py |
Protocol for vector search |
create_search_tool |
_vectors.py |
Creates AF FunctionTool from vector search |
Source Files Reference (SK → AF mapping)
SK Source Files
| SK File | Lines | Content |
|---|---|---|
data/vector.py |
2369 | All vector store abstractions, enums, decorator, search |
data/_shared.py |
184 | SearchOptions, KernelSearchResults, shared search types |
data/text_search.py |
349 | TextSearch base, TextSearchResult |
connectors/ai/embedding_generator_base.py |
50 | EmbeddingGeneratorBase ABC |
connectors/in_memory.py |
520 | InMemoryCollection, InMemoryStore |
connectors/azure_ai_search.py |
793 | Azure AI Search collection + store |
connectors/azure_cosmos_db.py |
1104 | Cosmos DB (Mongo + NoSQL) |
connectors/redis.py |
845 | Redis (Hashset + JSON) |
connectors/qdrant.py |
653 | Qdrant collection + store |
connectors/postgres.py |
987 | PostgreSQL collection + store |
connectors/mongodb.py |
633 | MongoDB Atlas collection + store |
connectors/pinecone.py |
691 | Pinecone collection + store |
connectors/chroma.py |
484 | Chroma collection + store |
connectors/faiss.py |
278 | FAISS (extends InMemory) |
connectors/weaviate.py |
804 | Weaviate collection + store |
connectors/oracle.py |
1267 | Oracle collection + store |
connectors/sql_server.py |
1132 | SQL Server collection + store |
connectors/ai/open_ai/services/open_ai_text_embedding.py |
91 | OpenAI embedding impl |
connectors/ai/open_ai/services/open_ai_text_embedding_base.py |
78 | OpenAI embedding base |
connectors/brave.py |
~200 | Brave TextSearch impl |
connectors/google_search.py |
~200 | Google TextSearch impl |
Implementation Phases
Phase 1: Core Embedding Abstractions & OpenAI Implementation
Goal: Establish the embedding generator abstraction and ship one working implementation. Mergeable: Yes — adds new types/protocols, no breaking changes.
1.1 — Embedding types in _types.py
EmbeddingInputTTypeVar (defaultstr) — generic input type for embedding generationEmbeddingTTypeVar (defaultlist[float]) — generic output embedding vector typeEmbedding[EmbeddingT]generic class:vector: EmbeddingT,model_id: str | None,dimensions: int | None(explicit param or computed from vector length),created_at: datetime | None,additional_properties: dict[str, Any]GeneratedEmbeddings[EmbeddingT, EmbeddingOptionsT]generic class: list-like container ofEmbedding[EmbeddingT]objects withoptions: EmbeddingOptionsT | None(the options used to generate),usage: dict[str, Any] | None,additional_properties: dict[str, Any]EmbeddingGenerationOptionsTypedDict (total=False):dimensions: int,model_id: str— follows the same pattern asChatOptions. Noadditional_propertiesneeded since it's a TypedDict and each implementation can extend with its own fields.
1.2 — Embedding generator protocol + base class in _clients.py
SupportsGetEmbeddings(Protocol[EmbeddingInputT, EmbeddingT, OptionsContraT]): generic over input, output, and options (all with defaults),get_embeddings(values: Sequence[EmbeddingInputT], *, options: OptionsContraT | None = None) -> Awaitable[GeneratedEmbeddings[EmbeddingT]]BaseEmbeddingClient(ABC, Generic[EmbeddingInputT, EmbeddingT, OptionsCoT]): ABC base class mirroringBaseChatClientpattern__init__withadditional_properties, etc.- Abstract
get_embeddings(...)for subclasses to implement directly (no_inner_*indirection — simpler than chat, no middleware needed)
EmbeddingTelemetryLayerinobservability.py— MRO-based telemetry (no closure),gen_ai.operation.name = "embeddings"
1.3 — OpenAI embedding generator in agent_framework/openai/ and agent_framework/azure/
RawOpenAIEmbeddingClient— implementsget_embeddingsvia_ensure_client()factoryOpenAIEmbeddingClient(OpenAIConfigMixin, EmbeddingTelemetryLayer[str, list[float], OptionsT], RawOpenAIEmbeddingClient[OptionsT])— full client with config + telemetry layersOpenAIEmbeddingOptions(EmbeddingGenerationOptions)— extends withencoding_format,userAzureOpenAIEmbeddingClientinagent_framework/azure/— followsAzureOpenAIChatClientpattern withAzureOpenAIConfigMixin,load_settings, Entra ID credential supportAzureOpenAISettingsextended withembedding_deployment_name(env var:AZURE_OPENAI_EMBEDDING_DEPLOYMENT_NAME)
1.4 — Tests and samples
- Unit tests for types, protocol, base class, OpenAI client, Azure OpenAI client
- Integration tests for OpenAI and Azure OpenAI (gated behind
RUN_INTEGRATION_TESTS+ credentials,@pytest.mark.flaky) - Samples in
samples/02-agents/embeddings/—openai_embeddings.py,azure_openai_embeddings.py
Phase 2: Embedding Generators for Existing Providers
Goal: Add embedding generators to all existing AF provider packages that have chat clients. Mergeable: Yes — each is independent, added to existing provider packages.
2.1 — Azure AI Inference embedding (in packages/azure-ai/)
2.2 — Ollama embedding (in packages/ollama/)
2.3 — Anthropic embedding (in packages/anthropic/)
2.4 — Bedrock embedding (in packages/bedrock/)
Phase 3: Core Vector Store Abstractions
Goal: Establish all vector store types, enums, the decorator, collection definition, and base classes. Mergeable: Yes — adds new abstractions, no breaking changes.
3.1 — Vector store enums and field types in _vectors.py
FieldTypesenum:KEY,VECTOR,DATAIndexKindenum:HNSW,FLAT,IVF_FLAT,DISK_ANN,QUANTIZED_FLAT,DYNAMIC,DEFAULTDistanceFunctionenum:COSINE_SIMILARITY,COSINE_DISTANCE,DOT_PROD,EUCLIDEAN_DISTANCE,EUCLIDEAN_SQUARED_DISTANCE,MANHATTAN,HAMMING,DEFAULT- No
SearchTypeenum — useLiteral["vector", "keyword_hybrid"]instead, per AF convention of avoiding unnecessary imports VectorStoreFieldplain class (not Pydantic)VectorStoreCollectionDefinitionclass (not Pydantic internally, but supports Pydantic models as input)SearchOptionsplain class — includesscore_threshold: float | Nonefor filtering results by score (see note below)SearchResponsegeneric classRecordFilterOptionsplain classDISTANCE_FUNCTION_DIRECTION_HELPERdict
3.2 — @vectorstoremodel decorator
- Port from SK, works with dataclasses, Pydantic models, plain classes, and dicts
- Sets
__vectorstoremodel__and__vectorstoremodel_definition__on the class - Remove SK-specific
kernelprefix (__kernel_vectorstoremodel__→__vectorstoremodel__)
3.3 — Serialization/deserialization protocols
SerializeMethodProtocol,ToDictFunctionProtocol,FromDictFunctionProtocol, etc.- Port the record handler logic but without Pydantic base class — use plain class or ABC
3.4 — Vector store base classes in _vectors.py
VectorStoreRecordHandler— internal base class that handles serialization/deserialization between user data models and store-specific formats, plus embedding generation for vector fields. BothBaseVectorCollectionandBaseVectorSearchextend this.BaseVectorCollection(VectorStoreRecordHandler)— base for collections- Uses
SupportsGetEmbeddingsinstead ofEmbeddingGeneratorBase - Not a Pydantic model — use
__init__with explicit params upsert,get,delete,ensure_collection_exists,collection_exists,ensure_collection_deleted- Async context manager support
- Uses
BaseVectorStore— base for storesget_collection,list_collection_names,collection_exists,ensure_collection_deleted- Async context manager support
3.5 — Vector search base class
BaseVectorSearch(VectorStoreRecordHandler)— base for vector search- Single
search(search_type=...)method withsearch_type: Literal["vector", "keyword_hybrid"]parameter — no enum, just a literal _inner_searchabstract method for implementations- Filter building with lambda parser (AST-based)
- Vector generation from values using embedding generator
- Single
3.6 — Protocols for type checking
SupportsVectorUpsert— Protocol for upsert/get/delete operationsSupportsVectorSearch— Protocol for vector search (singlesearch()withsearch_typeparameter)- No separate
SupportsVectorHybridSearch— search type is a parameter, not a separate capability - No protocol for
VectorStore— it's a factory for collections, not a capability to duck-type against
3.7 — Exception types
- Add vector store exceptions under
IntegrationExceptionor create new branch VectorStoreException,VectorStoreOperationException,VectorSearchException,VectorStoreModelException, etc.
3.8 — create_search_tool on BaseVectorSearch
- Method on
BaseVectorSearchthat creates an AFFunctionToolfrom the vector search - Wraps the single
search()method, passingsearch_typeparameter - Accepts:
name,description,search_type,top,skip,filter,string_mapper - The tool takes a query string, vectorizes it, searches, and returns results as strings
- Can also be a standalone factory function in
_vectors.py
3.9 — Tests for all vector store abstractions
- Unit tests for enums, field types, collection definition
- Unit tests for decorator
- Unit tests for serialization/deserialization
- Unit tests for record handler
Phase 4: In-Memory Vector Store
Goal: Provide a zero-dependency vector store for testing and development. Mergeable: Yes — first usable vector store.
4.1 — Port InMemoryCollection and InMemoryStore into core
- Place in
agent_framework/_vectors.py(alongside the abstractions) - Supports vector search (cosine similarity, etc.)
- No external dependencies
4.2 — Port FAISS extension (optional, can be separate package)
- Extends InMemory with FAISS indexing
4.3 — Tests and sample code
Phase 5: Vector Store Connectors — Tier 1 (High Priority)
Goal: Ship the most commonly used vector store connectors. Mergeable: Yes — each connector is independent.
Each connector follows the AF package structure:
- New package under
packages/ - Own
pyproject.toml,tests/, lazy loading in core
5.1 — Azure AI Search (packages/azure-ai-search/)
- May extend existing package or be new
AzureAISearchCollection,AzureAISearchStore
5.2 — Qdrant (packages/qdrant/)
- New package
QdrantCollection,QdrantStore
5.3 — Redis (packages/redis/)
- May extend existing redis package
RedisCollection(JSON + Hashset variants),RedisStore
5.4 — PostgreSQL/pgvector (packages/postgres/)
- New package
PostgresCollection,PostgresStore
Phase 6: Vector Store Connectors — Tier 2
Goal: Ship remaining vector store connectors. Mergeable: Yes — each connector is independent.
6.1 — MongoDB Atlas (packages/mongodb/)
6.2 — Azure Cosmos DB (packages/azure-cosmos-db/)
- Cosmos Mongo + Cosmos NoSQL
6.3 — Pinecone (packages/pinecone/)
6.4 — Chroma (packages/chroma/)
6.5 — Weaviate (packages/weaviate/)
Phase 7: Vector Store Connectors — Tier 3
Goal: Ship niche or less common connectors. Mergeable: Yes — each connector is independent.
7.1 — Oracle (packages/oracle/)
7.2 — SQL Server (packages/sql-server/)
7.3 — FAISS (packages/faiss/ or in core extending InMemory)
Note: When implementing any SQL-based connector (PostgreSQL, SQL Server, SQLite, Cosmos DB), review the .NET MEVD changes made by @roji (Shay Rojansky) in SK for design patterns, query building, filter translation, and feature parity: https://github.com/microsoft/semantic-kernel/pulls?q=is%3Apr+author%3Aroji+is%3Aclosed
Phase 8: Vector Store CRUD Tools
Goal: Provide a full set of agent-usable tools for CRUD operations on vector store collections. Mergeable: Yes — adds tools without changing existing APIs.
8.1 — create_upsert_tool — tool for upserting records into a collection
8.2 — create_get_tool — tool for retrieving records by key
- Key-based lookup only (by primary key), not a search tool
- Documentation must clearly distinguish this from
create_search_tool: get_tool retrieves specific records by their known key, while search_tool performs similarity/filtered search across the collection - Consider if this overlaps with filtered search and document when to use which
8.3 — create_delete_tool — tool for deleting records by key
8.4 — Tests and samples for CRUD tools
Phase 9: Additional Embedding Implementations (New Providers)
Goal: Provide embedding generators for providers that don't yet have AF packages. Mergeable: Yes — each is independent, new packages.
9.1 — HuggingFace/ONNX embedding (new package or lab)
9.2 — Mistral AI embedding (new package)
9.3 — Google AI / Vertex AI embedding (new package)
9.4 — Nvidia embedding (new package)
Phase 10: TextSearch Abstractions & Implementations (Separate Work)
Goal: Port text search (non-vector) abstractions and implementations. Mergeable: Yes — independent of vector stores.
10.1 — TextSearch base class and types
SearchOptions,SearchResponse,TextSearchResultTextSearchbase class withsearch()methodcreate_search_function()for kernel integration (may need AF equivalent)
10.2 — Brave Search implementation
10.3 — Google Search implementation
10.4 — Vector store text search bridge (connecting VectorSearch to TextSearch interface)
Key Considerations
-
No Pydantic for internal classes: All AF internal classes should use plain classes. Pydantic is only used for user-facing input validation (e.g., vector store data models).
-
Protocol + Base class: Follow AF's pattern of both a
Protocolfor duck-typing and aBaseABC for implementation, matching howSupportsChatGetResponse+BaseChatClientworks. -
Exception hierarchy: Use AF's
IntegrationExceptionbranch for vector store operations, since vector stores are external dependencies. -
from __future__ import annotations: Required in all files per AF coding standard. -
No
**kwargsescape hatches in public APIs: For user-facing interfaces, use explicit named parameters per AF coding standard. Internal implementation details (e.g., cooperative multiple inheritance / MRO patterns) may use**kwargswhere necessary, as long as they are not exposed in public signatures. -
Lazy loading: Connector packages use
__getattr__lazy loading in core provider folders. -
Reusable data models: The
@vectorstoremodeldecorator andVectorStoreCollectionDefinitionshould be agnostic enough to work with both SK and AF. The core types (FieldTypes,IndexKind,DistanceFunction,VectorStoreField) should be identical or easily mapped. -
create_search_tool: The AF-native equivalent of SK'screate_search_function. Instead of creating aKernelFunction, this creates an AFFunctionTool(via the@tooldecorator pattern) from a vector search. This allows agents to use vector search as a tool during conversations. Design:create_search_tool(name, description, search_type, ...)→ returns aFunctionToolthat wrapsVectorSearch.search(search_type=...)- The tool accepts a query string, performs embedding + vector search, and returns results as strings
- Supports configurable string mappers, filter functions, top/skip defaults
- Lives in
_vectors.pyas a method onBaseVectorSearchand/or as a standalone factory function
-
CRUD tools: A full set of create/read/update/delete tools for vector store collections, allowing agents to manage data in vector stores. Design:
create_upsert_tool(...)→ tool for upserting recordscreate_get_tool(...)→ tool for retrieving records by keycreate_delete_tool(...)→ tool for deleting records- These are separate from search and are placed in a later phase
-
Score threshold filtering:
SearchOptionsincludesscore_threshold: float | Noneto filter search results by relevance score (ref: SK .NET PR #13501). The semantics depend on the distance function: for similarity functions (cosine similarity, dot product), results below the threshold are filtered out; for distance functions (cosine distance, euclidean), results above the threshold are filtered out. UseDISTANCE_FUNCTION_DIRECTION_HELPERto determine direction. Connectors should implement this natively where the database supports it, falling back to client-side post-filtering otherwise.