dao-ai 0.1.2__py3-none-any.whl → 0.1.20__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/apps/__init__.py +24 -0
- dao_ai/apps/handlers.py +105 -0
- dao_ai/apps/model_serving.py +29 -0
- dao_ai/apps/resources.py +1122 -0
- dao_ai/apps/server.py +39 -0
- dao_ai/cli.py +546 -37
- dao_ai/config.py +1179 -139
- dao_ai/evaluation.py +543 -0
- dao_ai/genie/__init__.py +55 -7
- dao_ai/genie/cache/__init__.py +34 -7
- dao_ai/genie/cache/base.py +143 -2
- dao_ai/genie/cache/context_aware/__init__.py +31 -0
- dao_ai/genie/cache/context_aware/base.py +1151 -0
- dao_ai/genie/cache/context_aware/in_memory.py +609 -0
- dao_ai/genie/cache/context_aware/persistent.py +802 -0
- dao_ai/genie/cache/context_aware/postgres.py +1166 -0
- dao_ai/genie/cache/core.py +1 -1
- dao_ai/genie/cache/lru.py +257 -75
- dao_ai/genie/cache/optimization.py +890 -0
- dao_ai/genie/core.py +235 -11
- dao_ai/memory/postgres.py +175 -39
- dao_ai/middleware/__init__.py +38 -0
- dao_ai/middleware/assertions.py +3 -3
- dao_ai/middleware/context_editing.py +230 -0
- dao_ai/middleware/core.py +4 -4
- dao_ai/middleware/guardrails.py +3 -3
- dao_ai/middleware/human_in_the_loop.py +3 -2
- dao_ai/middleware/message_validation.py +4 -4
- dao_ai/middleware/model_call_limit.py +77 -0
- dao_ai/middleware/model_retry.py +121 -0
- dao_ai/middleware/pii.py +157 -0
- dao_ai/middleware/summarization.py +1 -1
- dao_ai/middleware/tool_call_limit.py +210 -0
- dao_ai/middleware/tool_retry.py +174 -0
- dao_ai/middleware/tool_selector.py +129 -0
- dao_ai/models.py +327 -370
- dao_ai/nodes.py +9 -16
- dao_ai/orchestration/core.py +33 -9
- dao_ai/orchestration/supervisor.py +29 -13
- dao_ai/orchestration/swarm.py +6 -1
- dao_ai/{prompts.py → prompts/__init__.py} +12 -61
- dao_ai/prompts/instructed_retriever_decomposition.yaml +58 -0
- dao_ai/prompts/instruction_reranker.yaml +14 -0
- dao_ai/prompts/router.yaml +37 -0
- dao_ai/prompts/verifier.yaml +46 -0
- dao_ai/providers/base.py +28 -2
- dao_ai/providers/databricks.py +363 -33
- dao_ai/state.py +1 -0
- dao_ai/tools/__init__.py +5 -3
- dao_ai/tools/genie.py +103 -26
- dao_ai/tools/instructed_retriever.py +366 -0
- dao_ai/tools/instruction_reranker.py +202 -0
- dao_ai/tools/mcp.py +539 -97
- dao_ai/tools/router.py +89 -0
- dao_ai/tools/slack.py +13 -2
- dao_ai/tools/sql.py +7 -3
- dao_ai/tools/unity_catalog.py +32 -10
- dao_ai/tools/vector_search.py +493 -160
- dao_ai/tools/verifier.py +159 -0
- dao_ai/utils.py +182 -2
- dao_ai/vector_search.py +46 -1
- {dao_ai-0.1.2.dist-info → dao_ai-0.1.20.dist-info}/METADATA +45 -9
- dao_ai-0.1.20.dist-info/RECORD +89 -0
- dao_ai/agent_as_code.py +0 -22
- dao_ai/genie/cache/semantic.py +0 -970
- dao_ai-0.1.2.dist-info/RECORD +0 -64
- {dao_ai-0.1.2.dist-info → dao_ai-0.1.20.dist-info}/WHEEL +0 -0
- {dao_ai-0.1.2.dist-info → dao_ai-0.1.20.dist-info}/entry_points.txt +0 -0
- {dao_ai-0.1.2.dist-info → dao_ai-0.1.20.dist-info}/licenses/LICENSE +0 -0
dao_ai/tools/verifier.py
ADDED
|
@@ -0,0 +1,159 @@
|
|
|
1
|
+
"""
|
|
2
|
+
Result verifier for validating search results against user constraints.
|
|
3
|
+
|
|
4
|
+
Provides structured feedback for intelligent retry when results don't match intent.
|
|
5
|
+
"""
|
|
6
|
+
|
|
7
|
+
import json
|
|
8
|
+
from pathlib import Path
|
|
9
|
+
from typing import Any
|
|
10
|
+
|
|
11
|
+
import mlflow
|
|
12
|
+
import yaml
|
|
13
|
+
from langchain_core.documents import Document
|
|
14
|
+
from langchain_core.language_models import BaseChatModel
|
|
15
|
+
from langchain_core.runnables import Runnable
|
|
16
|
+
from loguru import logger
|
|
17
|
+
from mlflow.entities import SpanType
|
|
18
|
+
|
|
19
|
+
from dao_ai.config import VerificationResult
|
|
20
|
+
|
|
21
|
+
# Load prompt template
|
|
22
|
+
_PROMPT_PATH = Path(__file__).parent.parent / "prompts" / "verifier.yaml"
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
def _load_prompt_template() -> dict[str, Any]:
|
|
26
|
+
"""Load the verifier prompt template from YAML."""
|
|
27
|
+
with open(_PROMPT_PATH) as f:
|
|
28
|
+
return yaml.safe_load(f)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
def _format_results_summary(documents: list[Document], max_docs: int = 5) -> str:
|
|
32
|
+
"""Format top documents for verification prompt."""
|
|
33
|
+
if not documents:
|
|
34
|
+
return "No results retrieved."
|
|
35
|
+
|
|
36
|
+
summaries = []
|
|
37
|
+
for i, doc in enumerate(documents[:max_docs]):
|
|
38
|
+
metadata_str = ", ".join(
|
|
39
|
+
f"{k}: {v}"
|
|
40
|
+
for k, v in doc.metadata.items()
|
|
41
|
+
if not k.startswith("_") and k not in ("rrf_score", "reranker_score")
|
|
42
|
+
)
|
|
43
|
+
content_preview = (
|
|
44
|
+
doc.page_content[:200] + "..."
|
|
45
|
+
if len(doc.page_content) > 200
|
|
46
|
+
else doc.page_content
|
|
47
|
+
)
|
|
48
|
+
summaries.append(f"{i + 1}. {content_preview}\n Metadata: {metadata_str}")
|
|
49
|
+
|
|
50
|
+
return "\n\n".join(summaries)
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def _format_constraints(constraints: list[str] | None) -> str:
|
|
54
|
+
"""Format constraints list for prompt."""
|
|
55
|
+
if not constraints:
|
|
56
|
+
return "No explicit constraints specified."
|
|
57
|
+
return "\n".join(f"- {c}" for c in constraints)
|
|
58
|
+
|
|
59
|
+
|
|
60
|
+
@mlflow.trace(name="verify_results", span_type=SpanType.LLM)
|
|
61
|
+
def verify_results(
|
|
62
|
+
llm: BaseChatModel,
|
|
63
|
+
query: str,
|
|
64
|
+
documents: list[Document],
|
|
65
|
+
schema_description: str,
|
|
66
|
+
constraints: list[str] | None = None,
|
|
67
|
+
previous_feedback: str | None = None,
|
|
68
|
+
) -> VerificationResult:
|
|
69
|
+
"""
|
|
70
|
+
Verify that search results satisfy user constraints.
|
|
71
|
+
|
|
72
|
+
Args:
|
|
73
|
+
llm: Language model for verification
|
|
74
|
+
query: User's original search query
|
|
75
|
+
documents: Retrieved documents to verify
|
|
76
|
+
schema_description: Column names, types, and filter syntax
|
|
77
|
+
constraints: Explicit constraints to verify
|
|
78
|
+
previous_feedback: Feedback from previous failed attempt (for retry)
|
|
79
|
+
|
|
80
|
+
Returns:
|
|
81
|
+
VerificationResult with pass/fail status and structured feedback
|
|
82
|
+
"""
|
|
83
|
+
prompt_config = _load_prompt_template()
|
|
84
|
+
prompt_template = prompt_config["template"]
|
|
85
|
+
|
|
86
|
+
prompt = prompt_template.format(
|
|
87
|
+
query=query,
|
|
88
|
+
schema_description=schema_description,
|
|
89
|
+
constraints=_format_constraints(constraints),
|
|
90
|
+
num_results=len(documents),
|
|
91
|
+
results_summary=_format_results_summary(documents),
|
|
92
|
+
previous_feedback=previous_feedback or "N/A (first attempt)",
|
|
93
|
+
)
|
|
94
|
+
|
|
95
|
+
logger.trace("Verifying results", query=query[:100], num_docs=len(documents))
|
|
96
|
+
|
|
97
|
+
# Use LangChain's with_structured_output for automatic strategy selection
|
|
98
|
+
# (JSON schema vs tool calling based on model capabilities)
|
|
99
|
+
try:
|
|
100
|
+
structured_llm: Runnable[str, VerificationResult] = llm.with_structured_output(
|
|
101
|
+
VerificationResult
|
|
102
|
+
)
|
|
103
|
+
result: VerificationResult = structured_llm.invoke(prompt)
|
|
104
|
+
except Exception as e:
|
|
105
|
+
logger.warning(
|
|
106
|
+
"Verifier failed, treating as passed with low confidence", error=str(e)
|
|
107
|
+
)
|
|
108
|
+
return VerificationResult(
|
|
109
|
+
passed=True,
|
|
110
|
+
confidence=0.0,
|
|
111
|
+
feedback="Verification failed to produce a valid result",
|
|
112
|
+
)
|
|
113
|
+
|
|
114
|
+
# Log for observability
|
|
115
|
+
mlflow.log_text(
|
|
116
|
+
json.dumps(result.model_dump(), indent=2),
|
|
117
|
+
"verification_result.json",
|
|
118
|
+
)
|
|
119
|
+
|
|
120
|
+
logger.debug(
|
|
121
|
+
"Verification complete",
|
|
122
|
+
passed=result.passed,
|
|
123
|
+
confidence=result.confidence,
|
|
124
|
+
unmet_constraints=result.unmet_constraints,
|
|
125
|
+
)
|
|
126
|
+
|
|
127
|
+
return result
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
def add_verification_metadata(
|
|
131
|
+
documents: list[Document],
|
|
132
|
+
result: VerificationResult,
|
|
133
|
+
exhausted: bool = False,
|
|
134
|
+
) -> list[Document]:
|
|
135
|
+
"""
|
|
136
|
+
Add verification metadata to documents.
|
|
137
|
+
|
|
138
|
+
Args:
|
|
139
|
+
documents: Documents to annotate
|
|
140
|
+
result: Verification result
|
|
141
|
+
exhausted: Whether max retries were exhausted
|
|
142
|
+
|
|
143
|
+
Returns:
|
|
144
|
+
Documents with verification metadata added
|
|
145
|
+
"""
|
|
146
|
+
status = "exhausted" if exhausted else ("passed" if result.passed else "failed")
|
|
147
|
+
|
|
148
|
+
annotated = []
|
|
149
|
+
for doc in documents:
|
|
150
|
+
metadata = {
|
|
151
|
+
**doc.metadata,
|
|
152
|
+
"_verification_status": status,
|
|
153
|
+
"_verification_confidence": result.confidence,
|
|
154
|
+
}
|
|
155
|
+
if result.feedback:
|
|
156
|
+
metadata["_verification_feedback"] = result.feedback
|
|
157
|
+
annotated.append(Document(page_content=doc.page_content, metadata=metadata))
|
|
158
|
+
|
|
159
|
+
return annotated
|
dao_ai/utils.py
CHANGED
|
@@ -1,17 +1,22 @@
|
|
|
1
1
|
import importlib
|
|
2
2
|
import importlib.metadata
|
|
3
|
+
import json
|
|
3
4
|
import os
|
|
4
5
|
import re
|
|
5
6
|
import site
|
|
6
7
|
from importlib.metadata import PackageNotFoundError, version
|
|
7
8
|
from pathlib import Path
|
|
8
|
-
from typing import Any, Callable, Sequence
|
|
9
|
+
from typing import Any, Callable, Sequence, TypeVar
|
|
9
10
|
|
|
11
|
+
from langchain_core.language_models import BaseChatModel
|
|
10
12
|
from langchain_core.tools import BaseTool
|
|
11
13
|
from loguru import logger
|
|
14
|
+
from pydantic import BaseModel
|
|
12
15
|
|
|
13
16
|
import dao_ai
|
|
14
17
|
|
|
18
|
+
T = TypeVar("T", bound=BaseModel)
|
|
19
|
+
|
|
15
20
|
|
|
16
21
|
def is_lib_provided(lib_name: str, pip_requirements: Sequence[str]) -> bool:
|
|
17
22
|
return any(
|
|
@@ -152,7 +157,7 @@ def get_installed_packages() -> dict[str, str]:
|
|
|
152
157
|
|
|
153
158
|
packages: Sequence[str] = [
|
|
154
159
|
f"databricks-agents=={version('databricks-agents')}",
|
|
155
|
-
f"databricks-langchain=={version('databricks-langchain')}",
|
|
160
|
+
f"databricks-langchain[memory]=={version('databricks-langchain')}",
|
|
156
161
|
f"databricks-mcp=={version('databricks-mcp')}",
|
|
157
162
|
f"databricks-sdk[openai]=={version('databricks-sdk')}",
|
|
158
163
|
f"ddgs=={version('ddgs')}",
|
|
@@ -322,3 +327,178 @@ def is_in_model_serving() -> bool:
|
|
|
322
327
|
return True
|
|
323
328
|
|
|
324
329
|
return False
|
|
330
|
+
|
|
331
|
+
|
|
332
|
+
def get_databricks_response_format(model_class: type[BaseModel]) -> dict[str, Any]:
|
|
333
|
+
"""Create a Databricks-compatible response_format for structured output.
|
|
334
|
+
|
|
335
|
+
Databricks requires the json_schema response format to have a 'name' field.
|
|
336
|
+
This function creates the properly formatted response_format dictionary
|
|
337
|
+
from a Pydantic model.
|
|
338
|
+
|
|
339
|
+
Args:
|
|
340
|
+
model_class: A Pydantic model class to use as the output schema
|
|
341
|
+
|
|
342
|
+
Returns:
|
|
343
|
+
A dictionary suitable for use with llm.bind(response_format=...)
|
|
344
|
+
|
|
345
|
+
Example:
|
|
346
|
+
>>> response_format = get_databricks_response_format(MyModel)
|
|
347
|
+
>>> bound_llm = llm.bind(response_format=response_format)
|
|
348
|
+
>>> result = bound_llm.invoke(prompt)
|
|
349
|
+
"""
|
|
350
|
+
schema = model_class.model_json_schema()
|
|
351
|
+
|
|
352
|
+
# Remove $defs from the schema - Databricks doesn't support complex refs
|
|
353
|
+
# We need to inline any referenced definitions
|
|
354
|
+
if "$defs" in schema:
|
|
355
|
+
schema = _inline_schema_defs(schema)
|
|
356
|
+
|
|
357
|
+
return {
|
|
358
|
+
"type": "json_schema",
|
|
359
|
+
"json_schema": {
|
|
360
|
+
"name": model_class.__name__,
|
|
361
|
+
"schema": schema,
|
|
362
|
+
"strict": True,
|
|
363
|
+
},
|
|
364
|
+
}
|
|
365
|
+
|
|
366
|
+
|
|
367
|
+
def _inline_schema_defs(schema: dict[str, Any]) -> dict[str, Any]:
|
|
368
|
+
"""Inline $defs references in a JSON schema.
|
|
369
|
+
|
|
370
|
+
Databricks doesn't support $ref and complex nested definitions,
|
|
371
|
+
so we need to inline them.
|
|
372
|
+
|
|
373
|
+
Args:
|
|
374
|
+
schema: The original JSON schema with $defs
|
|
375
|
+
|
|
376
|
+
Returns:
|
|
377
|
+
A schema with all references inlined
|
|
378
|
+
"""
|
|
379
|
+
defs = schema.pop("$defs", {})
|
|
380
|
+
if not defs:
|
|
381
|
+
return schema
|
|
382
|
+
|
|
383
|
+
def resolve_refs(obj: Any) -> Any:
|
|
384
|
+
if isinstance(obj, dict):
|
|
385
|
+
if "$ref" in obj:
|
|
386
|
+
# Extract the definition name from #/$defs/DefinitionName
|
|
387
|
+
ref_path = obj["$ref"]
|
|
388
|
+
if ref_path.startswith("#/$defs/"):
|
|
389
|
+
def_name = ref_path[len("#/$defs/") :]
|
|
390
|
+
if def_name in defs:
|
|
391
|
+
# Return a copy of the definition with refs resolved
|
|
392
|
+
return resolve_refs(defs[def_name].copy())
|
|
393
|
+
return obj
|
|
394
|
+
return {k: resolve_refs(v) for k, v in obj.items()}
|
|
395
|
+
elif isinstance(obj, list):
|
|
396
|
+
return [resolve_refs(item) for item in obj]
|
|
397
|
+
return obj
|
|
398
|
+
|
|
399
|
+
return resolve_refs(schema)
|
|
400
|
+
|
|
401
|
+
|
|
402
|
+
def _repair_json(content: str) -> str | None:
|
|
403
|
+
"""Attempt to repair malformed JSON from LLM output.
|
|
404
|
+
|
|
405
|
+
Handles common issues:
|
|
406
|
+
- Extra text before/after JSON object
|
|
407
|
+
- Truncated JSON (unclosed brackets/braces)
|
|
408
|
+
- Trailing commas
|
|
409
|
+
|
|
410
|
+
Args:
|
|
411
|
+
content: The potentially malformed JSON string
|
|
412
|
+
|
|
413
|
+
Returns:
|
|
414
|
+
Repaired JSON string if successful, None otherwise
|
|
415
|
+
"""
|
|
416
|
+
# 1. Extract JSON object if wrapped in extra text
|
|
417
|
+
start = content.find("{")
|
|
418
|
+
end = content.rfind("}")
|
|
419
|
+
if start == -1 or end == -1 or start >= end:
|
|
420
|
+
return None
|
|
421
|
+
content = content[start : end + 1]
|
|
422
|
+
|
|
423
|
+
# 2. Try parsing as-is first
|
|
424
|
+
try:
|
|
425
|
+
json.loads(content)
|
|
426
|
+
return content
|
|
427
|
+
except json.JSONDecodeError:
|
|
428
|
+
pass
|
|
429
|
+
|
|
430
|
+
# 3. Fix trailing commas before closing brackets
|
|
431
|
+
content = re.sub(r",\s*}", "}", content)
|
|
432
|
+
content = re.sub(r",\s*]", "]", content)
|
|
433
|
+
|
|
434
|
+
# 4. Try to close unclosed brackets/braces
|
|
435
|
+
open_braces = content.count("{") - content.count("}")
|
|
436
|
+
open_brackets = content.count("[") - content.count("]")
|
|
437
|
+
|
|
438
|
+
if open_braces > 0 or open_brackets > 0:
|
|
439
|
+
# Remove trailing comma if present
|
|
440
|
+
content = content.rstrip().rstrip(",")
|
|
441
|
+
content += "]" * open_brackets + "}" * open_braces
|
|
442
|
+
|
|
443
|
+
# 5. Final validation
|
|
444
|
+
try:
|
|
445
|
+
json.loads(content)
|
|
446
|
+
return content
|
|
447
|
+
except json.JSONDecodeError:
|
|
448
|
+
return None
|
|
449
|
+
|
|
450
|
+
|
|
451
|
+
def invoke_with_structured_output(
|
|
452
|
+
llm: BaseChatModel,
|
|
453
|
+
prompt: str,
|
|
454
|
+
model_class: type[T],
|
|
455
|
+
) -> T | None:
|
|
456
|
+
"""Invoke an LLM with Databricks-compatible structured output.
|
|
457
|
+
|
|
458
|
+
Uses response_format with json_schema type and proper 'name' field
|
|
459
|
+
as required by Databricks Foundation Model APIs.
|
|
460
|
+
|
|
461
|
+
Args:
|
|
462
|
+
llm: The language model to invoke
|
|
463
|
+
prompt: The prompt to send to the model
|
|
464
|
+
model_class: The Pydantic model class for the expected output
|
|
465
|
+
|
|
466
|
+
Returns:
|
|
467
|
+
An instance of model_class, or None if parsing fails
|
|
468
|
+
"""
|
|
469
|
+
response_format = get_databricks_response_format(model_class)
|
|
470
|
+
bound_llm = llm.bind(response_format=response_format)
|
|
471
|
+
|
|
472
|
+
response = bound_llm.invoke(prompt)
|
|
473
|
+
|
|
474
|
+
content = response.content
|
|
475
|
+
if not isinstance(content, str):
|
|
476
|
+
return None
|
|
477
|
+
|
|
478
|
+
try:
|
|
479
|
+
# Try parsing the JSON directly
|
|
480
|
+
result_dict = json.loads(content)
|
|
481
|
+
return model_class.model_validate(result_dict)
|
|
482
|
+
except json.JSONDecodeError as e:
|
|
483
|
+
# Attempt JSON repair
|
|
484
|
+
repaired = _repair_json(content)
|
|
485
|
+
if repaired:
|
|
486
|
+
try:
|
|
487
|
+
result_dict = json.loads(repaired)
|
|
488
|
+
logger.debug("JSON repair successful", model_class=model_class.__name__)
|
|
489
|
+
return model_class.model_validate(result_dict)
|
|
490
|
+
except (json.JSONDecodeError, Exception):
|
|
491
|
+
pass
|
|
492
|
+
logger.warning(
|
|
493
|
+
"Failed to parse structured output",
|
|
494
|
+
error=str(e),
|
|
495
|
+
model_class=model_class.__name__,
|
|
496
|
+
)
|
|
497
|
+
return None
|
|
498
|
+
except Exception as e:
|
|
499
|
+
logger.warning(
|
|
500
|
+
"Failed to parse structured output",
|
|
501
|
+
error=str(e),
|
|
502
|
+
model_class=model_class.__name__,
|
|
503
|
+
)
|
|
504
|
+
return None
|
dao_ai/vector_search.py
CHANGED
|
@@ -64,7 +64,12 @@ def index_exists(
|
|
|
64
64
|
return True
|
|
65
65
|
except Exception as e:
|
|
66
66
|
# Check if this is a "not exists" error or something else
|
|
67
|
-
|
|
67
|
+
# Handle both "RESOURCE_DOES_NOT_EXIST" and "does not exist" error patterns
|
|
68
|
+
error_str = str(e).lower()
|
|
69
|
+
if (
|
|
70
|
+
"does not exist" not in error_str
|
|
71
|
+
and "resource_does_not_exist" not in error_str
|
|
72
|
+
):
|
|
68
73
|
# For unexpected errors, provide a more helpful message
|
|
69
74
|
print(
|
|
70
75
|
"Unexpected error describing the index. This could be a permission issue."
|
|
@@ -72,3 +77,43 @@ def index_exists(
|
|
|
72
77
|
raise e
|
|
73
78
|
# If we reach here, the index doesn't exist
|
|
74
79
|
return False
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
def find_index(
|
|
83
|
+
vsc: VectorSearchClient, index_full_name: str
|
|
84
|
+
) -> tuple[bool, str | None]:
|
|
85
|
+
"""
|
|
86
|
+
Find a Vector Search index across all endpoints.
|
|
87
|
+
|
|
88
|
+
Searches all available endpoints to find where the index is located.
|
|
89
|
+
|
|
90
|
+
Args:
|
|
91
|
+
vsc: Databricks Vector Search client instance
|
|
92
|
+
index_full_name: Fully qualified name of the index (catalog.schema.index)
|
|
93
|
+
|
|
94
|
+
Returns:
|
|
95
|
+
Tuple of (exists: bool, endpoint_name: str | None)
|
|
96
|
+
- (True, endpoint_name) if index is found
|
|
97
|
+
- (False, None) if index is not found on any endpoint
|
|
98
|
+
"""
|
|
99
|
+
try:
|
|
100
|
+
endpoints = vsc.list_endpoints().get("endpoints", [])
|
|
101
|
+
except Exception as e:
|
|
102
|
+
if "REQUEST_LIMIT_EXCEEDED" in str(e):
|
|
103
|
+
print("WARN: couldn't list endpoints due to REQUEST_LIMIT_EXCEEDED error.")
|
|
104
|
+
return (False, None)
|
|
105
|
+
raise e
|
|
106
|
+
|
|
107
|
+
for endpoint in endpoints:
|
|
108
|
+
endpoint_name: str = endpoint["name"]
|
|
109
|
+
try:
|
|
110
|
+
vsc.get_index(endpoint_name, index_full_name).describe()
|
|
111
|
+
return (True, endpoint_name)
|
|
112
|
+
except Exception:
|
|
113
|
+
# Index not on this endpoint, try next
|
|
114
|
+
# Catches both "does not exist" and "RESOURCE_DOES_NOT_EXIST" errors,
|
|
115
|
+
# as well as other errors (permission issues, etc.) - we continue
|
|
116
|
+
# searching other endpoints regardless of error type
|
|
117
|
+
continue
|
|
118
|
+
|
|
119
|
+
return (False, None)
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: dao-ai
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.20
|
|
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
|
|
@@ -26,9 +26,9 @@ Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
|
26
26
|
Classifier: Topic :: System :: Distributed Computing
|
|
27
27
|
Requires-Python: >=3.11
|
|
28
28
|
Requires-Dist: databricks-agents>=1.9.0
|
|
29
|
-
Requires-Dist: databricks-langchain[memory]>=0.
|
|
29
|
+
Requires-Dist: databricks-langchain[memory]>=0.13.0
|
|
30
30
|
Requires-Dist: databricks-mcp>=0.5.0
|
|
31
|
-
Requires-Dist: databricks-sdk[openai]>=0.
|
|
31
|
+
Requires-Dist: databricks-sdk[openai]>=0.77.0
|
|
32
32
|
Requires-Dist: ddgs>=9.10.0
|
|
33
33
|
Requires-Dist: dspy>=2.6.27
|
|
34
34
|
Requires-Dist: flashrank>=0.2.10
|
|
@@ -43,7 +43,7 @@ Requires-Dist: langgraph>=1.0.5
|
|
|
43
43
|
Requires-Dist: langmem>=0.0.30
|
|
44
44
|
Requires-Dist: loguru>=0.7.3
|
|
45
45
|
Requires-Dist: mcp>=1.24.0
|
|
46
|
-
Requires-Dist: mlflow>=3.8.1
|
|
46
|
+
Requires-Dist: mlflow[databricks]>=3.8.1
|
|
47
47
|
Requires-Dist: nest-asyncio>=1.6.0
|
|
48
48
|
Requires-Dist: openevals>=0.1.3
|
|
49
49
|
Requires-Dist: openpyxl>=3.1.5
|
|
@@ -79,7 +79,7 @@ Description-Content-Type: text/markdown
|
|
|
79
79
|
|
|
80
80
|
# DAO: Declarative Agent Orchestration
|
|
81
81
|
|
|
82
|
-
[](CHANGELOG.md)
|
|
83
83
|
[](https://www.python.org/)
|
|
84
84
|
[](LICENSE)
|
|
85
85
|
|
|
@@ -125,7 +125,7 @@ DAO AI Builder generates valid YAML configurations that work seamlessly with thi
|
|
|
125
125
|
- **[Architecture](docs/architecture.md)** - Understand how DAO works under the hood
|
|
126
126
|
|
|
127
127
|
### Core Concepts
|
|
128
|
-
- **[Key Capabilities](docs/key-capabilities.md)** - Explore
|
|
128
|
+
- **[Key Capabilities](docs/key-capabilities.md)** - Explore 15 powerful features for production agents
|
|
129
129
|
- **[Configuration Reference](docs/configuration-reference.md)** - Complete YAML configuration guide
|
|
130
130
|
- **[Examples](docs/examples.md)** - Ready-to-use example configurations
|
|
131
131
|
|
|
@@ -148,7 +148,7 @@ Before you begin, you'll need:
|
|
|
148
148
|
- **Python 3.11 or newer** installed on your computer ([download here](https://www.python.org/downloads/))
|
|
149
149
|
- **A Databricks workspace** (ask your IT team or see [Databricks docs](https://docs.databricks.com/))
|
|
150
150
|
- Access to **Unity Catalog** (your organization's data catalog)
|
|
151
|
-
- **Model Serving** enabled (for deploying AI agents)
|
|
151
|
+
- **Model Serving** or **Databricks Apps** enabled (for deploying AI agents)
|
|
152
152
|
- *Optional*: Vector Search, Genie (for advanced features)
|
|
153
153
|
|
|
154
154
|
**Not sure if you have access?** Your Databricks administrator can grant you permissions.
|
|
@@ -235,7 +235,7 @@ app:
|
|
|
235
235
|
- *assistant
|
|
236
236
|
orchestration:
|
|
237
237
|
swarm:
|
|
238
|
-
|
|
238
|
+
default_agent: *assistant
|
|
239
239
|
```
|
|
240
240
|
|
|
241
241
|
**💡 What's happening here?**
|
|
@@ -293,6 +293,16 @@ This single command:
|
|
|
293
293
|
3. Deploys it to Databricks
|
|
294
294
|
4. Creates a serving endpoint
|
|
295
295
|
|
|
296
|
+
**Deploying to a specific workspace:**
|
|
297
|
+
|
|
298
|
+
```bash
|
|
299
|
+
# Deploy to AWS workspace
|
|
300
|
+
dao-ai bundle --deploy --run -c config/my_agent.yaml --profile aws-field-eng
|
|
301
|
+
|
|
302
|
+
# Deploy to Azure workspace
|
|
303
|
+
dao-ai bundle --deploy --run -c config/my_agent.yaml --profile azure-retail
|
|
304
|
+
```
|
|
305
|
+
|
|
296
306
|
**Step 5: Interact with your agent**
|
|
297
307
|
|
|
298
308
|
Once deployed, you can chat with your agent using Python:
|
|
@@ -335,6 +345,7 @@ DAO provides powerful capabilities for building production-ready AI agents:
|
|
|
335
345
|
|
|
336
346
|
| Feature | Description |
|
|
337
347
|
|---------|-------------|
|
|
348
|
+
| **Dual Deployment Targets** | Deploy to Databricks Model Serving or Databricks Apps with a single config |
|
|
338
349
|
| **Multi-Tool Support** | Python functions, Unity Catalog, MCP, Agent Endpoints |
|
|
339
350
|
| **On-Behalf-Of User** | Per-user permissions and governance |
|
|
340
351
|
| **Advanced Caching** | Two-tier (LRU + Semantic) caching for cost optimization |
|
|
@@ -398,7 +409,8 @@ The `config/examples/` directory contains ready-to-use configurations organized
|
|
|
398
409
|
|
|
399
410
|
- `01_getting_started/minimal.yaml` - Simplest possible agent
|
|
400
411
|
- `02_tools/vector_search_with_reranking.yaml` - RAG with improved accuracy
|
|
401
|
-
- `04_genie/genie_semantic_cache.yaml` - NL-to-SQL with
|
|
412
|
+
- `04_genie/genie_semantic_cache.yaml` - NL-to-SQL with PostgreSQL semantic caching
|
|
413
|
+
- `04_genie/genie_in_memory_semantic_cache.yaml` - NL-to-SQL with in-memory semantic caching (no database)
|
|
402
414
|
- `05_memory/conversation_summarization.yaml` - Long conversation handling
|
|
403
415
|
- `06_on_behalf_of_user/obo_basic.yaml` - User-level access control
|
|
404
416
|
- `07_human_in_the_loop/human_in_the_loop.yaml` - Approval workflows
|
|
@@ -422,10 +434,34 @@ dao-ai graph -c config/my_config.yaml -o workflow.png
|
|
|
422
434
|
# Deploy with Databricks Asset Bundles
|
|
423
435
|
dao-ai bundle --deploy --run -c config/my_config.yaml
|
|
424
436
|
|
|
437
|
+
# Deploy to a specific workspace (multi-cloud support)
|
|
438
|
+
dao-ai bundle --deploy -c config/my_config.yaml --profile aws-field-eng
|
|
439
|
+
dao-ai bundle --deploy -c config/my_config.yaml --profile azure-retail
|
|
440
|
+
|
|
425
441
|
# Interactive chat with agent
|
|
426
442
|
dao-ai chat -c config/my_config.yaml
|
|
427
443
|
```
|
|
428
444
|
|
|
445
|
+
### Multi-Cloud Deployment
|
|
446
|
+
|
|
447
|
+
DAO AI supports deploying to Azure, AWS, and GCP workspaces with automatic cloud detection:
|
|
448
|
+
|
|
449
|
+
```bash
|
|
450
|
+
# Deploy to AWS workspace
|
|
451
|
+
dao-ai bundle --deploy -c config/my_config.yaml --profile aws-prod
|
|
452
|
+
|
|
453
|
+
# Deploy to Azure workspace
|
|
454
|
+
dao-ai bundle --deploy -c config/my_config.yaml --profile azure-prod
|
|
455
|
+
|
|
456
|
+
# Deploy to GCP workspace
|
|
457
|
+
dao-ai bundle --deploy -c config/my_config.yaml --profile gcp-prod
|
|
458
|
+
```
|
|
459
|
+
|
|
460
|
+
The CLI automatically:
|
|
461
|
+
- Detects the cloud provider from your profile's workspace URL
|
|
462
|
+
- Selects appropriate compute node types for each cloud
|
|
463
|
+
- Creates isolated deployment state per profile
|
|
464
|
+
|
|
429
465
|
👉 **Learn more:** [CLI Reference Documentation](docs/cli-reference.md)
|
|
430
466
|
|
|
431
467
|
---
|
|
@@ -0,0 +1,89 @@
|
|
|
1
|
+
dao_ai/__init__.py,sha256=18P98ExEgUaJ1Byw440Ct1ty59v6nxyWtc5S6Uq2m9Q,1062
|
|
2
|
+
dao_ai/catalog.py,sha256=sPZpHTD3lPx4EZUtIWeQV7VQM89WJ6YH__wluk1v2lE,4947
|
|
3
|
+
dao_ai/cli.py,sha256=7hVCC8mn9S3c4wW-eRt-WoFKzV1wPdJVAeNhkyhfUGc,53251
|
|
4
|
+
dao_ai/config.py,sha256=08eHf7HzXNEsFY1_-lCESCtC-RhEZy9nikTiWPmc25A,156770
|
|
5
|
+
dao_ai/evaluation.py,sha256=4dveWDwFnUxaybswr0gag3ydZ5RGVCTRaiE3eKLClD4,18161
|
|
6
|
+
dao_ai/graph.py,sha256=1-uQlo7iXZQTT3uU8aYu0N5rnhw5_g_2YLwVsAs6M-U,1119
|
|
7
|
+
dao_ai/logging.py,sha256=lYy4BmucCHvwW7aI3YQkQXKJtMvtTnPDu9Hnd7_O4oc,1556
|
|
8
|
+
dao_ai/messages.py,sha256=4ZBzO4iFdktGSLrmhHzFjzMIt2tpaL-aQLHOQJysGnY,6959
|
|
9
|
+
dao_ai/models.py,sha256=NaHj91Gra4M8thlKX1DSufLqtJfZSZ55lm1H1dJL_O8,77320
|
|
10
|
+
dao_ai/nodes.py,sha256=H7_C0ev0TpS5KWkGZD6eE4Wn6ouBwnN5HgYUyBeKe0A,10881
|
|
11
|
+
dao_ai/optimization.py,sha256=phK6t4wYmWPObCjGUBHdZzsaFXGhQOjhAek2bAEfwXo,22971
|
|
12
|
+
dao_ai/state.py,sha256=ifDTAC7epdowk3Z1CP3Xqw4uH2dIxQEVF3C747dA8yI,6436
|
|
13
|
+
dao_ai/types.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
14
|
+
dao_ai/utils.py,sha256=ImgH0jnHPCK2AR7KcueG_Zb7kltcBzTw78ujDUpARIE,17184
|
|
15
|
+
dao_ai/vector_search.py,sha256=PfmT2PDMymk-3dTm2uszlOZNyHyiDge--imxKpKJRsY,4440
|
|
16
|
+
dao_ai/apps/__init__.py,sha256=RLuhZf4gQ4pemwKDz1183aXib8UfaRhwfKvRx68GRlM,661
|
|
17
|
+
dao_ai/apps/handlers.py,sha256=6-IhhklHSPnS8aqKp155wPaSnYWTU1BSOPwbdWYBkFU,3594
|
|
18
|
+
dao_ai/apps/model_serving.py,sha256=XLt3_0pGSRceMK6YtOrND9Jnh7mKLPCtwjVDLIaptQU,847
|
|
19
|
+
dao_ai/apps/resources.py,sha256=5l6UxfMq6uspOql-HNDyUikfqRAa9eH_TiJHrGgMb6s,40029
|
|
20
|
+
dao_ai/apps/server.py,sha256=neWbVnC2z9f-tJZBnho70FytNDEVOdOM1YngoGc5KHI,1264
|
|
21
|
+
dao_ai/genie/__init__.py,sha256=UpSvP6gZO8H-eAPokYpkshvFxYD4ETYZHz-pRPoK2sI,2786
|
|
22
|
+
dao_ai/genie/core.py,sha256=eKZo4pRagwI6QglAXqHYjUaC3AicmGMiy_9WIuZ-tzw,9119
|
|
23
|
+
dao_ai/genie/cache/__init__.py,sha256=hMD2q7VRX8fQmkd4rXhxGJdRIVbDqLh2DyjBu0CdM_k,2129
|
|
24
|
+
dao_ai/genie/cache/base.py,sha256=nbWl-KTstUPGagdUtO8xtVUSosuqkaNc_hx-PgT1ROo,7155
|
|
25
|
+
dao_ai/genie/cache/core.py,sha256=48sDY7dbrsmflb96OFEE8DYarNB6zyiFxZQG-qfhXD4,2537
|
|
26
|
+
dao_ai/genie/cache/lru.py,sha256=dWoNottME8y6y_OKnQZ1xH4NmQxk2PdXvUgKcdzjlxI,19935
|
|
27
|
+
dao_ai/genie/cache/optimization.py,sha256=8tyMrthHCxdOdvqDwGnGAvRNCWk9e0nIb3dJkE05t-4,30167
|
|
28
|
+
dao_ai/genie/cache/context_aware/__init__.py,sha256=EaW2CmWxb0CDNcm3pKL6Vyaw2KuwanKV1LiFVlT2M-s,1197
|
|
29
|
+
dao_ai/genie/cache/context_aware/base.py,sha256=o3S3f0B0jCB7vjb2XKWm5hFcO6v-jNYc6ZELyBkeBrg,40452
|
|
30
|
+
dao_ai/genie/cache/context_aware/in_memory.py,sha256=Z-ZrMTVD1pjC55irhodBWsrs6D2h3Sv-Iifk0Cr1mRo,22316
|
|
31
|
+
dao_ai/genie/cache/context_aware/persistent.py,sha256=cpn25Go6ZyN65lY_vh5cWcuqr__nNH7RPWJA_LP7wcE,28154
|
|
32
|
+
dao_ai/genie/cache/context_aware/postgres.py,sha256=cakJuba3dFjKoEHlpBYgmr3pEuM88dM8ambgL6Vq_54,46403
|
|
33
|
+
dao_ai/hooks/__init__.py,sha256=uA4DQdP9gDf4SyNjNx9mWPoI8UZOcTyFsCXV0NraFvQ,463
|
|
34
|
+
dao_ai/hooks/core.py,sha256=yZAfRfB0MyMo--uwGr4STtVxxen5s4ZUrNTnR3a3qkA,1721
|
|
35
|
+
dao_ai/memory/__init__.py,sha256=Us3wFehvug_h83m-UJ7OXdq2qZ0e9nHBQE7m5RwoAd8,559
|
|
36
|
+
dao_ai/memory/base.py,sha256=99nfr2UZJ4jmfTL_KrqUlRSCoRxzkZyWyx5WqeUoMdQ,338
|
|
37
|
+
dao_ai/memory/core.py,sha256=38H-JLIyUrRDIECLvpXK3iJlWG35X97E-DTo_4c3Jzc,6317
|
|
38
|
+
dao_ai/memory/databricks.py,sha256=SM6nwLjhSRJO4hLc3GUuht5YydYtTi3BAOae6jPwTm4,14377
|
|
39
|
+
dao_ai/memory/postgres.py,sha256=bSjtvEht0h6jy2ADN2vqISVQDxm_DeM586VDdGaShJQ,23168
|
|
40
|
+
dao_ai/middleware/__init__.py,sha256=Qy8wbvjXF7TrUzi3tWziOwxqsrUcT1rzE3UWd3x5CrU,5108
|
|
41
|
+
dao_ai/middleware/assertions.py,sha256=C1K-TnNZfBEwWouioHCt6c48i1ux9QKfQaX6AzghhgE,27408
|
|
42
|
+
dao_ai/middleware/base.py,sha256=uG2tpdnjL5xY5jCKvb_m3UTBtl4ZC6fJQUkDsQvV8S4,1279
|
|
43
|
+
dao_ai/middleware/context_editing.py,sha256=5rNKqH1phFFQTVW-4nzlVH5cbqomD-HFEIy2Z841D4I,7687
|
|
44
|
+
dao_ai/middleware/core.py,sha256=XFzL-A1_jS_pUCw7Q-z1WD0gutmpWZhfCMqHI6ifbhA,2096
|
|
45
|
+
dao_ai/middleware/guardrails.py,sha256=wjH4OwDRagkrKpcGNf7_bf3eJhtMpIWK_RIrrvMeqDs,14023
|
|
46
|
+
dao_ai/middleware/human_in_the_loop.py,sha256=YS11oQcRVzHVuZi309tuXfB4ItGuOz-PRT0fXwupdsY,7537
|
|
47
|
+
dao_ai/middleware/message_validation.py,sha256=SGvXow76BB1eW8zDSSuLJgRkIvLU-WOwA1Cd5_DatmQ,19818
|
|
48
|
+
dao_ai/middleware/model_call_limit.py,sha256=sxv15iNOUMjVLTEXwMBR5zAkxkWbnysbSIsBcuJbNUI,2216
|
|
49
|
+
dao_ai/middleware/model_retry.py,sha256=SlWjAcaEmvj6KBOkjUicChYjhlg7bAJM7-e6KLpHS9Q,3908
|
|
50
|
+
dao_ai/middleware/pii.py,sha256=zetfoz1WlJ-V0vjJp37v8NGimXB27EkZfetUHpGCXno,5137
|
|
51
|
+
dao_ai/middleware/summarization.py,sha256=gp2s9uc4DEJat-mWjWEzMaR-zAAeUOXYvu5EEYtqae4,7143
|
|
52
|
+
dao_ai/middleware/tool_call_limit.py,sha256=WQ3NmA3pLo-pNPBmwM7KwkYpT1segEnWqkhgW1xNkCE,6321
|
|
53
|
+
dao_ai/middleware/tool_retry.py,sha256=QfJ7yTHneME8VtnA88QcmnjXIegSFeJztyngy49wTgM,5568
|
|
54
|
+
dao_ai/middleware/tool_selector.py,sha256=POj72YdzZEiNGfW4AQXPBeVVS1RUBsiG7PBuSENEhe0,4516
|
|
55
|
+
dao_ai/orchestration/__init__.py,sha256=i85CLfRR335NcCFhaXABcMkn6WZfXnJ8cHH4YZsZN0s,1622
|
|
56
|
+
dao_ai/orchestration/core.py,sha256=8bPigzWtHUZ0Gw4Q_91uvcREucVQstxlelC06W_qmn0,10683
|
|
57
|
+
dao_ai/orchestration/supervisor.py,sha256=FoQ1fYP_e0taKC4ByITqJLOYvwJd1zecYYLs4RcY1lk,10605
|
|
58
|
+
dao_ai/orchestration/swarm.py,sha256=BloDI0TWhGisv9r3-zTgJWZQy9l3hbQ5tXYggovr5i8,9467
|
|
59
|
+
dao_ai/prompts/__init__.py,sha256=r91BY_yq28iUL0Pz5NbMo1VEDQh-aE44GqN0tBrIKfc,3011
|
|
60
|
+
dao_ai/prompts/instructed_retriever_decomposition.yaml,sha256=OkBLLlgU8MXtvGPlhESXgFfwYCUGRDcyD8O1iWOsmbk,2107
|
|
61
|
+
dao_ai/prompts/instruction_reranker.yaml,sha256=4OGZLNbdcWk6slBY5vnt_C-nGLPZM6e21smTNyaRPmE,406
|
|
62
|
+
dao_ai/prompts/router.yaml,sha256=79C_O98cpNndeMO0Vdn91CC7vxZx0hZ1rl1BAgnGjYc,1319
|
|
63
|
+
dao_ai/prompts/verifier.yaml,sha256=9snFQuxfYuEr46F4gv13VqL9q2PJCtWlbBhN3_IO2zI,1455
|
|
64
|
+
dao_ai/providers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
65
|
+
dao_ai/providers/base.py,sha256=cJGo3UjUTPgS91dv38ePOHwQQtYhIa84ebb167CBXjk,2111
|
|
66
|
+
dao_ai/providers/databricks.py,sha256=cg-TY9IS3-OqIo1gkLe1YwOR1H-s8YTBGrqDrkOWR6c,73569
|
|
67
|
+
dao_ai/tools/__init__.py,sha256=4dX_N6G_WrkV2BhS7hN8tR9zrMNlorLTKQYM388KTR4,1758
|
|
68
|
+
dao_ai/tools/agent.py,sha256=plIWALywRjaDSnot13nYehBsrHRpBUpsVZakoGeajOE,1858
|
|
69
|
+
dao_ai/tools/core.py,sha256=bRIN3BZhRQX8-Kpu3HPomliodyskCqjxynQmYbk6Vjs,3783
|
|
70
|
+
dao_ai/tools/email.py,sha256=A3TsCoQgJR7UUWR0g45OPRGDpVoYwctFs1MOZMTt_d4,7389
|
|
71
|
+
dao_ai/tools/genie.py,sha256=MWW2nCutl5-Wxwt4m7AxrS0ufqZimTKXa-lbojhwRYQ,12219
|
|
72
|
+
dao_ai/tools/instructed_retriever.py,sha256=iEu7oH1Z9_-Id0SMaq-dAgCNigeRrJDDTSZTcOJLl6k,12990
|
|
73
|
+
dao_ai/tools/instruction_reranker.py,sha256=_1kGwrXkJk4QR2p8n3lAaYkUVoidxCxV9wNCtoS0qco,6730
|
|
74
|
+
dao_ai/tools/mcp.py,sha256=4uvag52OJPInUEnxFLwpE0JRugTrgHeWbkP5lzIx4lg,22620
|
|
75
|
+
dao_ai/tools/memory.py,sha256=lwObKimAand22Nq3Y63tsv-AXQ5SXUigN9PqRjoWKes,1836
|
|
76
|
+
dao_ai/tools/python.py,sha256=jWFnZPni2sCdtd8D1CqXnZIPHnWkdK27bCJnBXpzhvo,1879
|
|
77
|
+
dao_ai/tools/router.py,sha256=YIVzSk4-ZFQHgvkhyrPHGLbDyzE9koa5QmbcTT-npnI,2872
|
|
78
|
+
dao_ai/tools/search.py,sha256=cJ3D9FKr1GAR6xz55dLtRkjtQsI0WRueGt9TPDFpOxc,433
|
|
79
|
+
dao_ai/tools/slack.py,sha256=QnMsA7cYD1MnEcqGqqSr6bKIhV0RgDpkyaiPmDqnAts,5433
|
|
80
|
+
dao_ai/tools/sql.py,sha256=FG-Aa0FAUAnhCuZvao1J-y-cMM6bU5eCujNbsYn0xDw,7864
|
|
81
|
+
dao_ai/tools/time.py,sha256=tufJniwivq29y0LIffbgeBTIDE6VgrLpmVf8Qr90qjw,9224
|
|
82
|
+
dao_ai/tools/unity_catalog.py,sha256=oBlW6pH-Ne08g60QW9wVi_tyeVYDiecuNoxQbIIFmN8,16515
|
|
83
|
+
dao_ai/tools/vector_search.py,sha256=34uhd58FKHzvcdgHHoACRdZAUJWTaUuPYiwIqBwvGqk,29061
|
|
84
|
+
dao_ai/tools/verifier.py,sha256=ociBVsGkQNyhWS6F6G8x17V7zAQfSuTe4Xcd6Y-7lPE,4975
|
|
85
|
+
dao_ai-0.1.20.dist-info/METADATA,sha256=v-u8GWz1AnJXLm1LfSMrD-cHZYT-nbyU57VNOxG9KWY,16954
|
|
86
|
+
dao_ai-0.1.20.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
|
|
87
|
+
dao_ai-0.1.20.dist-info/entry_points.txt,sha256=Xa-UFyc6gWGwMqMJOt06ZOog2vAfygV_DSwg1AiP46g,43
|
|
88
|
+
dao_ai-0.1.20.dist-info/licenses/LICENSE,sha256=YZt3W32LtPYruuvHE9lGk2bw6ZPMMJD8yLrjgHybyz4,1069
|
|
89
|
+
dao_ai-0.1.20.dist-info/RECORD,,
|
dao_ai/agent_as_code.py
DELETED
|
@@ -1,22 +0,0 @@
|
|
|
1
|
-
import mlflow
|
|
2
|
-
from mlflow.models import ModelConfig
|
|
3
|
-
from mlflow.pyfunc import ResponsesAgent
|
|
4
|
-
|
|
5
|
-
from dao_ai.config import AppConfig
|
|
6
|
-
from dao_ai.logging import configure_logging
|
|
7
|
-
|
|
8
|
-
mlflow.set_registry_uri("databricks-uc")
|
|
9
|
-
mlflow.set_tracking_uri("databricks")
|
|
10
|
-
|
|
11
|
-
mlflow.langchain.autolog()
|
|
12
|
-
|
|
13
|
-
model_config: ModelConfig = ModelConfig()
|
|
14
|
-
config: AppConfig = AppConfig(**model_config.to_dict())
|
|
15
|
-
|
|
16
|
-
log_level: str = config.app.log_level
|
|
17
|
-
|
|
18
|
-
configure_logging(level=log_level)
|
|
19
|
-
|
|
20
|
-
app: ResponsesAgent = config.as_responses_agent()
|
|
21
|
-
|
|
22
|
-
mlflow.models.set_model(app)
|