dao-ai 0.0.22__tar.gz → 0.0.23__tar.gz

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.
Files changed (352) hide show
  1. {dao_ai-0.0.22 → dao_ai-0.0.23}/PKG-INFO +26 -3
  2. {dao_ai-0.0.22 → dao_ai-0.0.23}/README.md +24 -2
  3. dao_ai-0.0.23/config/examples/mcp_with_uc_connection.yaml +109 -0
  4. dao_ai-0.0.23/config/examples/slack.yaml +69 -0
  5. {dao_ai-0.0.22 → dao_ai-0.0.23}/pyproject.toml +2 -1
  6. {dao_ai-0.0.22 → dao_ai-0.0.23}/requirements.txt +1 -0
  7. {dao_ai-0.0.22 → dao_ai-0.0.23}/schemas/model_config_schema.json +11 -0
  8. {dao_ai-0.0.22 → dao_ai-0.0.23}/src/dao_ai/config.py +5 -0
  9. {dao_ai-0.0.22 → dao_ai-0.0.23}/src/dao_ai/tools/__init__.py +2 -0
  10. dao_ai-0.0.23/src/dao_ai/tools/mcp.py +164 -0
  11. dao_ai-0.0.23/src/dao_ai/tools/slack.py +136 -0
  12. {dao_ai-0.0.22 → dao_ai-0.0.23}/src/dao_ai/utils.py +4 -0
  13. {dao_ai-0.0.22 → dao_ai-0.0.23}/tests/dao_ai/test_function_parsing.py +2 -1
  14. {dao_ai-0.0.22 → dao_ai-0.0.23}/tests/dao_ai/test_mcp.py +63 -1
  15. dao_ai-0.0.22/src/dao_ai/tools/mcp.py +0 -117
  16. {dao_ai-0.0.22 → dao_ai-0.0.23}/.gitignore +0 -0
  17. {dao_ai-0.0.22 → dao_ai-0.0.23}/.python-version +0 -0
  18. {dao_ai-0.0.22 → dao_ai-0.0.23}/CHANGELOG.md +0 -0
  19. {dao_ai-0.0.22 → dao_ai-0.0.23}/CONTRIBUTING.md +0 -0
  20. {dao_ai-0.0.22 → dao_ai-0.0.23}/LICENSE +0 -0
  21. {dao_ai-0.0.22 → dao_ai-0.0.23}/Makefile +0 -0
  22. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/Makefile +0 -0
  23. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/REFACTORING_SUMMARY.md +0 -0
  24. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/base-environment-serverless.yaml +0 -0
  25. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/demo_docs/BRAND_REP_DEMO_SUMMARY.md +0 -0
  26. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/demo_docs/demo_scripts/brand_rep_product_education_demo.md +0 -0
  27. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/demo_docs/demo_scripts/store_associate_ai_assistant_demo.md +0 -0
  28. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/demo_docs/demo_scripts/store_manager_alert_response_demo.md +0 -0
  29. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/development_workflows.md +0 -0
  30. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/docs/.gitkeep +0 -0
  31. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/docs/Makefile +0 -0
  32. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/docs/agent_implementation.mmd +0 -0
  33. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/docs/agent_tools_architecture.mmd +0 -0
  34. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/docs/agents-and-tools/agent-troubleshooting.md +0 -0
  35. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/docs/agents-and-tools/agents/agent-best-practices.md +0 -0
  36. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/docs/agents-and-tools/agents/agent-development-patterns.md +0 -0
  37. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/docs/agents-and-tools/agents/agent-performance.md +0 -0
  38. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/docs/agents-and-tools/agents/agent-quickstart.md +0 -0
  39. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/docs/agents-and-tools/ai-agents.md +0 -0
  40. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/docs/agents-and-tools/overview.md +0 -0
  41. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/docs/agents-and-tools/references/agent-reference.md +0 -0
  42. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/docs/agents-and-tools/references/tools-reference.md +0 -0
  43. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/docs/applications/streamlit-app.md +0 -0
  44. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/docs/architecture/overview.md +0 -0
  45. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/docs/architecture.mmd +0 -0
  46. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/docs/architecture.png +0 -0
  47. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/docs/customer_preparation_guide.md +0 -0
  48. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/docs/databricks_integration.mmd +0 -0
  49. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/docs/deployment/production.md +0 -0
  50. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/docs/development/contributing.md +0 -0
  51. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/docs/employee_tools_guide.md +0 -0
  52. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/docs/getting-started/installation.md +0 -0
  53. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/docs/getting-started/mkdocs-quickstart.md +0 -0
  54. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/docs/getting-started/quick-start.md +0 -0
  55. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/docs/index.md +0 -0
  56. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/docs/mkdocs.yml +0 -0
  57. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/docs/scenario_1_architecture.mmd +0 -0
  58. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/docs/scenario_1_flow.mmd +0 -0
  59. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/docs/setup-docs.sh +0 -0
  60. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/docs/task_assignment_workflow_guide.md +0 -0
  61. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/docs/tools/overview.md +0 -0
  62. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/examples/customer_preparation_workflow.py +0 -0
  63. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/examples/task_assignment_workflow.py +0 -0
  64. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/load-env.sh +0 -0
  65. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app/CSS_REFACTORING_SUMMARY.md +0 -0
  66. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app/DEMO_CONTROLS_RESTORED.md +0 -0
  67. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app/DEMO_IMPLEMENTATION_SUMMARY.md +0 -0
  68. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app/DEMO_QUICK_START.md +0 -0
  69. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app/Dockerfile +0 -0
  70. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app/HOMEPAGE_README.md +0 -0
  71. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app/Makefile +0 -0
  72. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app/README.md +0 -0
  73. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app/app.py +0 -0
  74. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app/app.yaml +0 -0
  75. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app/components/__init__.py +0 -0
  76. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app/components/backup_homepage.py +0 -0
  77. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app/components/chat.py +0 -0
  78. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app/components/enhanced_charts.py +0 -0
  79. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app/components/enhanced_navigation.py +0 -0
  80. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app/components/homepage/__init__.py +0 -0
  81. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app/components/homepage/associate/__init__.py +0 -0
  82. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app/components/homepage/associate/associate_homepage.py +0 -0
  83. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app/components/homepage/associate/dashboard_tab.py +0 -0
  84. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app/components/homepage/associate/my_tasks_tab.py +0 -0
  85. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app/components/homepage/associate/performance_tab.py +0 -0
  86. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app/components/homepage/associate/products_tab.py +0 -0
  87. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app/components/homepage/associate/schedule_tab.py +0 -0
  88. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app/components/homepage/common/__init__.py +0 -0
  89. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app/components/homepage/common/chat_integration.py +0 -0
  90. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app/components/homepage/common/kpi_summary.py +0 -0
  91. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app/components/homepage/common/notifications.py +0 -0
  92. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app/components/homepage/homepage.py +0 -0
  93. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app/components/homepage/store_manager/__init__.py +0 -0
  94. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app/components/homepage/store_manager/alerts_tab.py +0 -0
  95. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app/components/homepage/store_manager/analytics_tab.py +0 -0
  96. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app/components/homepage/store_manager/dashboard_tab.py +0 -0
  97. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app/components/homepage/store_manager/demo_alerts.py +0 -0
  98. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app/components/homepage/store_manager/inventory_tab.py +0 -0
  99. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app/components/homepage/store_manager/manager_homepage.py +0 -0
  100. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app/components/homepage/store_manager/operations_tab.py +0 -0
  101. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app/components/homepage/store_manager/team_tab.py +0 -0
  102. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app/components/homepage/vp_retail_operations/__init__.py +0 -0
  103. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app/components/homepage/vp_retail_operations/ai_insights_tab.py +0 -0
  104. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app/components/homepage/vp_retail_operations/executive_dashboard_tab.py +0 -0
  105. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app/components/homepage/vp_retail_operations/geographical_analysis_tab.py +0 -0
  106. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app/components/homepage/vp_retail_operations/performance_metrics_tab.py +0 -0
  107. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app/components/homepage/vp_retail_operations/strategic_insights_tab.py +0 -0
  108. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app/components/homepage/vp_retail_operations/vp_homepage.py +0 -0
  109. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app/components/metrics.py +0 -0
  110. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app/components/navigation.py +0 -0
  111. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app/components/oldhomepage.py +0 -0
  112. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app/components/styles.py +0 -0
  113. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app/config.yaml +0 -0
  114. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app/demo_docs/BRAND_REP_DEMO_SUMMARY.md +0 -0
  115. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app/demo_docs/comprehensive_demo_script.md +0 -0
  116. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app/demo_docs/demo_scripts/brand_rep_product_education_demo.md +0 -0
  117. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app/demo_docs/demo_scripts/store_associate_ai_assistant_demo.md +0 -0
  118. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app/demo_docs/demo_scripts/store_manager_alert_response_demo.md +0 -0
  119. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app/dev/README.md +0 -0
  120. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app/dev/__init__.py +0 -0
  121. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app/dev/components/__init__.py +0 -0
  122. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app/dev/components/dashboard_card.py +0 -0
  123. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app/dev/demo_alerts.py +0 -0
  124. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app/dev/examples/sample_dashboard.py +0 -0
  125. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app/pages/__init__.py +0 -0
  126. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app/pages/component_showcase.py +0 -0
  127. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app/pages/dev_playground.py +0 -0
  128. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app/pages/playground.py +0 -0
  129. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app/pages_wip/daily_operations.py +0 -0
  130. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app/pages_wip/inventory.py +0 -0
  131. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app/pages_wip/my_schedule.py +0 -0
  132. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app/pages_wip/my_tasks.py +0 -0
  133. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app/pages_wip/orders.py +0 -0
  134. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app/pages_wip/products_promotions.py +0 -0
  135. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app/pages_wip/staff.py +0 -0
  136. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app/pages_wip/team_insights.py +0 -0
  137. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app/pyproject.toml +0 -0
  138. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app/requirements.txt +0 -0
  139. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app/static/css/style.css +0 -0
  140. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app/styles/README.md +0 -0
  141. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app/styles/__init__.py +0 -0
  142. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app/styles/base.py +0 -0
  143. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app/styles/components.py +0 -0
  144. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app/styles/dashboard.py +0 -0
  145. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app/styles/homepage.py +0 -0
  146. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app/styles/theme.py +0 -0
  147. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app/test_vip_notification.py +0 -0
  148. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app/tests/test_calculations.py +0 -0
  149. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app/utils/config.py +0 -0
  150. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app/utils/database.py +0 -0
  151. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app/utils/model_serving.py +0 -0
  152. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app/utils/store_context.py +0 -0
  153. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app_tailadmin/Makefile +0 -0
  154. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app_tailadmin/README.md +0 -0
  155. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app_tailadmin/app.py +0 -0
  156. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app_tailadmin/components/tailadmin/__init__.py +0 -0
  157. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app_tailadmin/components/tailadmin/tailadmin/__init__.py +0 -0
  158. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app_tailadmin/components/tailadmin/tailadmin/tailadmin_components.py +0 -0
  159. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app_tailadmin/components/tailadmin/tailadmin/tailadmin_components_enhanced.py +0 -0
  160. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app_tailadmin/components/tailadmin/tailadmin/tailadmin_styles.py +0 -0
  161. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app_tailadmin/components/tailadmin/tailadmin_styles.py +0 -0
  162. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app_tailadmin/old/TAILADMIN_README.md +0 -0
  163. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app_tailadmin/old/homepage_tailadmin.py +0 -0
  164. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app_tailadmin/old/tailadmin_demo.py +0 -0
  165. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app_tailadmin/old/tailadmin_implementation_guide.py +0 -0
  166. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app_tailadmin/old/test_vp_dashboard.py +0 -0
  167. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app_tailadmin/old/vp_dashboard_enhanced.py +0 -0
  168. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app_tailadmin/old/vp_dashboard_tailadmin.py +0 -0
  169. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app_tailadmin/pages/components_demo.py +0 -0
  170. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app_tailadmin/pages/homepage.py +0 -0
  171. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app_tailadmin/pages/implementation_guide.py +0 -0
  172. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app_tailadmin/pages/vp_dashboard_clean.py +0 -0
  173. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app_tailadmin/pages/vp_dashboard_enhanced.py +0 -0
  174. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app_tailadmin/pyproject.toml +0 -0
  175. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app_tailadmin/tests/__init__.py +0 -0
  176. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/streamlit_store_app_tailadmin/tests/test_imports.py +0 -0
  177. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/tests/.gitkeep +0 -0
  178. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/tests/README.md +0 -0
  179. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/tests/images/doritos_upc.png +0 -0
  180. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/tests/images/lays_upc.png +0 -0
  181. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/tests/manager_demo_script.md +0 -0
  182. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/tests/notebook_vector_search_test.py +0 -0
  183. {dao_ai-0.0.22 → dao_ai-0.0.23}/apps/dais2025/store-app/tests/test_vector_search_integration.py +0 -0
  184. {dao_ai-0.0.22 → dao_ai-0.0.23}/config/dais2025/model_config_dais.yaml +0 -0
  185. {dao_ai-0.0.22 → dao_ai-0.0.23}/config/examples/deep_research.yaml +0 -0
  186. {dao_ai-0.0.22 → dao_ai-0.0.23}/config/examples/executive_assistant.yaml +0 -0
  187. {dao_ai-0.0.22 → dao_ai-0.0.23}/config/examples/genie.yaml +0 -0
  188. {dao_ai-0.0.22 → dao_ai-0.0.23}/config/examples/genie_and_vector_search.yaml +0 -0
  189. {dao_ai-0.0.22 → dao_ai-0.0.23}/config/examples/genie_with_conversion_id.yaml +0 -0
  190. {dao_ai-0.0.22 → dao_ai-0.0.23}/config/examples/human_in_the_loop.yaml +0 -0
  191. {dao_ai-0.0.22 → dao_ai-0.0.23}/config/examples/jira.yaml +0 -0
  192. {dao_ai-0.0.22 → dao_ai-0.0.23}/config/examples/mcp.yaml +0 -0
  193. {dao_ai-0.0.22 → dao_ai-0.0.23}/config/examples/minimal.yaml +0 -0
  194. {dao_ai-0.0.22 → dao_ai-0.0.23}/config/examples/reservations.yaml +0 -0
  195. {dao_ai-0.0.22 → dao_ai-0.0.23}/config/hardware_store/supervisor.yaml +0 -0
  196. {dao_ai-0.0.22 → dao_ai-0.0.23}/config/hardware_store/supervisor_postgres.yaml +0 -0
  197. {dao_ai-0.0.22 → dao_ai-0.0.23}/config/hardware_store/swarm.yaml +0 -0
  198. {dao_ai-0.0.22 → dao_ai-0.0.23}/config/quick_serve_restaurant/.gitkeep +0 -0
  199. {dao_ai-0.0.22 → dao_ai-0.0.23}/config/quick_serve_restaurant/quick-serve-restaurant.yaml +0 -0
  200. {dao_ai-0.0.22 → dao_ai-0.0.23}/data/dais2025/appointments.sql +0 -0
  201. {dao_ai-0.0.22 → dao_ai-0.0.23}/data/dais2025/appointments_data.sql +0 -0
  202. {dao_ai-0.0.22 → dao_ai-0.0.23}/data/dais2025/brand_rep_demo_data.sql +0 -0
  203. {dao_ai-0.0.22 → dao_ai-0.0.23}/data/dais2025/brand_rep_demo_queries.sql +0 -0
  204. {dao_ai-0.0.22 → dao_ai-0.0.23}/data/dais2025/brand_rep_demo_tables.sql +0 -0
  205. {dao_ai-0.0.22 → dao_ai-0.0.23}/data/dais2025/brand_rep_demo_validation.sql +0 -0
  206. {dao_ai-0.0.22 → dao_ai-0.0.23}/data/dais2025/customers.sql +0 -0
  207. {dao_ai-0.0.22 → dao_ai-0.0.23}/data/dais2025/customers_data.sql +0 -0
  208. {dao_ai-0.0.22 → dao_ai-0.0.23}/data/dais2025/dim_stores.sql +0 -0
  209. {dao_ai-0.0.22 → dao_ai-0.0.23}/data/dais2025/dim_stores_data.sql +0 -0
  210. {dao_ai-0.0.22 → dao_ai-0.0.23}/data/dais2025/employee_performance.sql +0 -0
  211. {dao_ai-0.0.22 → dao_ai-0.0.23}/data/dais2025/employee_performance_data.sql +0 -0
  212. {dao_ai-0.0.22 → dao_ai-0.0.23}/data/dais2025/employee_tasks.sql +0 -0
  213. {dao_ai-0.0.22 → dao_ai-0.0.23}/data/dais2025/employee_tasks_data.sql +0 -0
  214. {dao_ai-0.0.22 → dao_ai-0.0.23}/data/dais2025/inventory.sql +0 -0
  215. {dao_ai-0.0.22 → dao_ai-0.0.23}/data/dais2025/inventory_data.sql +0 -0
  216. {dao_ai-0.0.22 → dao_ai-0.0.23}/data/dais2025/managers.sql +0 -0
  217. {dao_ai-0.0.22 → dao_ai-0.0.23}/data/dais2025/managers_data.sql +0 -0
  218. {dao_ai-0.0.22 → dao_ai-0.0.23}/data/dais2025/product_data.sql +0 -0
  219. {dao_ai-0.0.22 → dao_ai-0.0.23}/data/dais2025/products.sql +0 -0
  220. {dao_ai-0.0.22 → dao_ai-0.0.23}/data/dais2025/task_assignments.sql +0 -0
  221. {dao_ai-0.0.22 → dao_ai-0.0.23}/data/hardware_store/inventory.snappy.parquet +0 -0
  222. {dao_ai-0.0.22 → dao_ai-0.0.23}/data/hardware_store/inventory.sql +0 -0
  223. {dao_ai-0.0.22 → dao_ai-0.0.23}/data/hardware_store/products.snappy.parquet +0 -0
  224. {dao_ai-0.0.22 → dao_ai-0.0.23}/data/hardware_store/products.sql +0 -0
  225. {dao_ai-0.0.22 → dao_ai-0.0.23}/data/quick_serve_restaurant/.gitkeep +0 -0
  226. {dao_ai-0.0.22 → dao_ai-0.0.23}/data/quick_serve_restaurant/fulfil_item_orders.sql +0 -0
  227. {dao_ai-0.0.22 → dao_ai-0.0.23}/data/quick_serve_restaurant/items_description.csv +0 -0
  228. {dao_ai-0.0.22 → dao_ai-0.0.23}/data/quick_serve_restaurant/items_description.sql +0 -0
  229. {dao_ai-0.0.22 → dao_ai-0.0.23}/data/quick_serve_restaurant/items_raw.csv +0 -0
  230. {dao_ai-0.0.22 → dao_ai-0.0.23}/data/quick_serve_restaurant/items_raw.sql +0 -0
  231. {dao_ai-0.0.22 → dao_ai-0.0.23}/data/quick_serve_restaurant/orders_raw.csv +0 -0
  232. {dao_ai-0.0.22 → dao_ai-0.0.23}/data/quick_serve_restaurant/orders_raw.sql +0 -0
  233. {dao_ai-0.0.22 → dao_ai-0.0.23}/databricks.yaml +0 -0
  234. {dao_ai-0.0.22 → dao_ai-0.0.23}/docs/genie.png +0 -0
  235. {dao_ai-0.0.22 → dao_ai-0.0.23}/docs/hardware_store/README.md +0 -0
  236. {dao_ai-0.0.22 → dao_ai-0.0.23}/docs/hardware_store/retail_supervisor.png +0 -0
  237. {dao_ai-0.0.22 → dao_ai-0.0.23}/docs/hardware_store/retail_swarm.png +0 -0
  238. {dao_ai-0.0.22 → dao_ai-0.0.23}/docs/quick_serve_restaurant/.gitkeep +0 -0
  239. {dao_ai-0.0.22 → dao_ai-0.0.23}/docs/quick_serve_restaurant/quick-serve-restaurant.png +0 -0
  240. {dao_ai-0.0.22 → dao_ai-0.0.23}/environment.yaml +0 -0
  241. {dao_ai-0.0.22 → dao_ai-0.0.23}/examples/dais2025/examples.yaml +0 -0
  242. {dao_ai-0.0.22 → dao_ai-0.0.23}/examples/deep_research/examples.yaml +0 -0
  243. {dao_ai-0.0.22 → dao_ai-0.0.23}/examples/executive_assistant/examples.yaml +0 -0
  244. {dao_ai-0.0.22 → dao_ai-0.0.23}/examples/hardware_store/examples.yaml +0 -0
  245. {dao_ai-0.0.22 → dao_ai-0.0.23}/examples/quick_serve_restaurant/.gitkeep +0 -0
  246. {dao_ai-0.0.22 → dao_ai-0.0.23}/examples/quick_serve_restaurant/examples.yaml +0 -0
  247. {dao_ai-0.0.22 → dao_ai-0.0.23}/functions/dais2025/extract_store_numbers.sql +0 -0
  248. {dao_ai-0.0.22 → dao_ai-0.0.23}/functions/dais2025/find_inventory_by_sku.sql +0 -0
  249. {dao_ai-0.0.22 → dao_ai-0.0.23}/functions/dais2025/find_inventory_by_upc.sql +0 -0
  250. {dao_ai-0.0.22 → dao_ai-0.0.23}/functions/dais2025/find_product_by_sku.sql +0 -0
  251. {dao_ai-0.0.22 → dao_ai-0.0.23}/functions/dais2025/find_product_by_upc.sql +0 -0
  252. {dao_ai-0.0.22 → dao_ai-0.0.23}/functions/dais2025/find_store_by_number.sql +0 -0
  253. {dao_ai-0.0.22 → dao_ai-0.0.23}/functions/dais2025/find_store_inventory_by_sku.sql +0 -0
  254. {dao_ai-0.0.22 → dao_ai-0.0.23}/functions/dais2025/find_store_inventory_by_upc.sql +0 -0
  255. {dao_ai-0.0.22 → dao_ai-0.0.23}/functions/hardware_store/find_inventory_by_sku.sql +0 -0
  256. {dao_ai-0.0.22 → dao_ai-0.0.23}/functions/hardware_store/find_inventory_by_upc.sql +0 -0
  257. {dao_ai-0.0.22 → dao_ai-0.0.23}/functions/hardware_store/find_product_by_sku.sql +0 -0
  258. {dao_ai-0.0.22 → dao_ai-0.0.23}/functions/hardware_store/find_product_by_upc.sql +0 -0
  259. {dao_ai-0.0.22 → dao_ai-0.0.23}/functions/hardware_store/find_store_inventory_by_sku.sql +0 -0
  260. {dao_ai-0.0.22 → dao_ai-0.0.23}/functions/hardware_store/find_store_inventory_by_upc.sql +0 -0
  261. {dao_ai-0.0.22 → dao_ai-0.0.23}/functions/quick_serve_restaurant/.gitkeep +0 -0
  262. {dao_ai-0.0.22 → dao_ai-0.0.23}/functions/quick_serve_restaurant/insert_coffee_order.sql +0 -0
  263. {dao_ai-0.0.22 → dao_ai-0.0.23}/functions/quick_serve_restaurant/lookup_items_by_descriptions.sql +0 -0
  264. {dao_ai-0.0.22 → dao_ai-0.0.23}/functions/quick_serve_restaurant/match_historical_item_order_by_date.sql +0 -0
  265. {dao_ai-0.0.22 → dao_ai-0.0.23}/functions/quick_serve_restaurant/match_item_by_description_and_price.sql +0 -0
  266. {dao_ai-0.0.22 → dao_ai-0.0.23}/notebooks/01_ingest_and_transform.py +0 -0
  267. {dao_ai-0.0.22 → dao_ai-0.0.23}/notebooks/02_provision_vector_search.py +0 -0
  268. {dao_ai-0.0.22 → dao_ai-0.0.23}/notebooks/03_provision_lakebase.py +0 -0
  269. {dao_ai-0.0.22 → dao_ai-0.0.23}/notebooks/04_unity_catalog_tools.py +0 -0
  270. {dao_ai-0.0.22 → dao_ai-0.0.23}/notebooks/05_deploy_agent.py +0 -0
  271. {dao_ai-0.0.22 → dao_ai-0.0.23}/notebooks/06_generate_evaluation_data.py +0 -0
  272. {dao_ai-0.0.22 → dao_ai-0.0.23}/notebooks/07_run_evaluation.py +0 -0
  273. {dao_ai-0.0.22 → dao_ai-0.0.23}/notebooks/08_run_examples.py +0 -0
  274. {dao_ai-0.0.22 → dao_ai-0.0.23}/notebooks/09_evaluate_inferences.py +0 -0
  275. {dao_ai-0.0.22 → dao_ai-0.0.23}/notebooks/99_scratchpad.py +0 -0
  276. {dao_ai-0.0.22 → dao_ai-0.0.23}/notebooks/INVESTech.py +0 -0
  277. {dao_ai-0.0.22 → dao_ai-0.0.23}/schemas/bundle_config_schema.json +0 -0
  278. {dao_ai-0.0.22 → dao_ai-0.0.23}/src/dais2025/__init__.py +0 -0
  279. {dao_ai-0.0.22 → dao_ai-0.0.23}/src/dais2025/models.py +0 -0
  280. {dao_ai-0.0.22 → dao_ai-0.0.23}/src/dais2025/tools/__init__.py +0 -0
  281. {dao_ai-0.0.22 → dao_ai-0.0.23}/src/dais2025/tools/customer.py +0 -0
  282. {dao_ai-0.0.22 → dao_ai-0.0.23}/src/dais2025/tools/employee.py +0 -0
  283. {dao_ai-0.0.22 → dao_ai-0.0.23}/src/dais2025/tools/executive.py +0 -0
  284. {dao_ai-0.0.22 → dao_ai-0.0.23}/src/dais2025/tools/genie.py +0 -0
  285. {dao_ai-0.0.22 → dao_ai-0.0.23}/src/dais2025/tools/inventory.py +0 -0
  286. {dao_ai-0.0.22 → dao_ai-0.0.23}/src/dais2025/tools/models.py +0 -0
  287. {dao_ai-0.0.22 → dao_ai-0.0.23}/src/dais2025/tools/store.py +0 -0
  288. {dao_ai-0.0.22 → dao_ai-0.0.23}/src/dao_ai/__init__.py +0 -0
  289. {dao_ai-0.0.22 → dao_ai-0.0.23}/src/dao_ai/agent_as_code.py +0 -0
  290. {dao_ai-0.0.22 → dao_ai-0.0.23}/src/dao_ai/catalog.py +0 -0
  291. {dao_ai-0.0.22 → dao_ai-0.0.23}/src/dao_ai/chat_models.py +0 -0
  292. {dao_ai-0.0.22 → dao_ai-0.0.23}/src/dao_ai/cli.py +0 -0
  293. {dao_ai-0.0.22 → dao_ai-0.0.23}/src/dao_ai/graph.py +0 -0
  294. {dao_ai-0.0.22 → dao_ai-0.0.23}/src/dao_ai/guardrails.py +0 -0
  295. {dao_ai-0.0.22 → dao_ai-0.0.23}/src/dao_ai/hooks/__init__.py +0 -0
  296. {dao_ai-0.0.22 → dao_ai-0.0.23}/src/dao_ai/hooks/core.py +0 -0
  297. {dao_ai-0.0.22 → dao_ai-0.0.23}/src/dao_ai/memory/__init__.py +0 -0
  298. {dao_ai-0.0.22 → dao_ai-0.0.23}/src/dao_ai/memory/base.py +0 -0
  299. {dao_ai-0.0.22 → dao_ai-0.0.23}/src/dao_ai/memory/core.py +0 -0
  300. {dao_ai-0.0.22 → dao_ai-0.0.23}/src/dao_ai/memory/postgres.py +0 -0
  301. {dao_ai-0.0.22 → dao_ai-0.0.23}/src/dao_ai/messages.py +0 -0
  302. {dao_ai-0.0.22 → dao_ai-0.0.23}/src/dao_ai/models.py +0 -0
  303. {dao_ai-0.0.22 → dao_ai-0.0.23}/src/dao_ai/nodes.py +0 -0
  304. {dao_ai-0.0.22 → dao_ai-0.0.23}/src/dao_ai/prompts.py +0 -0
  305. {dao_ai-0.0.22 → dao_ai-0.0.23}/src/dao_ai/providers/__init__.py +0 -0
  306. {dao_ai-0.0.22 → dao_ai-0.0.23}/src/dao_ai/providers/base.py +0 -0
  307. {dao_ai-0.0.22 → dao_ai-0.0.23}/src/dao_ai/providers/databricks.py +0 -0
  308. {dao_ai-0.0.22 → dao_ai-0.0.23}/src/dao_ai/state.py +0 -0
  309. {dao_ai-0.0.22 → dao_ai-0.0.23}/src/dao_ai/tools/agent.py +0 -0
  310. {dao_ai-0.0.22 → dao_ai-0.0.23}/src/dao_ai/tools/core.py +0 -0
  311. {dao_ai-0.0.22 → dao_ai-0.0.23}/src/dao_ai/tools/genie.py +0 -0
  312. {dao_ai-0.0.22 → dao_ai-0.0.23}/src/dao_ai/tools/human_in_the_loop.py +0 -0
  313. {dao_ai-0.0.22 → dao_ai-0.0.23}/src/dao_ai/tools/python.py +0 -0
  314. {dao_ai-0.0.22 → dao_ai-0.0.23}/src/dao_ai/tools/time.py +0 -0
  315. {dao_ai-0.0.22 → dao_ai-0.0.23}/src/dao_ai/tools/unity_catalog.py +0 -0
  316. {dao_ai-0.0.22 → dao_ai-0.0.23}/src/dao_ai/tools/vector_search.py +0 -0
  317. {dao_ai-0.0.22 → dao_ai-0.0.23}/src/dao_ai/types.py +0 -0
  318. {dao_ai-0.0.22 → dao_ai-0.0.23}/src/dao_ai/vector_search.py +0 -0
  319. {dao_ai-0.0.22 → dao_ai-0.0.23}/src/hardware_store/__init__.py +0 -0
  320. {dao_ai-0.0.22 → dao_ai-0.0.23}/src/hardware_store/hooks.py +0 -0
  321. {dao_ai-0.0.22 → dao_ai-0.0.23}/src/hardware_store/tools.py +0 -0
  322. {dao_ai-0.0.22 → dao_ai-0.0.23}/src/quick_serve_restaurant/.gitkeep +0 -0
  323. {dao_ai-0.0.22 → dao_ai-0.0.23}/src/quick_serve_restaurant/__init__.py +0 -0
  324. {dao_ai-0.0.22 → dao_ai-0.0.23}/src/quick_serve_restaurant/tools.py +0 -0
  325. {dao_ai-0.0.22 → dao_ai-0.0.23}/tests/config/test_model_config.yaml +0 -0
  326. {dao_ai-0.0.22 → dao_ai-0.0.23}/tests/conftest.py +0 -0
  327. {dao_ai-0.0.22 → dao_ai-0.0.23}/tests/dao_ai/test_catalog.py +0 -0
  328. {dao_ai-0.0.22 → dao_ai-0.0.23}/tests/dao_ai/test_chat_history.py +0 -0
  329. {dao_ai-0.0.22 → dao_ai-0.0.23}/tests/dao_ai/test_config.py +0 -0
  330. {dao_ai-0.0.22 → dao_ai-0.0.23}/tests/dao_ai/test_databricks.py +0 -0
  331. {dao_ai-0.0.22 → dao_ai-0.0.23}/tests/dao_ai/test_genie.py +0 -0
  332. {dao_ai-0.0.22 → dao_ai-0.0.23}/tests/dao_ai/test_genie_conversation_ids_in_outputs.py +0 -0
  333. {dao_ai-0.0.22 → dao_ai-0.0.23}/tests/dao_ai/test_genie_databricks_integration.py +0 -0
  334. {dao_ai-0.0.22 → dao_ai-0.0.23}/tests/dao_ai/test_hooks.py +0 -0
  335. {dao_ai-0.0.22 → dao_ai-0.0.23}/tests/dao_ai/test_inference.py +0 -0
  336. {dao_ai-0.0.22 → dao_ai-0.0.23}/tests/dao_ai/test_inference_integration.py +0 -0
  337. {dao_ai-0.0.22 → dao_ai-0.0.23}/tests/dao_ai/test_messages.py +0 -0
  338. {dao_ai-0.0.22 → dao_ai-0.0.23}/tests/dao_ai/test_models.py +0 -0
  339. {dao_ai-0.0.22 → dao_ai-0.0.23}/tests/dao_ai/test_postgres_integration.py +0 -0
  340. {dao_ai-0.0.22 → dao_ai-0.0.23}/tests/dao_ai/test_state.py +0 -0
  341. {dao_ai-0.0.22 → dao_ai-0.0.23}/tests/dao_ai/test_summarization_inference.py +0 -0
  342. {dao_ai-0.0.22 → dao_ai-0.0.23}/tests/dao_ai/test_tools.py +0 -0
  343. {dao_ai-0.0.22 → dao_ai-0.0.23}/tests/dao_ai/test_types.py +0 -0
  344. {dao_ai-0.0.22 → dao_ai-0.0.23}/tests/dao_ai/test_unity_catalog.py +0 -0
  345. {dao_ai-0.0.22 → dao_ai-0.0.23}/tests/dao_ai/test_utils.py +0 -0
  346. {dao_ai-0.0.22 → dao_ai-0.0.23}/tests/dao_ai/test_vector_search.py +0 -0
  347. {dao_ai-0.0.22 → dao_ai-0.0.23}/tests/dao_ai/weather_server_mcp.py +0 -0
  348. {dao_ai-0.0.22 → dao_ai-0.0.23}/tests/hardware_store/.gitkeep +0 -0
  349. {dao_ai-0.0.22 → dao_ai-0.0.23}/tests/hardware_store/test_graph.py +0 -0
  350. {dao_ai-0.0.22 → dao_ai-0.0.23}/tests/images/doritos_upc.png +0 -0
  351. {dao_ai-0.0.22 → dao_ai-0.0.23}/tests/images/lays_upc.png +0 -0
  352. {dao_ai-0.0.22 → dao_ai-0.0.23}/tests/quick_serve_restaurant/.gitkeep +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dao-ai
