dao-ai 0.1.6__py3-none-any.whl → 0.1.7__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/config.py +70 -23
- {dao_ai-0.1.6.dist-info → dao_ai-0.1.7.dist-info}/METADATA +1 -1
- {dao_ai-0.1.6.dist-info → dao_ai-0.1.7.dist-info}/RECORD +6 -6
- {dao_ai-0.1.6.dist-info → dao_ai-0.1.7.dist-info}/WHEEL +0 -0
- {dao_ai-0.1.6.dist-info → dao_ai-0.1.7.dist-info}/entry_points.txt +0 -0
- {dao_ai-0.1.6.dist-info → dao_ai-0.1.7.dist-info}/licenses/LICENSE +0 -0
dao_ai/config.py
CHANGED
|
@@ -24,6 +24,7 @@ from databricks.sdk.credentials_provider import (
|
|
|
24
24
|
ModelServingUserCredentials,
|
|
25
25
|
)
|
|
26
26
|
from databricks.sdk.errors.platform import NotFound
|
|
27
|
+
from databricks.sdk.service.apps import App
|
|
27
28
|
from databricks.sdk.service.catalog import FunctionInfo, TableInfo
|
|
28
29
|
from databricks.sdk.service.dashboards import GenieSpace
|
|
29
30
|
from databricks.sdk.service.database import DatabaseInstance
|
|
@@ -147,7 +148,7 @@ class PrimitiveVariableModel(BaseModel, HasValue):
|
|
|
147
148
|
return str(value)
|
|
148
149
|
|
|
149
150
|
@model_validator(mode="after")
|
|
150
|
-
def validate_value(self) ->
|
|
151
|
+
def validate_value(self) -> Self:
|
|
151
152
|
if not isinstance(self.as_value(), (str, int, float, bool)):
|
|
152
153
|
raise ValueError("Value must be a primitive type (str, int, float, bool)")
|
|
153
154
|
return self
|
|
@@ -415,15 +416,45 @@ class SchemaModel(BaseModel, HasFullName):
|
|
|
415
416
|
|
|
416
417
|
|
|
417
418
|
class DatabricksAppModel(IsDatabricksResource, HasFullName):
|
|
419
|
+
"""
|
|
420
|
+
Configuration for a Databricks App resource.
|
|
421
|
+
|
|
422
|
+
The `name` is the unique instance name of the Databricks App within the workspace.
|
|
423
|
+
The `url` is dynamically retrieved from the workspace client by calling
|
|
424
|
+
`apps.get(name)` and returning the app's URL.
|
|
425
|
+
|
|
426
|
+
Example:
|
|
427
|
+
```yaml
|
|
428
|
+
resources:
|
|
429
|
+
apps:
|
|
430
|
+
my_app:
|
|
431
|
+
name: my-databricks-app
|
|
432
|
+
```
|
|
433
|
+
"""
|
|
434
|
+
|
|
418
435
|
model_config = ConfigDict(use_enum_values=True, extra="forbid")
|
|
419
436
|
name: str
|
|
420
|
-
|
|
437
|
+
"""The unique instance name of the Databricks App in the workspace."""
|
|
438
|
+
|
|
439
|
+
@property
|
|
440
|
+
def url(self) -> str:
|
|
441
|
+
"""
|
|
442
|
+
Retrieve the URL of the Databricks App from the workspace.
|
|
443
|
+
|
|
444
|
+
Returns:
|
|
445
|
+
The URL of the deployed Databricks App.
|
|
446
|
+
|
|
447
|
+
Raises:
|
|
448
|
+
RuntimeError: If the app is not found or URL is not available.
|
|
449
|
+
"""
|
|
450
|
+
app: App = self.workspace_client.apps.get(self.name)
|
|
451
|
+
if app.url is None:
|
|
452
|
+
raise RuntimeError(
|
|
453
|
+
f"Databricks App '{self.name}' does not have a URL. "
|
|
454
|
+
"The app may not be deployed yet."
|
|
455
|
+
)
|
|
456
|
+
return app.url
|
|
421
457
|
|
|
422
|
-
@model_validator(mode="after")
|
|
423
|
-
def resolve_variables(self) -> Self:
|
|
424
|
-
"""Resolve AnyVariable fields to their actual string values."""
|
|
425
|
-
self.url = value_of(self.url)
|
|
426
|
-
return self
|
|
427
458
|
|
|
428
459
|
@property
|
|
429
460
|
def full_name(self) -> str:
|
|
@@ -445,7 +476,7 @@ class TableModel(IsDatabricksResource, HasFullName):
|
|
|
445
476
|
name: Optional[str] = None
|
|
446
477
|
|
|
447
478
|
@model_validator(mode="after")
|
|
448
|
-
def validate_name_or_schema_required(self) ->
|
|
479
|
+
def validate_name_or_schema_required(self) -> Self:
|
|
449
480
|
if not self.name and not self.schema_model:
|
|
450
481
|
raise ValueError(
|
|
451
482
|
"Either 'name' or 'schema_model' must be provided for TableModel"
|
|
@@ -1011,7 +1042,7 @@ class VolumePathModel(BaseModel, HasFullName):
|
|
|
1011
1042
|
path: Optional[str] = None
|
|
1012
1043
|
|
|
1013
1044
|
@model_validator(mode="after")
|
|
1014
|
-
def validate_path_or_volume(self) ->
|
|
1045
|
+
def validate_path_or_volume(self) -> Self:
|
|
1015
1046
|
if not self.volume and not self.path:
|
|
1016
1047
|
raise ValueError("Either 'volume' or 'path' must be provided")
|
|
1017
1048
|
return self
|
|
@@ -1853,6 +1884,7 @@ class McpFunctionModel(BaseFunctionModel, IsDatabricksResource):
|
|
|
1853
1884
|
headers: dict[str, AnyVariable] = Field(default_factory=dict)
|
|
1854
1885
|
args: list[str] = Field(default_factory=list)
|
|
1855
1886
|
# MCP-specific fields
|
|
1887
|
+
app: Optional[DatabricksAppModel] = None
|
|
1856
1888
|
connection: Optional[ConnectionModel] = None
|
|
1857
1889
|
functions: Optional[SchemaModel] = None
|
|
1858
1890
|
genie_room: Optional[GenieRoomModel] = None
|
|
@@ -1940,6 +1972,7 @@ class McpFunctionModel(BaseFunctionModel, IsDatabricksResource):
|
|
|
1940
1972
|
|
|
1941
1973
|
Returns the URL based on the configured source:
|
|
1942
1974
|
- If url is set, returns it directly
|
|
1975
|
+
- If app is set, retrieves URL from Databricks App via workspace client
|
|
1943
1976
|
- If connection is set, constructs URL from connection
|
|
1944
1977
|
- If genie_room is set, constructs Genie MCP URL
|
|
1945
1978
|
- If sql is set, constructs DBSQL MCP URL (serverless)
|
|
@@ -1952,6 +1985,7 @@ class McpFunctionModel(BaseFunctionModel, IsDatabricksResource):
|
|
|
1952
1985
|
- Vector Search: https://{host}/api/2.0/mcp/vector-search/{catalog}/{schema}
|
|
1953
1986
|
- UC Functions: https://{host}/api/2.0/mcp/functions/{catalog}/{schema}
|
|
1954
1987
|
- Connection: https://{host}/api/2.0/mcp/external/{connection_name}
|
|
1988
|
+
- Databricks App: Retrieved dynamically from workspace
|
|
1955
1989
|
"""
|
|
1956
1990
|
# Direct URL provided
|
|
1957
1991
|
if self.url:
|
|
@@ -1973,6 +2007,10 @@ class McpFunctionModel(BaseFunctionModel, IsDatabricksResource):
|
|
|
1973
2007
|
# DBSQL MCP server (serverless, workspace-level)
|
|
1974
2008
|
if self.sql:
|
|
1975
2009
|
return f"{workspace_host}/api/2.0/mcp/sql"
|
|
2010
|
+
|
|
2011
|
+
# Databricks App
|
|
2012
|
+
if self.app:
|
|
2013
|
+
return self.app.url
|
|
1976
2014
|
|
|
1977
2015
|
# Vector Search
|
|
1978
2016
|
if self.vector_search:
|
|
@@ -1983,33 +2021,35 @@ class McpFunctionModel(BaseFunctionModel, IsDatabricksResource):
|
|
|
1983
2021
|
raise ValueError(
|
|
1984
2022
|
"vector_search must have an index with a schema (catalog/schema) configured"
|
|
1985
2023
|
)
|
|
1986
|
-
catalog: str = self.vector_search.index.schema_model.catalog_name
|
|
1987
|
-
schema: str = self.vector_search.index.schema_model.schema_name
|
|
2024
|
+
catalog: str = value_of(self.vector_search.index.schema_model.catalog_name)
|
|
2025
|
+
schema: str = value_of(self.vector_search.index.schema_model.schema_name)
|
|
1988
2026
|
return f"{workspace_host}/api/2.0/mcp/vector-search/{catalog}/{schema}"
|
|
1989
2027
|
|
|
1990
2028
|
# UC Functions MCP server
|
|
1991
2029
|
if self.functions:
|
|
1992
|
-
catalog: str = self.functions.catalog_name
|
|
1993
|
-
schema: str = self.functions.schema_name
|
|
2030
|
+
catalog: str = value_of(self.functions.catalog_name)
|
|
2031
|
+
schema: str = value_of(self.functions.schema_name)
|
|
1994
2032
|
return f"{workspace_host}/api/2.0/mcp/functions/{catalog}/{schema}"
|
|
1995
2033
|
|
|
1996
2034
|
raise ValueError(
|
|
1997
|
-
"No URL source configured. Provide one of: url, connection, genie_room, "
|
|
2035
|
+
"No URL source configured. Provide one of: url, app, connection, genie_room, "
|
|
1998
2036
|
"sql, vector_search, or functions"
|
|
1999
2037
|
)
|
|
2000
2038
|
|
|
2001
2039
|
@field_serializer("transport")
|
|
2002
|
-
def serialize_transport(self, value) -> str:
|
|
2040
|
+
def serialize_transport(self, value: TransportType) -> str:
|
|
2041
|
+
"""Serialize transport enum to string."""
|
|
2003
2042
|
if isinstance(value, TransportType):
|
|
2004
2043
|
return value.value
|
|
2005
2044
|
return str(value)
|
|
2006
2045
|
|
|
2007
2046
|
@model_validator(mode="after")
|
|
2008
|
-
def validate_mutually_exclusive(self) ->
|
|
2047
|
+
def validate_mutually_exclusive(self) -> Self:
|
|
2009
2048
|
"""Validate that exactly one URL source is provided."""
|
|
2010
2049
|
# Count how many URL sources are provided
|
|
2011
2050
|
url_sources: list[tuple[str, Any]] = [
|
|
2012
2051
|
("url", self.url),
|
|
2052
|
+
("app", self.app),
|
|
2013
2053
|
("connection", self.connection),
|
|
2014
2054
|
("genie_room", self.genie_room),
|
|
2015
2055
|
("sql", self.sql),
|
|
@@ -2025,13 +2065,13 @@ class McpFunctionModel(BaseFunctionModel, IsDatabricksResource):
|
|
|
2025
2065
|
if len(provided_sources) == 0:
|
|
2026
2066
|
raise ValueError(
|
|
2027
2067
|
"For STREAMABLE_HTTP transport, exactly one of the following must be provided: "
|
|
2028
|
-
"url, connection, genie_room, sql, vector_search, or functions"
|
|
2068
|
+
"url, app, connection, genie_room, sql, vector_search, or functions"
|
|
2029
2069
|
)
|
|
2030
2070
|
if len(provided_sources) > 1:
|
|
2031
2071
|
raise ValueError(
|
|
2032
2072
|
f"For STREAMABLE_HTTP transport, only one URL source can be provided. "
|
|
2033
2073
|
f"Found: {', '.join(provided_sources)}. "
|
|
2034
|
-
f"Please provide only one of: url, connection, genie_room, sql, vector_search, or functions"
|
|
2074
|
+
f"Please provide only one of: url, app, connection, genie_room, sql, vector_search, or functions"
|
|
2035
2075
|
)
|
|
2036
2076
|
|
|
2037
2077
|
if self.transport == TransportType.STDIO:
|
|
@@ -2043,18 +2083,25 @@ class McpFunctionModel(BaseFunctionModel, IsDatabricksResource):
|
|
|
2043
2083
|
return self
|
|
2044
2084
|
|
|
2045
2085
|
@model_validator(mode="after")
|
|
2046
|
-
def update_url(self) ->
|
|
2047
|
-
|
|
2086
|
+
def update_url(self) -> Self:
|
|
2087
|
+
"""Resolve AnyVariable to concrete value for URL."""
|
|
2088
|
+
if self.url is not None:
|
|
2089
|
+
resolved_value: Any = value_of(self.url)
|
|
2090
|
+
# Cast to string since URL must be a string
|
|
2091
|
+
self.url = str(resolved_value) if resolved_value else None
|
|
2048
2092
|
return self
|
|
2049
2093
|
|
|
2050
2094
|
@model_validator(mode="after")
|
|
2051
|
-
def update_headers(self) ->
|
|
2095
|
+
def update_headers(self) -> Self:
|
|
2096
|
+
"""Resolve AnyVariable to concrete values for headers."""
|
|
2052
2097
|
for key, value in self.headers.items():
|
|
2053
|
-
|
|
2098
|
+
resolved_value: Any = value_of(value)
|
|
2099
|
+
# Headers must be strings
|
|
2100
|
+
self.headers[key] = str(resolved_value) if resolved_value else ""
|
|
2054
2101
|
return self
|
|
2055
2102
|
|
|
2056
2103
|
@model_validator(mode="after")
|
|
2057
|
-
def validate_tool_filters(self) ->
|
|
2104
|
+
def validate_tool_filters(self) -> Self:
|
|
2058
2105
|
"""Validate tool filter configuration."""
|
|
2059
2106
|
from loguru import logger
|
|
2060
2107
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dao-ai
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.7
|
|
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
|
|
@@ -2,7 +2,7 @@ dao_ai/__init__.py,sha256=18P98ExEgUaJ1Byw440Ct1ty59v6nxyWtc5S6Uq2m9Q,1062
|
|
|
2
2
|
dao_ai/agent_as_code.py,sha256=xIlLDpPVfmDVzLvbdY_V_CrC4Jvj2ItCWJ-NzdrszTo,538
|
|
3
3
|
dao_ai/catalog.py,sha256=sPZpHTD3lPx4EZUtIWeQV7VQM89WJ6YH__wluk1v2lE,4947
|
|
4
4
|
dao_ai/cli.py,sha256=7LGrVDRgSBpznr8c8EksAhzPW_8NJ9h4St3DSpx-0z4,48196
|
|
5
|
-
dao_ai/config.py,sha256=
|
|
5
|
+
dao_ai/config.py,sha256=GY-n2PtPg4pYtO46KYpHFIGkNkCDVoPA5S7sKLjWpVc,124699
|
|
6
6
|
dao_ai/graph.py,sha256=1-uQlo7iXZQTT3uU8aYu0N5rnhw5_g_2YLwVsAs6M-U,1119
|
|
7
7
|
dao_ai/logging.py,sha256=lYy4BmucCHvwW7aI3YQkQXKJtMvtTnPDu9Hnd7_O4oc,1556
|
|
8
8
|
dao_ai/messages.py,sha256=4ZBzO4iFdktGSLrmhHzFjzMIt2tpaL-aQLHOQJysGnY,6959
|
|
@@ -64,8 +64,8 @@ dao_ai/tools/sql.py,sha256=tKd1gjpLuKdQDyfmyYYtMiNRHDW6MGRbdEVaeqyB8Ok,7632
|
|
|
64
64
|
dao_ai/tools/time.py,sha256=tufJniwivq29y0LIffbgeBTIDE6VgrLpmVf8Qr90qjw,9224
|
|
65
65
|
dao_ai/tools/unity_catalog.py,sha256=AjQfW7bvV8NurqDLIyntYRv2eJuTwNdbvex1L5CRjOk,15534
|
|
66
66
|
dao_ai/tools/vector_search.py,sha256=oe2uBwl2TfeJIXPpwiS6Rmz7wcHczSxNyqS9P3hE6co,14542
|
|
67
|
-
dao_ai-0.1.
|
|
68
|
-
dao_ai-0.1.
|
|
69
|
-
dao_ai-0.1.
|
|
70
|
-
dao_ai-0.1.
|
|
71
|
-
dao_ai-0.1.
|
|
67
|
+
dao_ai-0.1.7.dist-info/METADATA,sha256=jzaENv6Ic9S-uds3qTC4Pu7chwzYG8y0zvTBni4VCW8,16685
|
|
68
|
+
dao_ai-0.1.7.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
69
|
+
dao_ai-0.1.7.dist-info/entry_points.txt,sha256=Xa-UFyc6gWGwMqMJOt06ZOog2vAfygV_DSwg1AiP46g,43
|
|
70
|
+
dao_ai-0.1.7.dist-info/licenses/LICENSE,sha256=YZt3W32LtPYruuvHE9lGk2bw6ZPMMJD8yLrjgHybyz4,1069
|
|
71
|
+
dao_ai-0.1.7.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|