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 CHANGED
@@ -7,6 +7,9 @@ from mlflow.pyfunc import ResponsesAgent
7
7
 
8
8
  from dao_ai.config import AppConfig
9
9
 
10
+ mlflow.set_registry_uri("databricks-uc")
11
+ mlflow.set_tracking_uri("databricks")
12
+
10
13
  mlflow.langchain.autolog()
11
14
 
12
15
  model_config: ModelConfig = ModelConfig()
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"
@@ -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
- logging.debug("Waiting for query result...")
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
- logging.debug(f"Waiting...: {resp['status']}")
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
  )
@@ -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 databricks_langchain.vector_search_retriever_tool import VectorSearchRetrieverTool
5
- from langchain_core.tools import BaseTool
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
- ) -> BaseTool:
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. It also registers the retriever schema with MLflow
23
- for proper integration with the model serving infrastructure.
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 BaseTool instance that can perform vector search operations
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
- vector_store: VectorStoreModel = retriever.vector_store
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 = vector_store.index.full_name
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 = vector_store.primary_key
49
- doc_uri: str = vector_store.doc_uri
50
- text_column: str = vector_store.embedding_source_column
51
-
52
- vector_search_tool: BaseTool = VectorSearchRetrieverTool(
53
- name=name,
54
- tool_name=name,
55
- description=description,
56
- tool_description=description,
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
- **search_parameters,
60
- workspace_client=vector_store.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.27
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.12
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.56; extra == 'databricks'
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=kPSeDz2-1jRaed1TMs4LA3VECoyqe9_Ed2beRLB9gXQ,472
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=DRFj_1W5sfGH5f2tGQaeC733pTIDTqvbyAt14v8FQYs,70296
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=xfBo9-6k9ss1c7QlC26QDCwS2sY3mgUYgWzTTV6443M,6662
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=W_lXSMbPTULMAx-KW7zBJfP7LtkcPGRnEfGcSYuu708,65824
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=8HSOCzSg6PlBzBYXMmNfUnl-LO03p3Ki3fxLPm_dhPg,15051
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=EDYQs51zIPaAP0ma1D81wJT77GQ-v-cjb2XrFVWfWdg,2621
37
- dao_ai-0.0.27.dist-info/METADATA,sha256=iKbZTl0tFi0S2XUir9uIGh6WyOTvM9yH-4FHCHOzsuE,42695
38
- dao_ai-0.0.27.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
39
- dao_ai-0.0.27.dist-info/entry_points.txt,sha256=Xa-UFyc6gWGwMqMJOt06ZOog2vAfygV_DSwg1AiP46g,43
40
- dao_ai-0.0.27.dist-info/licenses/LICENSE,sha256=YZt3W32LtPYruuvHE9lGk2bw6ZPMMJD8yLrjgHybyz4,1069
41
- dao_ai-0.0.27.dist-info/RECORD,,
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,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: hatchling 1.27.0
2
+ Generator: hatchling 1.28.0
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any