3
- Version: 0.0.22
3
+ Version: 0.0.23
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,6 +26,7 @@ Classifier: Topic :: System :: Distributed Computing
26
26
  Requires-Python: >=3.12
27
27
  Requires-Dist: databricks-agents>=1.6.1
28
28
  Requires-Dist: databricks-langchain>=0.8.0
29
+ Requires-Dist: databricks-mcp>=0.3.0
29
30
  Requires-Dist: databricks-sdk[openai]>=0.67.0
30
31
  Requires-Dist: duckduckgo-search>=8.0.2
31
32
  Requires-Dist: grandalf>=0.8
@@ -653,7 +654,7 @@ test:
653
654
  #### 4. MCP (Model Context Protocol) Tools (`type: mcp`)
654
655
  MCP tools allow interaction with external services that implement the Model Context Protocol, supporting both HTTP and stdio transports.
655
656
 
656
- **Configuration Example:**
657
+ **Configuration Example (Direct URL):**
657
658
  ```yaml
658
659
  tools:
659
660
  weather_tool_mcp:
@@ -664,8 +665,30 @@ test:
664
665
  transport: streamable_http
665
666
  url: http://localhost:8000/mcp
666
667
  ```
668
+
669
+ **Configuration Example (Unity Catalog Connection):**
670
+ MCP tools can also use Unity Catalog Connections for secure, governed access with on-behalf-of-user capabilities. The connection provides OAuth authentication, while the URL specifies the endpoint:
671
+ ```yaml
672
+ resources:
673
+ connections:
674
+ github_connection:
675
+ name: github_u2m_connection # UC Connection name
676
+
677
+ tools:
678
+ github_mcp:
679
+ name: github_mcp
680
+ function:
681
+ type: mcp
682
+ name: github_mcp
683
+ transport: streamable_http
684
+ url: https://workspace.databricks.com/api/2.0/mcp/external/github_u2m_connection # MCP endpoint URL
685
+ connection: *github_connection # UC Connection provides OAuth authentication
686
+ ```
687
+
667
688
  **Development:**
