dao-ai 0.0.27__py3-none-any.whl → 0.0.29__py3-none-any.whl
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.
- dao_ai/agent_as_code.py +3 -0
- dao_ai/config.py +60 -0
- dao_ai/providers/databricks.py +7 -0
- dao_ai/tools/genie.py +2 -6
- dao_ai/tools/vector_search.py +232 -22
- dao_ai/utils.py +1 -0
- {dao_ai-0.0.27.dist-info → dao_ai-0.0.29.dist-info}/METADATA +5 -3
- {dao_ai-0.0.27.dist-info → dao_ai-0.0.29.dist-info}/RECORD +11 -11
- {dao_ai-0.0.27.dist-info → dao_ai-0.0.29.dist-info}/WHEEL +1 -1
- {dao_ai-0.0.27.dist-info → dao_ai-0.0.29.dist-info}/entry_points.txt +0 -0
- {dao_ai-0.0.27.dist-info → dao_ai-0.0.29.dist-info}/licenses/LICENSE +0 -0
dao_ai/agent_as_code.py
CHANGED
dao_ai/config.py
CHANGED
|
@@ -895,6 +895,55 @@ class SearchParametersModel(BaseModel):
|
|
|
895
895
|
query_type: Optional[str] = "ANN"
|
|
896
896
|
|
|
897
897
|
|
|
898
|
+
class RerankParametersModel(BaseModel):
|
|
899
|
+
"""
|
|
900
|
+
Configuration for reranking retrieved documents using FlashRank.
|
|
901
|
+
|
|
902
|
+
FlashRank provides fast, local reranking without API calls using lightweight
|
|
903
|
+
cross-encoder models. Reranking improves retrieval quality by reordering results
|
|
904
|
+
based on semantic relevance to the query.
|
|
905
|
+
|
|
906
|
+
Typical workflow:
|
|
907
|
+
1. Retrieve more documents than needed (e.g., 50 via num_results)
|
|
908
|
+
2. Rerank all retrieved documents
|
|
909
|
+
3. Return top_n best matches (e.g., 5)
|
|
910
|
+
|
|
911
|
+
Example:
|
|
912
|
+
```yaml
|
|
913
|
+
retriever:
|
|
914
|
+
search_parameters:
|
|
915
|
+
num_results: 50 # Retrieve more candidates
|
|
916
|
+
rerank:
|
|
917
|
+
model: ms-marco-MiniLM-L-12-v2
|
|
918
|
+
top_n: 5 # Return top 5 after reranking
|
|
919
|
+
```
|
|
920
|
+
|
|
921
|
+
Available models (from fastest to most accurate):
|
|
922
|
+
- "ms-marco-TinyBERT-L-2-v2" (fastest, smallest)
|
|
923
|
+
- "ms-marco-MiniLM-L-6-v2"
|
|
924
|
+
- "ms-marco-MiniLM-L-12-v2" (default, good balance)
|
|
925
|
+
- "rank-T5-flan" (most accurate, slower)
|
|
926
|
+
"""
|
|
927
|
+
|
|
928
|
+
model_config = ConfigDict(use_enum_values=True, extra="forbid")
|
|
929
|
+
|
|
930
|
+
model: str = Field(
|
|
931
|
+
default="ms-marco-MiniLM-L-12-v2",
|
|
932
|
+
description="FlashRank model name. Default provides good balance of speed and accuracy.",
|
|
933
|
+
)
|
|
934
|
+
top_n: Optional[int] = Field(
|
|
935
|
+
default=None,
|
|
936
|
+
description="Number of documents to return after reranking. If None, uses search_parameters.num_results.",
|
|
937
|
+
)
|
|
938
|
+
cache_dir: Optional[str] = Field(
|
|
939
|
+
default="/tmp/flashrank_cache",
|
|
940
|
+
description="Directory to cache downloaded model weights.",
|
|
941
|
+
)
|
|
942
|
+
columns: Optional[list[str]] = Field(
|
|
943
|
+
default_factory=list, description="Columns to rerank using DatabricksReranker"
|
|
944
|
+
)
|
|
945
|
+
|
|
946
|
+
|
|
898
947
|
class RetrieverModel(BaseModel):
|
|
899
948
|
model_config = ConfigDict(use_enum_values=True, extra="forbid")
|
|
900
949
|
vector_store: VectorStoreModel
|
|
@@ -902,6 +951,10 @@ class RetrieverModel(BaseModel):
|
|
|
902
951
|
search_parameters: SearchParametersModel = Field(
|
|
903
952
|
default_factory=SearchParametersModel
|
|
904
953
|
)
|
|
954
|
+
rerank: Optional[RerankParametersModel | bool] = Field(
|
|
955
|
+
default=None,
|
|
956
|
+
description="Optional reranking configuration. Set to true for defaults, or provide ReRankParametersModel for custom settings.",
|
|
957
|
+
)
|
|
905
958
|
|
|
906
959
|
@model_validator(mode="after")
|
|
907
960
|
def set_default_columns(self):
|
|
@@ -910,6 +963,13 @@ class RetrieverModel(BaseModel):
|
|
|
910
963
|
self.columns = columns
|
|
911
964
|
return self
|
|
912
965
|
|
|
966
|
+
@model_validator(mode="after")
|
|
967
|
+
def set_default_reranker(self):
|
|
968
|
+
"""Convert bool to ReRankParametersModel with defaults."""
|
|
969
|
+
if isinstance(self.rerank, bool) and self.rerank:
|
|
970
|
+
self.rerank = RerankParametersModel()
|
|
971
|
+
return self
|
|
972
|
+
|
|
913
973
|
|
|
914
974
|
class FunctionType(str, Enum):
|
|
915
975
|
PYTHON = "python"
|
dao_ai/providers/databricks.py
CHANGED
|
@@ -219,6 +219,13 @@ class DatabricksProvider(ServiceProvider):
|
|
|
219
219
|
logger.debug("Creating agent...")
|
|
220
220
|
mlflow.set_registry_uri("databricks-uc")
|
|
221
221
|
|
|
222
|
+
# Set up experiment for proper tracking
|
|
223
|
+
experiment: Experiment = self.get_or_create_experiment(config)
|
|
224
|
+
mlflow.set_experiment(experiment_id=experiment.experiment_id)
|
|
225
|
+
logger.debug(
|
|
226
|
+
f"Using experiment: {experiment.name} (ID: {experiment.experiment_id})"
|
|
227
|
+
)
|
|
228
|
+
|
|
222
229
|
llms: Sequence[LLMModel] = list(config.resources.llms.values())
|
|
223
230
|
vector_indexes: Sequence[IndexModel] = list(
|
|
224
231
|
config.resources.vector_stores.values()
|
dao_ai/tools/genie.py
CHANGED
|
@@ -1,6 +1,5 @@
|
|
|
1
1
|
import bisect
|
|
2
2
|
import json
|
|
3
|
-
import logging
|
|
4
3
|
import os
|
|
5
4
|
import time
|
|
6
5
|
from dataclasses import asdict, dataclass
|
|
@@ -184,7 +183,7 @@ class Genie:
|
|
|
184
183
|
conversation_id, result, query_str, description
|
|
185
184
|
)
|
|
186
185
|
elif state in ["RUNNING", "PENDING"]:
|
|
187
|
-
|
|
186
|
+
logger.debug("Waiting for query result...")
|
|
188
187
|
time.sleep(self.poll_interval)
|
|
189
188
|
else:
|
|
190
189
|
return GenieResponse(
|
|
@@ -250,7 +249,7 @@ class Genie:
|
|
|
250
249
|
)
|
|
251
250
|
# includes EXECUTING_QUERY, Genie can retry after this status
|
|
252
251
|
else:
|
|
253
|
-
|
|
252
|
+
logger.debug(f"Waiting...: {resp['status']}")
|
|
254
253
|
time.sleep(self.poll_interval)
|
|
255
254
|
return GenieResponse(
|
|
256
255
|
conversation_id,
|
|
@@ -299,9 +298,6 @@ def create_genie_tool(
|
|
|
299
298
|
if isinstance(genie_room, dict):
|
|
300
299
|
genie_room = GenieRoomModel(**genie_room)
|
|
301
300
|
|
|
302
|
-
space_id: AnyVariable = genie_room.space_id or os.environ.get(
|
|
303
|
-
"DATABRICKS_GENIE_SPACE_ID"
|
|
304
|
-
)
|
|
305
301
|
space_id: AnyVariable = genie_room.space_id or os.environ.get(
|
|
306
302
|
"DATABRICKS_GENIE_SPACE_ID"
|
|
307
303
|
)
|
dao_ai/tools/vector_search.py
CHANGED
|
@@ -1,10 +1,21 @@
|
|
|
1
|
-
from typing import Any, Optional, Sequence
|
|
1
|
+
from typing import Annotated, Any, Callable, List, Optional, Sequence
|
|
2
2
|
|
|
3
3
|
import mlflow
|
|
4
|
-
from
|
|
5
|
-
from
|
|
4
|
+
from databricks.vector_search.reranker import DatabricksReranker
|
|
5
|
+
from databricks_ai_bridge.vector_search_retriever_tool import (
|
|
6
|
+
FilterItem,
|
|
7
|
+
VectorSearchRetrieverToolInput,
|
|
8
|
+
)
|
|
9
|
+
from databricks_langchain.vectorstores import DatabricksVectorSearch
|
|
10
|
+
from flashrank import Ranker, RerankRequest
|
|
11
|
+
from langchain_core.documents import Document
|
|
12
|
+
from langchain_core.tools import InjectedToolCallId, tool
|
|
13
|
+
from langgraph.prebuilt import InjectedState
|
|
14
|
+
from loguru import logger
|
|
15
|
+
from mlflow.entities import SpanType
|
|
6
16
|
|
|
7
17
|
from dao_ai.config import (
|
|
18
|
+
RerankParametersModel,
|
|
8
19
|
RetrieverModel,
|
|
9
20
|
VectorStoreModel,
|
|
10
21
|
)
|
|
@@ -14,13 +25,13 @@ def create_vector_search_tool(
|
|
|
14
25
|
retriever: RetrieverModel | dict[str, Any],
|
|
15
26
|
name: Optional[str] = None,
|
|
16
27
|
description: Optional[str] = None,
|
|
17
|
-
) ->
|
|
28
|
+
) -> Callable:
|
|
18
29
|
"""
|
|
19
30
|
Create a Vector Search tool for retrieving documents from a Databricks Vector Search index.
|
|
20
31
|
|
|
21
32
|
This function creates a tool that enables semantic search over product information,
|
|
22
|
-
documentation, or other content
|
|
23
|
-
|
|
33
|
+
documentation, or other content using the @tool decorator pattern. It supports optional
|
|
34
|
+
reranking of results using FlashRank for improved relevance.
|
|
24
35
|
|
|
25
36
|
Args:
|
|
26
37
|
retriever: Configuration details for the vector search retriever, including:
|
|
@@ -32,32 +43,69 @@ def create_vector_search_tool(
|
|
|
32
43
|
- vector_store: Dictionary with 'endpoint_name' and 'index' for vector search
|
|
33
44
|
- columns: List of columns to retrieve from the vector store
|
|
34
45
|
- search_parameters: Additional parameters for customizing the search behavior
|
|
46
|
+
- rerank: Optional rerank configuration for result reranking
|
|
47
|
+
name: Optional custom name for the tool
|
|
48
|
+
description: Optional custom description for the tool
|
|
35
49
|
|
|
36
50
|
Returns:
|
|
37
|
-
A
|
|
51
|
+
A LangChain tool that performs vector search with optional reranking
|
|
38
52
|
"""
|
|
39
53
|
|
|
40
54
|
if isinstance(retriever, dict):
|
|
41
55
|
retriever = RetrieverModel(**retriever)
|
|
42
56
|
|
|
43
|
-
|
|
57
|
+
vector_store_config: VectorStoreModel = retriever.vector_store
|
|
58
|
+
|
|
59
|
+
# Index is required for vector search
|
|
60
|
+
if vector_store_config.index is None:
|
|
61
|
+
raise ValueError("vector_store.index is required for vector search")
|
|
44
62
|
|
|
45
|
-
index_name: str =
|
|
46
|
-
columns: Sequence[str] = retriever.columns
|
|
63
|
+
index_name: str = vector_store_config.index.full_name
|
|
64
|
+
columns: Sequence[str] = retriever.columns or []
|
|
47
65
|
search_parameters: dict[str, Any] = retriever.search_parameters.model_dump()
|
|
48
|
-
primary_key: str =
|
|
49
|
-
doc_uri: str =
|
|
50
|
-
text_column: str =
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
66
|
+
primary_key: str = vector_store_config.primary_key or ""
|
|
67
|
+
doc_uri: str = vector_store_config.doc_uri or ""
|
|
68
|
+
text_column: str = vector_store_config.embedding_source_column
|
|
69
|
+
|
|
70
|
+
# Extract reranker configuration
|
|
71
|
+
reranker_config: Optional[RerankParametersModel] = retriever.rerank
|
|
72
|
+
|
|
73
|
+
# Initialize FlashRank ranker once if reranking is enabled
|
|
74
|
+
# This is expensive (loads model weights), so we do it once and reuse across invocations
|
|
75
|
+
ranker: Optional[Ranker] = None
|
|
76
|
+
if reranker_config:
|
|
77
|
+
logger.debug(
|
|
78
|
+
f"Creating vector search tool with reranking: '{name}' "
|
|
79
|
+
f"(model: {reranker_config.model}, top_n: {reranker_config.top_n or 'auto'})"
|
|
80
|
+
)
|
|
81
|
+
try:
|
|
82
|
+
ranker = Ranker(
|
|
83
|
+
model_name=reranker_config.model, cache_dir=reranker_config.cache_dir
|
|
84
|
+
)
|
|
85
|
+
logger.info(
|
|
86
|
+
f"FlashRank ranker initialized successfully (model: {reranker_config.model})"
|
|
87
|
+
)
|
|
88
|
+
except Exception as e:
|
|
89
|
+
logger.warning(
|
|
90
|
+
f"Failed to initialize FlashRank ranker during tool creation: {e}. "
|
|
91
|
+
"Reranking will be disabled for this tool."
|
|
92
|
+
)
|
|
93
|
+
# Set reranker_config to None so we don't attempt reranking
|
|
94
|
+
reranker_config = None
|
|
95
|
+
else:
|
|
96
|
+
logger.debug(
|
|
97
|
+
f"Creating vector search tool without reranking: '{name}' (standard similarity search only)"
|
|
98
|
+
)
|
|
99
|
+
|
|
100
|
+
# Initialize the vector store
|
|
101
|
+
# Note: text_column is only required for self-managed embeddings
|
|
102
|
+
# For Databricks-managed embeddings, it's automatically determined from the index
|
|
103
|
+
vector_store: DatabricksVectorSearch = DatabricksVectorSearch(
|
|
57
104
|
index_name=index_name,
|
|
105
|
+
text_column=None, # Let DatabricksVectorSearch determine this from the index
|
|
58
106
|
columns=columns,
|
|
59
|
-
|
|
60
|
-
workspace_client=
|
|
107
|
+
include_score=True,
|
|
108
|
+
workspace_client=vector_store_config.workspace_client,
|
|
61
109
|
)
|
|
62
110
|
|
|
63
111
|
# Register the retriever schema with MLflow for model serving integration
|
|
@@ -66,7 +114,169 @@ def create_vector_search_tool(
|
|
|
66
114
|
primary_key=primary_key,
|
|
67
115
|
text_column=text_column,
|
|
68
116
|
doc_uri=doc_uri,
|
|
69
|
-
other_columns=columns,
|
|
117
|
+
other_columns=list(columns),
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
# Helper function to perform vector similarity search
|
|
121
|
+
@mlflow.trace(name="find_documents", span_type=SpanType.RETRIEVER)
|
|
122
|
+
def _find_documents(
|
|
123
|
+
query: str, filters: Optional[List[FilterItem]] = None
|
|
124
|
+
) -> List[Document]:
|
|
125
|
+
"""Perform vector similarity search."""
|
|
126
|
+
# Convert filters to dict format
|
|
127
|
+
filters_dict: dict[str, Any] = {}
|
|
128
|
+
if filters:
|
|
129
|
+
for item in filters:
|
|
130
|
+
item_dict = dict(item)
|
|
131
|
+
filters_dict[item_dict["key"]] = item_dict["value"]
|
|
132
|
+
|
|
133
|
+
# Merge with any configured filters
|
|
134
|
+
combined_filters: dict[str, Any] = {
|
|
135
|
+
**filters_dict,
|
|
136
|
+
**search_parameters.get("filters", {}),
|
|
137
|
+
}
|
|
138
|
+
|
|
139
|
+
# Perform similarity search
|
|
140
|
+
num_results: int = search_parameters.get("num_results", 10)
|
|
141
|
+
query_type: str = search_parameters.get("query_type", "ANN")
|
|
142
|
+
|
|
143
|
+
logger.debug(
|
|
144
|
+
f"Performing vector search: query='{query[:50]}...', k={num_results}, filters={combined_filters}"
|
|
145
|
+
)
|
|
146
|
+
|
|
147
|
+
# Build similarity search kwargs
|
|
148
|
+
search_kwargs = {
|
|
149
|
+
"query": query,
|
|
150
|
+
"k": num_results,
|
|
151
|
+
"filter": combined_filters if combined_filters else None,
|
|
152
|
+
"query_type": query_type,
|
|
153
|
+
}
|
|
154
|
+
|
|
155
|
+
# Add DatabricksReranker if configured with columns
|
|
156
|
+
if reranker_config and reranker_config.columns:
|
|
157
|
+
search_kwargs["reranker"] = DatabricksReranker(
|
|
158
|
+
columns_to_rerank=reranker_config.columns
|
|
159
|
+
)
|
|
160
|
+
|
|
161
|
+
documents: List[Document] = vector_store.similarity_search(**search_kwargs)
|
|
162
|
+
|
|
163
|
+
logger.debug(f"Retrieved {len(documents)} documents from vector search")
|
|
164
|
+
return documents
|
|
165
|
+
|
|
166
|
+
# Helper function to rerank documents
|
|
167
|
+
@mlflow.trace(name="rerank_documents", span_type=SpanType.RETRIEVER)
|
|
168
|
+
def _rerank_documents(query: str, documents: List[Document]) -> List[Document]:
|
|
169
|
+
"""Rerank documents using FlashRank.
|
|
170
|
+
|
|
171
|
+
Uses the ranker instance initialized at tool creation time (captured in closure).
|
|
172
|
+
This avoids expensive model loading on every invocation.
|
|
173
|
+
"""
|
|
174
|
+
if not reranker_config or ranker is None:
|
|
175
|
+
return documents
|
|
176
|
+
|
|
177
|
+
logger.debug(
|
|
178
|
+
f"Starting reranking for {len(documents)} documents using model '{reranker_config.model}'"
|
|
179
|
+
)
|
|
180
|
+
|
|
181
|
+
# Prepare passages for reranking
|
|
182
|
+
passages: List[dict[str, Any]] = [
|
|
183
|
+
{"text": doc.page_content, "meta": doc.metadata} for doc in documents
|
|
184
|
+
]
|
|
185
|
+
|
|
186
|
+
# Create reranking request
|
|
187
|
+
rerank_request: RerankRequest = RerankRequest(query=query, passages=passages)
|
|
188
|
+
|
|
189
|
+
# Perform reranking
|
|
190
|
+
logger.debug(f"Reranking {len(passages)} passages for query: '{query[:50]}...'")
|
|
191
|
+
results: List[dict[str, Any]] = ranker.rerank(rerank_request)
|
|
192
|
+
|
|
193
|
+
# Apply top_n filtering
|
|
194
|
+
top_n: int = reranker_config.top_n or len(documents)
|
|
195
|
+
results = results[:top_n]
|
|
196
|
+
logger.debug(
|
|
197
|
+
f"Reranking complete. Filtered to top {top_n} results from {len(documents)} candidates"
|
|
198
|
+
)
|
|
199
|
+
|
|
200
|
+
# Convert back to Document objects with reranking scores
|
|
201
|
+
reranked_docs: List[Document] = []
|
|
202
|
+
for result in results:
|
|
203
|
+
# Find original document by matching text
|
|
204
|
+
orig_doc: Optional[Document] = next(
|
|
205
|
+
(doc for doc in documents if doc.page_content == result["text"]), None
|
|
206
|
+
)
|
|
207
|
+
if orig_doc:
|
|
208
|
+
# Add reranking score to metadata
|
|
209
|
+
reranked_doc: Document = Document(
|
|
210
|
+
page_content=orig_doc.page_content,
|
|
211
|
+
metadata={
|
|
212
|
+
**orig_doc.metadata,
|
|
213
|
+
"reranker_score": result["score"],
|
|
214
|
+
},
|
|
215
|
+
)
|
|
216
|
+
reranked_docs.append(reranked_doc)
|
|
217
|
+
|
|
218
|
+
logger.debug(
|
|
219
|
+
f"Reranked {len(documents)} documents → {len(reranked_docs)} results "
|
|
220
|
+
f"(model: {reranker_config.model}, top score: {reranked_docs[0].metadata.get('reranker_score', 0):.4f})"
|
|
221
|
+
if reranked_docs
|
|
222
|
+
else f"Reranking completed with {len(reranked_docs)} results"
|
|
223
|
+
)
|
|
224
|
+
|
|
225
|
+
return reranked_docs
|
|
226
|
+
|
|
227
|
+
# Create the main vector search tool using @tool decorator
|
|
228
|
+
# Note: args_schema provides descriptions for query and filters,
|
|
229
|
+
# so Annotated is only needed for injected LangGraph parameters
|
|
230
|
+
@tool(
|
|
231
|
+
name_or_callable=name or index_name,
|
|
232
|
+
description=description or "Search for documents using vector similarity",
|
|
233
|
+
args_schema=VectorSearchRetrieverToolInput,
|
|
70
234
|
)
|
|
235
|
+
def vector_search_tool(
|
|
236
|
+
query: str,
|
|
237
|
+
filters: Optional[List[FilterItem]] = None,
|
|
238
|
+
state: Annotated[dict, InjectedState] = None,
|
|
239
|
+
tool_call_id: Annotated[str, InjectedToolCallId] = None,
|
|
240
|
+
) -> list[dict[str, Any]]:
|
|
241
|
+
"""
|
|
242
|
+
Search for documents using vector similarity with optional reranking.
|
|
243
|
+
|
|
244
|
+
This tool performs a two-stage retrieval process:
|
|
245
|
+
1. Vector similarity search to find candidate documents
|
|
246
|
+
2. Optional reranking using cross-encoder model for improved relevance
|
|
247
|
+
|
|
248
|
+
Both stages are traced in MLflow for observability.
|
|
249
|
+
|
|
250
|
+
Returns:
|
|
251
|
+
Command with ToolMessage containing the retrieved documents
|
|
252
|
+
"""
|
|
253
|
+
logger.debug(
|
|
254
|
+
f"Vector search tool called: query='{query[:50]}...', reranking={reranker_config is not None}"
|
|
255
|
+
)
|
|
256
|
+
|
|
257
|
+
# Step 1: Perform vector similarity search
|
|
258
|
+
documents: List[Document] = _find_documents(query, filters)
|
|
259
|
+
|
|
260
|
+
# Step 2: If reranking is enabled, rerank the documents
|
|
261
|
+
if reranker_config:
|
|
262
|
+
logger.debug(
|
|
263
|
+
f"Reranking enabled (model: '{reranker_config.model}', top_n: {reranker_config.top_n or 'all'})"
|
|
264
|
+
)
|
|
265
|
+
documents = _rerank_documents(query, documents)
|
|
266
|
+
logger.debug(f"Returning {len(documents)} reranked documents")
|
|
267
|
+
else:
|
|
268
|
+
logger.debug("Reranking disabled, returning original vector search results")
|
|
269
|
+
|
|
270
|
+
# Return Command with ToolMessage containing the documents
|
|
271
|
+
# Serialize documents to dicts for proper ToolMessage handling
|
|
272
|
+
serialized_docs: list[dict[str, Any]] = [
|
|
273
|
+
{
|
|
274
|
+
"page_content": doc.page_content,
|
|
275
|
+
"metadata": doc.metadata,
|
|
276
|
+
}
|
|
277
|
+
for doc in documents
|
|
278
|
+
]
|
|
279
|
+
|
|
280
|
+
return serialized_docs
|
|
71
281
|
|
|
72
282
|
return vector_search_tool
|
dao_ai/utils.py
CHANGED
|
@@ -100,6 +100,7 @@ def get_installed_packages() -> dict[str, str]:
|
|
|
100
100
|
f"databricks-mcp=={version('databricks-mcp')}",
|
|
101
101
|
f"databricks-sdk[openai]=={version('databricks-sdk')}",
|
|
102
102
|
f"duckduckgo-search=={version('duckduckgo-search')}",
|
|
103
|
+
f"flashrank=={version('flashrank')}",
|
|
103
104
|
f"langchain=={version('langchain')}",
|
|
104
105
|
f"langchain-mcp-adapters=={version('langchain-mcp-adapters')}",
|
|
105
106
|
f"langchain-openai=={version('langchain-openai')}",
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dao-ai
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.29
|
|
4
4
|
Summary: DAO AI: A modular, multi-agent orchestration framework for complex AI workflows. Supports agent handoff, tool integration, and dynamic configuration via YAML.
|
|
5
5
|
Project-URL: Homepage, https://github.com/natefleming/dao-ai
|
|
6
6
|
Project-URL: Documentation, https://natefleming.github.io/dao-ai
|
|
@@ -18,17 +18,19 @@ Classifier: Intended Audience :: Science/Research
|
|
|
18
18
|
Classifier: License :: OSI Approved :: MIT License
|
|
19
19
|
Classifier: Operating System :: OS Independent
|
|
20
20
|
Classifier: Programming Language :: Python :: 3
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
21
22
|
Classifier: Programming Language :: Python :: 3.12
|
|
22
23
|
Classifier: Programming Language :: Python :: 3.13
|
|
23
24
|
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
24
25
|
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
25
26
|
Classifier: Topic :: System :: Distributed Computing
|
|
26
|
-
Requires-Python: >=3.
|
|
27
|
+
Requires-Python: >=3.11
|
|
27
28
|
Requires-Dist: databricks-agents>=1.7.0
|
|
28
29
|
Requires-Dist: databricks-langchain>=0.8.1
|
|
29
30
|
Requires-Dist: databricks-mcp>=0.3.0
|
|
30
31
|
Requires-Dist: databricks-sdk[openai]>=0.67.0
|
|
31
32
|
Requires-Dist: duckduckgo-search>=8.0.2
|
|
33
|
+
Requires-Dist: flashrank>=0.2.8
|
|
32
34
|
Requires-Dist: gepa>=0.0.17
|
|
33
35
|
Requires-Dist: grandalf>=0.8
|
|
34
36
|
Requires-Dist: langchain-mcp-adapters>=0.1.10
|
|
@@ -56,7 +58,7 @@ Requires-Dist: tomli>=2.3.0
|
|
|
56
58
|
Requires-Dist: unitycatalog-ai[databricks]>=0.3.0
|
|
57
59
|
Provides-Extra: databricks
|
|
58
60
|
Requires-Dist: databricks-connect>=15.0.0; extra == 'databricks'
|
|
59
|
-
Requires-Dist: databricks-vectorsearch>=0.
|
|
61
|
+
Requires-Dist: databricks-vectorsearch>=0.63; extra == 'databricks'
|
|
60
62
|
Requires-Dist: pyspark>=3.5.0; extra == 'databricks'
|
|
61
63
|
Provides-Extra: dev
|
|
62
64
|
Requires-Dist: mypy>=1.0.0; extra == 'dev'
|
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
dao_ai/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
-
dao_ai/agent_as_code.py,sha256=
|
|
2
|
+
dao_ai/agent_as_code.py,sha256=sviZQV7ZPxE5zkZ9jAbfegI681nra5i8yYxw05e3X7U,552
|
|
3
3
|
dao_ai/catalog.py,sha256=sPZpHTD3lPx4EZUtIWeQV7VQM89WJ6YH__wluk1v2lE,4947
|
|
4
4
|
dao_ai/chat_models.py,sha256=uhwwOTeLyHWqoTTgHrs4n5iSyTwe4EQcLKnh3jRxPWI,8626
|
|
5
5
|
dao_ai/cli.py,sha256=gq-nsapWxDA1M6Jua3vajBvIwf0Oa6YLcB58lEtMKUo,22503
|
|
6
|
-
dao_ai/config.py,sha256=
|
|
6
|
+
dao_ai/config.py,sha256=qqBdYV-ElIMYDKzY4lBejyJ6ysmwnBkqyGMWRBwWGVo,72507
|
|
7
7
|
dao_ai/graph.py,sha256=9kjJx0oFZKq5J9-Kpri4-0VCJILHYdYyhqQnj0_noxQ,8913
|
|
8
8
|
dao_ai/guardrails.py,sha256=4TKArDONRy8RwHzOT1plZ1rhy3x9GF_aeGpPCRl6wYA,4016
|
|
9
9
|
dao_ai/messages.py,sha256=xl_3-WcFqZKCFCiov8sZOPljTdM3gX3fCHhxq-xFg2U,7005
|
|
@@ -12,7 +12,7 @@ dao_ai/nodes.py,sha256=iQ_5vL6mt1UcRnhwgz-l1D8Ww4CMQrSMVnP_Lu7fFjU,8781
|
|
|
12
12
|
dao_ai/prompts.py,sha256=7Hcstmv514P0s9s-TVoIlbkDV2XXOphGCW6gcPeyUYE,1628
|
|
13
13
|
dao_ai/state.py,sha256=_lF9krAYYjvFDMUwZzVKOn0ZnXKcOrbjWKdre0C5B54,1137
|
|
14
14
|
dao_ai/types.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
15
|
-
dao_ai/utils.py,sha256=
|
|
15
|
+
dao_ai/utils.py,sha256=4FV9y0EVn0tmxfkn4EdUAkOewoAF_T0pHDAHe6hJx-M,6708
|
|
16
16
|
dao_ai/vector_search.py,sha256=jlaFS_iizJ55wblgzZmswMM3UOL-qOp2BGJc0JqXYSg,2839
|
|
17
17
|
dao_ai/hooks/__init__.py,sha256=LlHGIuiZt6vGW8K5AQo1XJEkBP5vDVtMhq0IdjcLrD4,417
|
|
18
18
|
dao_ai/hooks/core.py,sha256=ZShHctUSoauhBgdf1cecy9-D7J6-sGn-pKjuRMumW5U,6663
|
|
@@ -22,20 +22,20 @@ dao_ai/memory/core.py,sha256=DnEjQO3S7hXr3CDDd7C2eE7fQUmcCS_8q9BXEgjPH3U,4271
|
|
|
22
22
|
dao_ai/memory/postgres.py,sha256=vvI3osjx1EoU5GBA6SCUstTBKillcmLl12hVgDMjfJY,15346
|
|
23
23
|
dao_ai/providers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
24
24
|
dao_ai/providers/base.py,sha256=-fjKypCOk28h6vioPfMj9YZSw_3Kcbi2nMuAyY7vX9k,1383
|
|
25
|
-
dao_ai/providers/databricks.py,sha256=
|
|
25
|
+
dao_ai/providers/databricks.py,sha256=QwQS0Mad6nZNOB2k_h3lTrwLRzI5ApLQjxOz4CpvhlI,66130
|
|
26
26
|
dao_ai/tools/__init__.py,sha256=G5-5Yi6zpQOH53b5IzLdtsC6g0Ep6leI5GxgxOmgw7Q,1203
|
|
27
27
|
dao_ai/tools/agent.py,sha256=WbQnyziiT12TLMrA7xK0VuOU029tdmUBXbUl-R1VZ0Q,1886
|
|
28
28
|
dao_ai/tools/core.py,sha256=Kei33S8vrmvPOAyrFNekaWmV2jqZ-IPS1QDSvU7RZF0,1984
|
|
29
|
-
dao_ai/tools/genie.py,sha256=
|
|
29
|
+
dao_ai/tools/genie.py,sha256=wt6pVykukNStOUlrTyjWUj-S2Wb47IuMr5HztEcN3Wg,14925
|
|
30
30
|
dao_ai/tools/human_in_the_loop.py,sha256=yk35MO9eNETnYFH-sqlgR-G24TrEgXpJlnZUustsLkI,3681
|
|
31
31
|
dao_ai/tools/mcp.py,sha256=5aQoRtx2z4xm6zgRslc78rSfEQe-mfhqov2NsiybYfc,8416
|
|
32
32
|
dao_ai/tools/python.py,sha256=XcQiTMshZyLUTVR5peB3vqsoUoAAy8gol9_pcrhddfI,1831
|
|
33
33
|
dao_ai/tools/slack.py,sha256=SCvyVcD9Pv_XXPXePE_fSU1Pd8VLTEkKDLvoGTZWy2Y,4775
|
|
34
34
|
dao_ai/tools/time.py,sha256=Y-23qdnNHzwjvnfkWvYsE7PoWS1hfeKy44tA7sCnNac,8759
|
|
35
35
|
dao_ai/tools/unity_catalog.py,sha256=uX_h52BuBAr4c9UeqSMI7DNz3BPRLeai5tBVW4sJqRI,13113
|
|
36
|
-
dao_ai/tools/vector_search.py,sha256=
|
|
37
|
-
dao_ai-0.0.
|
|
38
|
-
dao_ai-0.0.
|
|
39
|
-
dao_ai-0.0.
|
|
40
|
-
dao_ai-0.0.
|
|
41
|
-
dao_ai-0.0.
|
|
36
|
+
dao_ai/tools/vector_search.py,sha256=h6yCgEtOA3h-anJG0hGB3VvcmC3Os7_qnhz8xxRjv1E,11346
|
|
37
|
+
dao_ai-0.0.29.dist-info/METADATA,sha256=ze54m_V26Rh451YBjImiAAf_ZgZ3j41XscMLMoSrHGc,42778
|
|
38
|
+
dao_ai-0.0.29.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
39
|
+
dao_ai-0.0.29.dist-info/entry_points.txt,sha256=Xa-UFyc6gWGwMqMJOt06ZOog2vAfygV_DSwg1AiP46g,43
|
|
40
|
+
dao_ai-0.0.29.dist-info/licenses/LICENSE,sha256=YZt3W32LtPYruuvHE9lGk2bw6ZPMMJD8yLrjgHybyz4,1069
|
|
41
|
+
dao_ai-0.0.29.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|