668
- Ensure the MCP service is running and accessible at the specified URL or command. The framework will handle the MCP protocol communication automatically.
689
+ - **For direct URL connections**: Ensure the MCP service is running and accessible at the specified URL or command. Provide OAuth credentials (client_id, client_secret) or PAT for authentication.
690
+ - **For UC Connection**: URL is required to specify the endpoint. The connection provides OAuth authentication via the workspace client. Ensure the connection is configured in Unity Catalog with appropriate MCP scopes (`mcp.genie`, `mcp.functions`, `mcp.vectorsearch`, `mcp.external`).
691
+ - The framework will handle the MCP protocol communication automatically, including session management and authentication.
669
692
 
670
693
  ### Configuring New Agents
671
694
 
@@ -581,7 +581,7 @@ test:
581
581
  #### 4. MCP (Model Context Protocol) Tools (`type: mcp`)
582
582
  MCP tools allow interaction with external services that implement the Model Context Protocol, supporting both HTTP and stdio transports.
583
583
 
584
- **Configuration Example:**
584
+ **Configuration Example (Direct URL):**
585
585
  ```yaml
586
586
  tools:
587
587
  weather_tool_mcp:
@@ -592,8 +592,30 @@ test:
592
592
  transport: streamable_http
593
593
  url: http://localhost:8000/mcp
594
594
  ```
595
+
596
+ **Configuration Example (Unity Catalog Connection):**
597
+ MCP tools can also use Unity Catalog Connections for secure, governed access with on-behalf-of-user capabilities. The connection provides OAuth authentication, while the URL specifies the endpoint:
598
+ ```yaml
599
+ resources:
600
+ connections:
601
+ github_connection:
602
+ name: github_u2m_connection # UC Connection name
603
+
604
+ tools:
605
+ github_mcp:
606
+ name: github_mcp
607
+ function:
608
+ type: mcp
609
+ name: github_mcp
610
+ transport: streamable_http
611
+ url: https://workspace.databricks.com/api/2.0/mcp/external/github_u2m_connection # MCP endpoint URL
612
+ connection: *github_connection # UC Connection provides OAuth authentication
613
+ ```
614
+
595
615
  **Development:**
596
- Ensure the MCP service is running and accessible at the specified URL or command. The framework will handle the MCP protocol communication automatically.
616
+ - **For direct URL connections**: Ensure the MCP service is running and accessible at the specified URL or command. Provide OAuth credentials (client_id, client_secret) or PAT for authentication.
617
+ - **For UC Connection**: URL is required to specify the endpoint. The connection provides OAuth authentication via the workspace client. Ensure the connection is configured in Unity Catalog with appropriate MCP scopes (`mcp.genie`, `mcp.functions`, `mcp.vectorsearch`, `mcp.external`).
618
+ - The framework will handle the MCP protocol communication automatically, including session management and authentication.
597
619
 
598
620
  ### Configuring New Agents
599
621
 
@@ -0,0 +1,109 @@
1
+ # yaml-language-server: $schema=../../schemas/model_config_schema.json
2
+
3
+ variables:
4
+ client_id: &client_id # Service principal client ID
5
+ options:
6
+ - env: RETAIL_AI_DATABRICKS_CLIENT_ID
7
+ - scope: retail_ai
8
+ secret: RETAIL_AI_DATABRICKS_CLIENT_ID
9
+ client_secret: &client_secret # Service principal secret
10
+ options:
11
+ - env: RETAIL_AI_DATABRICKS_CLIENT_SECRET
12
+ - scope: retail_ai
13
+ secret: RETAIL_AI_DATABRICKS_CLIENT_SECRET
14
+ workspace_host: &workspace_host # Databricks workspace URL
15
+ options:
16
+ - env: RETAIL_AI_DATABRICKS_HOST
17
+ - scope: retail_ai
18
+ secret: RETAIL_AI_DATABRICKS_HOST
19
+
20
+ schemas:
21
+ retail_schema: &retail_schema # Unity Catalog schema configuration
22
+ catalog_name: nfleming # Unity Catalog name
23
+ schema_name: retail_ai # Schema within the catalog
24
+
25
+ resources:
26
+ llms:
27
+ default_llm: &default_llm # Default LLM configuration
28
+ name: databricks-claude-3-7-sonnet # Databricks serving endpoint name
29
+
30
+ connections:
31
+ github_connection: &github_connection # UC Connection for GitHub
32
+ name: github_u2m_connection # UC Connection name
33
+
34
+ tools:
35
+ # Example using UC Connection for GitHub MCP
36
+ github_mcp_uc: &github_mcp_uc
37
+ name: github_mcp # Tool name for agent reference
38
+ function:
39
+ type: mcp # Tool type: MCP server
40
+ name: github_mcp # MCP function name
41
+ transport: streamable_http # Transport protocol
42
+ url: https://adb-984752964297111.11.azuredatabricks.net/api/2.0/mcp/external/github_u2m_connection # MCP endpoint URL
43
+ connection: *github_connection # Reference to UC Connection (provides OAuth auth)
44
+
45
+ # Example using direct URL (existing approach)
46
+ weather_tool_mcp: &weather_tool_mcp
47
+ name: weather # Tool name for agent reference
48
+ function:
49
+ type: mcp # Tool type: MCP server
50
+ name: weather # MCP function name
51
+ transport: streamable_http # Transport protocol
52
+ url: http://localhost:8000/mcp # MCP server URL
53
+
54
+ vector_search_mcp: &vector_search_mcp # Vector search MCP tool configuration
55
+ name: vector_search_mcp
56
+ function:
57
+ type: mcp # MCP function type
58
+ name: vector_search_mcp
59
+ url: https://adb-984752964297111.11.azuredatabricks.net/api/2.0/mcp/vector-search/nfleming/retail_ai
60
+ client_id: *client_id
61
+ client_secret: *client_secret
62
+ workspace_host: *workspace_host
63
+
64
+ unity_catalog_mcp: &unity_catalog_mcp # Unity Catalog MCP tool configuration
65
+ name: unity_catalog_mcp
66
+ function:
67
+ type: mcp # MCP function type
68
+ name: unity_catalog_mcp
69
+ url: https://adb-984752964297111.11.azuredatabricks.net/api/2.0/mcp/functions/nfleming/retail_ai
70
+ client_id: *client_id
71
+ client_secret: *client_secret
72
+ workspace_host: *workspace_host
73
+
74
+ genie_mcp: &genie_mcp # Genie MCP tool configuration
75
+ name: genie_mcp
76
+ function:
77
+ type: mcp # MCP function type
78
+ name: genie_mcp
79
+ url: https://adb-984752964297111.11.azuredatabricks.net/api/2.0/mcp/genie/01f01c91f1f414d59daaefd2b7ec82ea
80
+ client_id: *client_id
81
+ client_secret: *client_secret
82
+ workspace_host: *workspace_host
83
+
84
+ agents:
85
+ mcp_agent: &mcp_agent # MCP agent configuration
86
+ name: mcp_agent # Agent identifier
87
+ model: *default_llm # Reference to LLM configuration
88
+ tools: # Tools available to this agent
89
+ - *github_mcp_uc
90
+ - *vector_search_mcp
91
+ - *unity_catalog_mcp
92
+ - *genie_mcp
93
+ prompt: | # System prompt defining agent behavior
94
+ You are a multi-purpose agent that can perform vector search, interact with Unity Catalog,
95
+ interact with Genie rooms, and interact with GitHub. Use the tools provided to answer
96
+ questions and perform tasks. You many need to use the tools in combination to achieve
97
+ complex tasks.
98
+
99
+ app:
100
+ name: mcp_agent # Application name
101
+ log_level: DEBUG # Logging level for the application
102
+ registered_model: # MLflow registered model configuration
103
+ schema: *retail_schema # Schema where model will be registered
104
+ name: mcp_agent # Model name in MLflow registry
105
+ agents: # List of agents included in the system
106
+ - *mcp_agent # MCP agent
107
+ orchestration: # Agent orchestration configuration
108
+ swarm: # Supervisor orchestration pattern
109
+ model: *default_llm # LLM for routing decisions
@@ -0,0 +1,69 @@
1
+ # yaml-language-server: $schema=../../schemas/model_config_schema.json
2
+
3
+ schemas:
4
+ default_schema: &default_schema # Unity Catalog schema configuration
5
+ catalog_name: main # Unity Catalog name
6
+ schema_name: default # Schema within the catalog
7
+
8
+ resources:
9
+ llms:
10
+ # Primary LLM for Slack agent
11
+ default_llm: &default_llm
12
+ name: databricks-meta-llama-3-3-70b-instruct # Databricks serving endpoint name
13
+ temperature: 0.7 # Temperature for more natural responses
14
+ max_tokens: 4096 # Maximum tokens per response
15
+ on_behalf_of_user: false
16
+
17
+ connections:
18
+ # Unity Catalog HTTP connection to Slack
19
+ slack_connection: &slack_connection
20
+ name: slack_bot_connection # UC Connection name
21
+ on_behalf_of_user: false # Use service principal auth
22
+
23
+ tools:
24
+ # Slack messaging tool using factory function
25
+ slack_tool: &slack_tool
26
+ name: send_slack_message # Tool name for agent reference
27
+ function:
28
+ type: factory # Tool type: factory function
29
+ name: dao_ai.tools.create_send_slack_message_tool # Factory function path
30
+ args: # Arguments passed to factory
31
+ connection: *slack_connection # Reference to Slack UC connection
32
+ channel_name: "general" # Slack channel name (can also use channel_id)
33
+ name: send_slack_message
34
+ description: Send a message to the #general Slack channel
35
+
36
+ agents:
37
+ # Slack notification agent
38
+ slack_agent: &slack_agent
39
+ name: slack_agent # Agent identifier
40
+ description: "Agent that can send notifications to Slack"
41
+ model: *default_llm # Reference to LLM configuration
42
+ tools: # Tools available to this agent
43
+ - *slack_tool
44
+ prompt: | # System prompt defining agent behavior
45
+ You are a helpful assistant that can send notifications to Slack.
46
+ When asked to notify someone or send a message, use the send_slack_message tool
47
+ to post to the #general channel. Keep messages concise and professional.
48
+
49
+ app:
50
+ name: slack_agent_example # Application name
51
+ description: "Agent system that can send notifications to Slack"
52
+ log_level: INFO # Logging level for the application
53
+ registered_model: # MLflow registered model configuration
54
+ schema: *default_schema # Schema where model will be registered
55
+ name: slack_notification_agent # Model name in MLflow registry
56
+ endpoint_name: slack_notification_agent # Model serving endpoint name
57
+ tags: # Tags for resource organization
58
+ integration: slack # Integration type
59
+ notification: true # Indicates notification capabilities
60
+ permissions: # Model serving permissions
61
+ - principals: [users] # Grant access to all users
62
+ entitlements:
63
+ - CAN_QUERY # Query permissions
64
+ agents: # List of agents included in the system
65
+ - *slack_agent # Slack notification agent
66
+ orchestration: # Agent orchestration configuration
67
+ swarm: # Swarm orchestration pattern
68
+ model: *default_llm # LLM for routing decisions
69
+
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
4
4
 
5
5
  [project]
6
6
  name = "dao-ai"
7
- version = "0.0.22"
7
+ version = "0.0.23"
8
8
  description = "DAO AI: A modular, multi-agent orchestration framework for complex AI workflows. Supports agent handoff, tool integration, and dynamic configuration via YAML."
9
9
  readme = "README.md"
10
10
  license = { text = "MIT" }
@@ -44,6 +44,7 @@ classifiers = [
44
44
  dependencies = [
45
45
  "databricks-agents>=1.6.1",
46
46
  "databricks-langchain>=0.8.0",
47
+ "databricks-mcp>=0.3.0",
47
48
  "databricks-sdk[openai]>=0.67.0",
48
49
  "duckduckgo-search>=8.0.2",
49
50
  "grandalf>=0.8",
@@ -25,6 +25,7 @@ cyclopts==3.24.0
25
25
  databricks-agents==1.6.1
26
26
  databricks-ai-bridge==0.8.0
27
27
  databricks-langchain==0.8.0
28
+ databricks-mcp==0.3.0
28
29
  databricks-sdk==0.67.0
29
30
  dataclasses-json==0.6.7
30
31
  deprecation==2.1.0
@@ -1677,6 +1677,17 @@
1677
1677
  "default": null,
1678
1678
  "title": "Url"
1679
1679
  },
1680
+ "connection": {
1681
+ "anyOf": [
1682
+ {
1683
+ "$ref": "#/$defs/ConnectionModel"
1684
+ },
1685
+ {
1686
+ "type": "null"
1687
+ }
1688
+ ],
1689
+ "default": null
1690
+ },
1680
1691
  "headers": {
1681
1692
  "additionalProperties": {
1682
1693
  "anyOf": [
@@ -666,6 +666,10 @@ class ConnectionModel(BaseModel, HasFullName, IsDatabricksResource):
666
666
  return [
667
667
  "catalog.connections",
668
668
  "serving.serving-endpoints",
669
+ "mcp.genie",
670
+ "mcp.functions",
671
+ "mcp.vectorsearch",
672
+ "mcp.external",
669
673
  ]
670
674
 
671
675
  def as_resources(self) -> Sequence[DatabricksResource]:
@@ -988,6 +992,7 @@ class McpFunctionModel(BaseFunctionModel, HasFullName):
988
992
  transport: TransportType = TransportType.STREAMABLE_HTTP
989
993
  command: Optional[str] = "python"
990
994
  url: Optional[AnyVariable] = None
995
+ connection: Optional[ConnectionModel] = None
991
996
  headers: dict[str, AnyVariable] = Field(default_factory=dict)
992
997
  args: list[str] = Field(default_factory=list)
993
998
  pat: Optional[AnyVariable] = None
@@ -7,6 +7,7 @@ from dao_ai.tools.core import (
7
7
  from dao_ai.tools.genie import create_genie_tool
8
8
  from dao_ai.tools.mcp import create_mcp_tools
9
9
  from dao_ai.tools.python import create_factory_tool, create_python_tool
10
+ from dao_ai.tools.slack import create_send_slack_message_tool
10
11
  from dao_ai.tools.time import (
11
12
  add_time_tool,
12
13
  current_time_tool,
@@ -27,6 +28,7 @@ __all__ = [
27
28
  "create_hooks",
28
29
  "create_mcp_tools",
29
30
  "create_python_tool",
31
+ "create_send_slack_message_tool",
30
32
  "create_tools",
31
33
  "create_uc_tools",
32
34
  "create_vector_search_tool",
@@ -0,0 +1,164 @@
1
+ import asyncio
2
+ from typing import Any, Sequence
3
+
4
+ from databricks_mcp import DatabricksOAuthClientProvider
5
+ from langchain_core.runnables.base import RunnableLike
6
+ from langchain_core.tools import tool as create_tool
7
+ from langchain_mcp_adapters.client import MultiServerMCPClient
8
+ from langchain_mcp_adapters.tools import load_mcp_tools
9
+ from loguru import logger
10
+ from mcp import ClientSession
11
+ from mcp.client.streamable_http import streamablehttp_client
12
+ from mcp.types import ListToolsResult, Tool
13
+
14
+ from dao_ai.config import (
15
+ McpFunctionModel,
16
+ TransportType,
17
+ )
18
+ from dao_ai.tools.human_in_the_loop import as_human_in_the_loop
19
+
20
+
21
+ def create_mcp_tools(
22
+ function: McpFunctionModel,
23
+ ) -> Sequence[RunnableLike]:
24
+ """
25
+ Create tools for invoking Databricks MCP functions.
26
+
27
+ Supports both direct MCP connections and UC Connection-based MCP access.
28
+ Uses session-based approach to handle authentication token expiration properly.
29
+
30
+ Based on: https://docs.databricks.com/aws/en/generative-ai/mcp/external-mcp
31
+ """
32
+ logger.debug(f"create_mcp_tools: {function}")
33
+
34
+ # Check if using UC Connection or direct MCP connection
35
+ if function.connection:
36
+ # Use UC Connection approach with DatabricksOAuthClientProvider
37
+ logger.debug(f"Using UC Connection for MCP: {function.connection.name}")
38
+ logger.debug(f"MCP URL: {function.url}")
39
+
40
+ async def _get_tools_with_connection():
41
+ """Get tools using DatabricksOAuthClientProvider."""
42
+ workspace_client = function.connection.workspace_client
43
+
44
+ async with streamablehttp_client(
45
+ function.url, auth=DatabricksOAuthClientProvider(workspace_client)
46
+ ) as (read_stream, write_stream, _):
47
+ async with ClientSession(read_stream, write_stream) as session:
48
+ # Initialize and list tools
49
+ await session.initialize()
50
+ tools = await load_mcp_tools(session)
51
+ return tools
52
+
53
+ try:
54
+ langchain_tools = asyncio.run(_get_tools_with_connection())
55
+ logger.debug(
56
+ f"Retrieved {len(langchain_tools)} MCP tools via UC Connection"
57
+ )
58
+
59
+ # Wrap tools with human-in-the-loop if needed
60
+ wrapped_tools = [
61
+ as_human_in_the_loop(tool, function) for tool in langchain_tools
62
+ ]
63
+ return wrapped_tools
64
+
65
+ except Exception as e:
66
+ logger.error(f"Failed to get tools from MCP server via UC Connection: {e}")
67
+ raise RuntimeError(
68
+ f"Failed to list MCP tools for function '{function.name}' via UC Connection '{function.connection.name}': {e}"
69
+ )
70
+
71
+ else:
72
+ # Use direct MCP connection with MultiServerMCPClient
73
+ logger.debug("Using direct MCP connection with MultiServerMCPClient")
74
+
75
+ def _create_fresh_connection() -> dict[str, Any]:
76
+ """Create connection config with fresh authentication headers."""
77
+ logger.debug("Creating fresh connection...")
78
+
79
+ if function.transport == TransportType.STDIO:
80
+ return {
81
+ "command": function.command,
82
+ "args": function.args,
83
+ "transport": function.transport,
84
+ }
85
+
86
+ # For HTTP transport, generate fresh headers
87
+ headers = function.headers.copy() if function.headers else {}
88
+
89
+ if "Authorization" not in headers:
90
+ logger.debug("Generating fresh authentication token for MCP function")
91
+
92
+ from dao_ai.config import value_of
93
+ from dao_ai.providers.databricks import DatabricksProvider
94
+
95
+ try:
96
+ provider = DatabricksProvider(
97
+ workspace_host=value_of(function.workspace_host),
98
+ client_id=value_of(function.client_id),
99
+ client_secret=value_of(function.client_secret),
100
+ pat=value_of(function.pat),
101
+ )
102
+ headers["Authorization"] = f"Bearer {provider.create_token()}"
103
+ logger.debug("Generated fresh authentication token")
104
+ except Exception as e:
105
+ logger.error(f"Failed to create fresh token: {e}")
106
+ else:
107
+ logger.debug("Using existing authentication token")
108
+
109
+ return {
110
+ "url": function.url,
111
+ "transport": function.transport,
112
+ "headers": headers,
113
+ }
114
+
115
+ # Get available tools from MCP server
116
+ async def _list_mcp_tools():
117
+ connection = _create_fresh_connection()
118
+ client = MultiServerMCPClient({function.name: connection})
119
+
120
+ try:
121
+ async with client.session(function.name) as session:
122
+ return await session.list_tools()
123
+ except Exception as e:
124
+ logger.error(f"Failed to list MCP tools: {e}")
125
+ return []
126
+
127
+ # Note: This still needs to run sync during tool creation/registration
128
+ # The actual tool execution will be async
129
+ try:
130
+ mcp_tools: list[Tool] | ListToolsResult = asyncio.run(_list_mcp_tools())
131
+ if isinstance(mcp_tools, ListToolsResult):
132
+ mcp_tools = mcp_tools.tools
133
+
134
+ logger.debug(f"Retrieved {len(mcp_tools)} MCP tools")
135
+ except Exception as e:
136
+ logger.error(f"Failed to get tools from MCP server: {e}")
137
+ raise RuntimeError(
138
+ f"Failed to list MCP tools for function '{function.name}' with transport '{function.transport}' and URL '{function.url}': {e}"
139
+ )
140
+
141
+ # Create wrapper tools with fresh session per invocation
142
+ def _create_tool_wrapper(mcp_tool: Tool) -> RunnableLike:
143
+ @create_tool(
144
+ mcp_tool.name,
145
+ description=mcp_tool.description or f"MCP tool: {mcp_tool.name}",
146
+ args_schema=mcp_tool.inputSchema,
147
+ )
148
+ async def tool_wrapper(**kwargs):
149
+ """Execute MCP tool with fresh session and authentication."""
150
+ logger.debug(f"Invoking MCP tool {mcp_tool.name} with fresh session")
151
+
152
+ connection = _create_fresh_connection()
153
+ client = MultiServerMCPClient({function.name: connection})
154
+
155
+ try:
156
+ async with client.session(function.name) as session:
157
+ return await session.call_tool(mcp_tool.name, kwargs)
158
+ except Exception as e:
159
+ logger.error(f"MCP tool {mcp_tool.name} failed: {e}")
160
+ raise
161
+
162
+ return as_human_in_the_loop(tool_wrapper, function)
163
+
164
+ return [_create_tool_wrapper(tool) for tool in mcp_tools]
@@ -0,0 +1,136 @@
1
+ from typing import Any, Callable, Optional
2
+
3
+ from databricks.sdk.service.serving import ExternalFunctionRequestHttpMethod
4
+ from langchain_core.tools import tool
5
+ from loguru import logger
6
+ from requests import Response
7
+
8
+ from dao_ai.config import ConnectionModel
9
+
10
+
11
+ def _find_channel_id_by_name(
12
+ connection: ConnectionModel, channel_name: str
13
+ ) -> Optional[str]:
14
+ """
15
+ Find a Slack channel ID by channel name using the conversations.list API.
16
+
17
+ Based on: https://docs.databricks.com/aws/en/generative-ai/agent-framework/slack-agent
18
+
19
+ Args:
20
+ connection: ConnectionModel with workspace_client
21
+ channel_name: Name of the Slack channel (with or without '#' prefix)
22
+
23
+ Returns:
24
+ Channel ID if found, None otherwise
25
+ """
26
+ # Remove '#' prefix if present
27
+ clean_name = channel_name.lstrip("#")
28
+
29
+ logger.debug(f"Looking up Slack channel ID for channel name: {clean_name}")
30
+
31
+ try:
32
+ # Call Slack API to list conversations
33
+ response: Response = connection.workspace_client.serving_endpoints.http_request(
34
+ conn=connection.name,
35
+ method=ExternalFunctionRequestHttpMethod.GET,
36
+ path="/api/conversations.list",
37
+ )
38
+
39
+ if response.status_code != 200:
40
+ logger.error(f"Failed to list Slack channels: {response.text}")
41
+ return None
42
+
43
+ # Parse response
44
+ data = response.json()
45
+
46
+ if not data.get("ok"):
47
+ logger.error(f"Slack API returned error: {data.get('error')}")
48
+ return None
49
+
50
+ # Search for channel by name
51
+ channels = data.get("channels", [])
52
+ for channel in channels:
53
+ if channel.get("name") == clean_name:
54
+ channel_id = channel.get("id")
55
+ logger.debug(
56
+ f"Found channel ID '{channel_id}' for channel name '{clean_name}'"
57
+ )
58
+ return channel_id
59
+
60
+ logger.warning(f"Channel '{clean_name}' not found in Slack workspace")
61
+ return None
62
+
63
+ except Exception as e:
64
+ logger.error(f"Error looking up Slack channel: {e}")
65
+ return None
66
+
67
+
68
+ def create_send_slack_message_tool(
69
+ connection: ConnectionModel | dict[str, Any],
70
+ channel_id: Optional[str] = None,
71
+ channel_name: Optional[str] = None,
72
+ name: Optional[str] = None,
73
+ description: Optional[str] = None,
74
+ ) -> Callable[[str], Any]:
75
+ """
76
+ Create a tool that sends a message to a Slack channel.
77
+
78
+ Args:
79
+ connection: Unity Catalog connection to Slack (ConnectionModel or dict)
80
+ channel_id: Slack channel ID (e.g., 'C1234567890'). If not provided, channel_name is used.
81
+ channel_name: Slack channel name (e.g., 'general' or '#general'). Used to lookup channel_id if not provided.
82
+ name: Custom tool name (default: 'send_slack_message')
83
+ description: Custom tool description
84
+
85
+ Returns:
86
+ A tool function that sends messages to the specified Slack channel
87
+
88
+ Based on: https://docs.databricks.com/aws/en/generative-ai/agent-framework/slack-agent
89
+ """
90
+ logger.debug("create_send_slack_message_tool")
91
+
92
+ # Validate inputs
93
+ if channel_id is None and channel_name is None:
94
+ raise ValueError("Either channel_id or channel_name must be provided")
95
+
96
+ # Convert connection dict to ConnectionModel if needed
97
+ if isinstance(connection, dict):
98
+ connection = ConnectionModel(**connection)
99
+
100
+ # Look up channel_id from channel_name if needed
101
+ if channel_id is None and channel_name is not None:
102
+ logger.debug(f"Looking up channel_id for channel_name: {channel_name}")
103
+ channel_id = _find_channel_id_by_name(connection, channel_name)
104
+ if channel_id is None:
105
+ raise ValueError(f"Could not find Slack channel with name '{channel_name}'")
106
+ logger.debug(
107
+ f"Resolved channel_name '{channel_name}' to channel_id '{channel_id}'"
108
+ )
109
+
110
+ if name is None:
111
+ name = "send_slack_message"
112
+
113
+ if description is None:
114
+ description = "Send a message to a Slack channel"
115
+
116
+ @tool(
117
+ name_or_callable=name,
118
+ description=description,
119
+ )
120
+ def send_slack_message(text: str) -> str:
121
+ response: Response = connection.workspace_client.serving_endpoints.http_request(
122
+ conn=connection.name,
123
+ method=ExternalFunctionRequestHttpMethod.POST,
124
+ path="/api/chat.postMessage",
125
+ json={"channel": channel_id, "text": text},
126
+ )
127
+
128
+ if response.status_code == 200:
129
+ return "Successful request sent to Slack: " + response.text
130
+ else:
131
+ return (
132
+ "Encountered failure when executing request. Message from Call: "
133
+ + response.text
134
+ )
135
+
136
+ return send_slack_message