dao-ai 0.1.11__tar.gz → 0.1.13__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.
- {dao_ai-0.1.11 → dao_ai-0.1.13}/PKG-INFO +4 -3
- {dao_ai-0.1.11 → dao_ai-0.1.13}/README.md +3 -2
- {dao_ai-0.1.11 → dao_ai-0.1.13}/config/examples/07_human_in_the_loop/human_in_the_loop.yaml +14 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/config/examples/15_complete_applications/hardware_store_lakebase.yaml +3 -2
- {dao_ai-0.1.11 → dao_ai-0.1.13}/docs/key-capabilities.md +69 -14
- {dao_ai-0.1.11 → dao_ai-0.1.13}/notebooks/07_run_evaluation.py +2 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/pyproject.toml +1 -1
- {dao_ai-0.1.11 → dao_ai-0.1.13}/src/dao_ai/apps/handlers.py +1 -1
- {dao_ai-0.1.11 → dao_ai-0.1.13}/src/dao_ai/apps/resources.py +60 -10
- {dao_ai-0.1.11 → dao_ai-0.1.13}/src/dao_ai/apps/server.py +2 -2
- {dao_ai-0.1.11 → dao_ai-0.1.13}/src/dao_ai/config.py +29 -28
- {dao_ai-0.1.11 → dao_ai-0.1.13}/src/dao_ai/providers/databricks.py +74 -20
- {dao_ai-0.1.11 → dao_ai-0.1.13}/tests/dao_ai/test_databricks.py +34 -45
- {dao_ai-0.1.11 → dao_ai-0.1.13}/.gitignore +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/.python-version +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/CHANGELOG.md +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/CONTRIBUTING.md +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/LICENSE +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/Makefile +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/app.yaml +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/config/examples/01_getting_started/README.md +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/config/examples/01_getting_started/minimal.yaml +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/config/examples/02_mcp/README.md +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/config/examples/02_mcp/custom_mcp.yaml +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/config/examples/02_mcp/external_mcp.yaml +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/config/examples/02_mcp/filtered_mcp.yaml +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/config/examples/02_mcp/managed_mcp.yaml +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/config/examples/02_mcp/slack_integration.yaml +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/config/examples/03_reranking/README.md +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/config/examples/03_reranking/vector_search_with_reranking.yaml +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/config/examples/04_genie/README.md +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/config/examples/04_genie/genie_basic.yaml +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/config/examples/04_genie/genie_lru_cache.yaml +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/config/examples/04_genie/genie_semantic_cache.yaml +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/config/examples/04_genie/genie_with_conversation_id.yaml +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/config/examples/05_memory/README.md +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/config/examples/05_memory/conversation_summarization.yaml +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/config/examples/05_memory/in_memory_basic.yaml +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/config/examples/05_memory/lakebase_persistence.yaml +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/config/examples/05_memory/postgres_persistence.yaml +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/config/examples/06_on_behalf_of_user/README.md +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/config/examples/06_on_behalf_of_user/obo_basic.yaml +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/config/examples/07_human_in_the_loop/README.md +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/config/examples/08_guardrails/README.md +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/config/examples/08_guardrails/guardrails_basic.yaml +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/config/examples/09_structured_output/README.md +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/config/examples/09_structured_output/structured_output.yaml +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/config/examples/10_agent_integrations/README.md +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/config/examples/10_agent_integrations/agent_bricks.yaml +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/config/examples/10_agent_integrations/kasal.yaml +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/config/examples/11_prompt_engineering/README.md +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/config/examples/11_prompt_engineering/prompt_optimization.yaml +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/config/examples/11_prompt_engineering/prompt_registry.yaml +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/config/examples/12_middleware/README.md +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/config/examples/12_middleware/combined_middleware.yaml +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/config/examples/12_middleware/context_management.yaml +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/config/examples/12_middleware/custom_field_validation.yaml +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/config/examples/12_middleware/limit_middleware.yaml +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/config/examples/12_middleware/logging_middleware.yaml +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/config/examples/12_middleware/pii_middleware.yaml +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/config/examples/12_middleware/retry_middleware.yaml +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/config/examples/12_middleware/tool_selector_middleware.yaml +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/config/examples/13_orchestration/README.md +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/config/examples/13_orchestration/supervisor_pattern.yaml +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/config/examples/13_orchestration/swarm_pattern.yaml +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/config/examples/14_basic_tools/README.md +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/config/examples/14_basic_tools/sql_tool_example.yaml +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/config/examples/15_complete_applications/README.md +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/config/examples/15_complete_applications/brick_store.yaml +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/config/examples/15_complete_applications/deep_research.yaml +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/config/examples/15_complete_applications/executive_assistant.yaml +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/config/examples/15_complete_applications/genie_and_genie_mcp.yaml +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/config/examples/15_complete_applications/genie_vector_search_hybrid.yaml +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/config/examples/15_complete_applications/hardware_store.yaml +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/config/examples/15_complete_applications/hardware_store_swarm.yaml +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/config/examples/15_complete_applications/quick_serve_restaurant.yaml +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/config/examples/15_complete_applications/reservations_system.yaml +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/config/examples/README.md +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/data/dais2025/appointments.sql +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/data/dais2025/appointments_data.sql +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/data/dais2025/brand_rep_demo_data.sql +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/data/dais2025/brand_rep_demo_queries.sql +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/data/dais2025/brand_rep_demo_tables.sql +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/data/dais2025/brand_rep_demo_validation.sql +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/data/dais2025/customers.sql +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/data/dais2025/customers_data.sql +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/data/dais2025/dim_stores.sql +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/data/dais2025/dim_stores_data.sql +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/data/dais2025/employee_performance.sql +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/data/dais2025/employee_performance_data.sql +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/data/dais2025/employee_tasks.sql +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/data/dais2025/employee_tasks_data.sql +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/data/dais2025/inventory.sql +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/data/dais2025/inventory_data.sql +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/data/dais2025/managers.sql +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/data/dais2025/managers_data.sql +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/data/dais2025/product_data.sql +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/data/dais2025/products.sql +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/data/dais2025/task_assignments.sql +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/data/hardware_store/inventory.snappy.parquet +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/data/hardware_store/inventory.sql +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/data/hardware_store/products.snappy.parquet +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/data/hardware_store/products.sql +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/data/quick_serve_restaurant/.gitkeep +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/data/quick_serve_restaurant/fulfil_item_orders.sql +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/data/quick_serve_restaurant/items_description.csv +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/data/quick_serve_restaurant/items_description.sql +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/data/quick_serve_restaurant/items_raw.csv +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/data/quick_serve_restaurant/items_raw.sql +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/data/quick_serve_restaurant/orders_raw.csv +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/data/quick_serve_restaurant/orders_raw.sql +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/databricks.yaml.template +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/docs/architecture.md +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/docs/cli-reference.md +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/docs/configuration-reference.md +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/docs/contributing.md +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/docs/examples.md +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/docs/faq.md +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/docs/hardware_store/README.md +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/docs/hardware_store/retail_supervisor.png +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/docs/hardware_store/retail_swarm.png +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/docs/images/genie.png +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/docs/python-api.md +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/docs/quick_serve_restaurant/.gitkeep +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/docs/quick_serve_restaurant/quick-serve-restaurant.png +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/docs/why-dao.md +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/environment.yaml +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/examples/dais2025/examples.yaml +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/examples/deep_research/examples.yaml +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/examples/executive_assistant/examples.yaml +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/examples/hardware_store/examples.yaml +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/examples/quick_serve_restaurant/.gitkeep +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/examples/quick_serve_restaurant/examples.yaml +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/functions/dais2025/extract_store_numbers.sql +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/functions/dais2025/find_inventory_by_sku.sql +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/functions/dais2025/find_inventory_by_upc.sql +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/functions/dais2025/find_product_by_sku.sql +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/functions/dais2025/find_product_by_upc.sql +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/functions/dais2025/find_store_by_number.sql +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/functions/dais2025/find_store_inventory_by_sku.sql +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/functions/dais2025/find_store_inventory_by_upc.sql +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/functions/hardware_store/find_inventory_by_sku.sql +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/functions/hardware_store/find_inventory_by_upc.sql +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/functions/hardware_store/find_product_by_sku.sql +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/functions/hardware_store/find_product_by_upc.sql +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/functions/hardware_store/find_store_inventory_by_sku.sql +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/functions/hardware_store/find_store_inventory_by_upc.sql +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/functions/quick_serve_restaurant/.gitkeep +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/functions/quick_serve_restaurant/insert_coffee_order.sql +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/functions/quick_serve_restaurant/lookup_items_by_descriptions.sql +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/functions/quick_serve_restaurant/match_historical_item_order_by_date.sql +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/functions/quick_serve_restaurant/match_item_by_description_and_price.sql +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/notebooks/01_ingest_and_transform.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/notebooks/02_provision_vector_search.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/notebooks/03_provision_lakebase.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/notebooks/04_unity_catalog_tools.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/notebooks/05_deploy_agent.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/notebooks/06_generate_evaluation_data.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/notebooks/08_run_examples.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/notebooks/09_evaluate_inferences.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/notebooks/10_optimize_prompts.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/notebooks/99_scratchpad.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/requirements.txt +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/schemas/bundle_config_schema.json +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/schemas/model_config_schema.json +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/src/dais2025/__init__.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/src/dais2025/models.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/src/dais2025/tools/__init__.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/src/dais2025/tools/customer.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/src/dais2025/tools/employee.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/src/dais2025/tools/executive.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/src/dais2025/tools/genie.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/src/dais2025/tools/inventory.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/src/dais2025/tools/models.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/src/dais2025/tools/store.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/src/dao_ai/__init__.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/src/dao_ai/apps/__init__.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/src/dao_ai/apps/model_serving.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/src/dao_ai/catalog.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/src/dao_ai/cli.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/src/dao_ai/genie/__init__.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/src/dao_ai/genie/cache/__init__.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/src/dao_ai/genie/cache/base.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/src/dao_ai/genie/cache/core.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/src/dao_ai/genie/cache/lru.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/src/dao_ai/genie/cache/semantic.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/src/dao_ai/genie/core.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/src/dao_ai/graph.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/src/dao_ai/hooks/__init__.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/src/dao_ai/hooks/core.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/src/dao_ai/logging.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/src/dao_ai/memory/__init__.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/src/dao_ai/memory/base.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/src/dao_ai/memory/core.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/src/dao_ai/memory/databricks.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/src/dao_ai/memory/postgres.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/src/dao_ai/messages.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/src/dao_ai/middleware/__init__.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/src/dao_ai/middleware/assertions.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/src/dao_ai/middleware/base.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/src/dao_ai/middleware/context_editing.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/src/dao_ai/middleware/core.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/src/dao_ai/middleware/guardrails.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/src/dao_ai/middleware/human_in_the_loop.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/src/dao_ai/middleware/message_validation.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/src/dao_ai/middleware/model_call_limit.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/src/dao_ai/middleware/model_retry.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/src/dao_ai/middleware/pii.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/src/dao_ai/middleware/summarization.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/src/dao_ai/middleware/tool_call_limit.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/src/dao_ai/middleware/tool_retry.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/src/dao_ai/middleware/tool_selector.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/src/dao_ai/models.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/src/dao_ai/nodes.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/src/dao_ai/optimization.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/src/dao_ai/orchestration/__init__.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/src/dao_ai/orchestration/core.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/src/dao_ai/orchestration/supervisor.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/src/dao_ai/orchestration/swarm.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/src/dao_ai/prompts.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/src/dao_ai/providers/__init__.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/src/dao_ai/providers/base.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/src/dao_ai/state.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/src/dao_ai/tools/__init__.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/src/dao_ai/tools/agent.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/src/dao_ai/tools/core.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/src/dao_ai/tools/email.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/src/dao_ai/tools/genie.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/src/dao_ai/tools/mcp.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/src/dao_ai/tools/memory.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/src/dao_ai/tools/python.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/src/dao_ai/tools/search.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/src/dao_ai/tools/slack.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/src/dao_ai/tools/sql.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/src/dao_ai/tools/time.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/src/dao_ai/tools/unity_catalog.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/src/dao_ai/tools/vector_search.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/src/dao_ai/types.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/src/dao_ai/utils.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/src/dao_ai/vector_search.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/tests/config/test_model_config.yaml +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/tests/conftest.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/tests/dao_ai/middleware/test_context_editing.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/tests/dao_ai/middleware/test_model_call_limit.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/tests/dao_ai/middleware/test_model_retry.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/tests/dao_ai/middleware/test_pii.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/tests/dao_ai/middleware/test_tool_call_limit.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/tests/dao_ai/middleware/test_tool_retry.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/tests/dao_ai/middleware/test_tool_selector.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/tests/dao_ai/test_agent_response_format.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/tests/dao_ai/test_assertions_middleware.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/tests/dao_ai/test_catalog.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/tests/dao_ai/test_chat_history.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/tests/dao_ai/test_config.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/tests/dao_ai/test_function_parsing.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/tests/dao_ai/test_genie.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/tests/dao_ai/test_genie_conversation_ids_in_outputs.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/tests/dao_ai/test_genie_databricks_integration.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/tests/dao_ai/test_genie_room_model.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/tests/dao_ai/test_guardrail_retry.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/tests/dao_ai/test_hitl_config_model.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/tests/dao_ai/test_hitl_responses_agent.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/tests/dao_ai/test_hooks.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/tests/dao_ai/test_human_in_the_loop.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/tests/dao_ai/test_inference.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/tests/dao_ai/test_inference_integration.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/tests/dao_ai/test_input_output_structure.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/tests/dao_ai/test_interrupt_type.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/tests/dao_ai/test_llm_interrupt_handling.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/tests/dao_ai/test_mcp.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/tests/dao_ai/test_mcp_filtering.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/tests/dao_ai/test_mcp_filtering_integration.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/tests/dao_ai/test_mcp_function_model.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/tests/dao_ai/test_message_validation_middleware.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/tests/dao_ai/test_messages.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/tests/dao_ai/test_models.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/tests/dao_ai/test_optimization.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/tests/dao_ai/test_postgres_integration.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/tests/dao_ai/test_prompt_optimizations.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/tests/dao_ai/test_prompts.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/tests/dao_ai/test_reranking.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/tests/dao_ai/test_reranking_integration.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/tests/dao_ai/test_resources_model_genie_integration.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/tests/dao_ai/test_response_format.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/tests/dao_ai/test_responses_agent_structured_output_unit.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/tests/dao_ai/test_semantic_cache_context.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/tests/dao_ai/test_sql_tool.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/tests/dao_ai/test_sql_tool_integration.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/tests/dao_ai/test_state.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/tests/dao_ai/test_summarization_inference.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/tests/dao_ai/test_swarm_middleware.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/tests/dao_ai/test_tools.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/tests/dao_ai/test_types.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/tests/dao_ai/test_unity_catalog.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/tests/dao_ai/test_utils.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/tests/dao_ai/test_utils_type_from_fqn.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/tests/dao_ai/test_vector_search.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/tests/dao_ai/test_warehouse_model.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/tests/dao_ai/weather_server_mcp.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/tests/hardware_store/.gitkeep +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/tests/hardware_store/test_graph.py +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/tests/images/doritos_upc.png +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/tests/images/lays_upc.png +0 -0
- {dao_ai-0.1.11 → dao_ai-0.1.13}/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.1.
|
|
3
|
+
Version: 0.1.13
|
|
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
|
|
@@ -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.
|
|
@@ -345,6 +345,7 @@ DAO provides powerful capabilities for building production-ready AI agents:
|
|
|
345
345
|
|
|
346
346
|
| Feature | Description |
|
|
347
347
|
|---------|-------------|
|
|
348
|
+
| **Dual Deployment Targets** | Deploy to Databricks Model Serving or Databricks Apps with a single config |
|
|
348
349
|
| **Multi-Tool Support** | Python functions, Unity Catalog, MCP, Agent Endpoints |
|
|
349
350
|
| **On-Behalf-Of User** | Per-user permissions and governance |
|
|
350
351
|
| **Advanced Caching** | Two-tier (LRU + Semantic) caching for cost optimization |
|
|
@@ -46,7 +46,7 @@ DAO AI Builder generates valid YAML configurations that work seamlessly with thi
|
|
|
46
46
|
- **[Architecture](docs/architecture.md)** - Understand how DAO works under the hood
|
|
47
47
|
|
|
48
48
|
### Core Concepts
|
|
49
|
-
- **[Key Capabilities](docs/key-capabilities.md)** - Explore
|
|
49
|
+
- **[Key Capabilities](docs/key-capabilities.md)** - Explore 15 powerful features for production agents
|
|
50
50
|
- **[Configuration Reference](docs/configuration-reference.md)** - Complete YAML configuration guide
|
|
51
51
|
- **[Examples](docs/examples.md)** - Ready-to-use example configurations
|
|
52
52
|
|
|
@@ -69,7 +69,7 @@ Before you begin, you'll need:
|
|
|
69
69
|
- **Python 3.11 or newer** installed on your computer ([download here](https://www.python.org/downloads/))
|
|
70
70
|
- **A Databricks workspace** (ask your IT team or see [Databricks docs](https://docs.databricks.com/))
|
|
71
71
|
- Access to **Unity Catalog** (your organization's data catalog)
|
|
72
|
-
- **Model Serving** enabled (for deploying AI agents)
|
|
72
|
+
- **Model Serving** or **Databricks Apps** enabled (for deploying AI agents)
|
|
73
73
|
- *Optional*: Vector Search, Genie (for advanced features)
|
|
74
74
|
|
|
75
75
|
**Not sure if you have access?** Your Databricks administrator can grant you permissions.
|
|
@@ -266,6 +266,7 @@ DAO provides powerful capabilities for building production-ready AI agents:
|
|
|
266
266
|
|
|
267
267
|
| Feature | Description |
|
|
268
268
|
|---------|-------------|
|
|
269
|
+
| **Dual Deployment Targets** | Deploy to Databricks Model Serving or Databricks Apps with a single config |
|
|
269
270
|
| **Multi-Tool Support** | Python functions, Unity Catalog, MCP, Agent Endpoints |
|
|
270
271
|
| **On-Behalf-Of User** | Per-user permissions and governance |
|
|
271
272
|
| **Advanced Caching** | Two-tier (LRU + Semantic) caching for cost optimization |
|
|
@@ -26,6 +26,18 @@
|
|
|
26
26
|
# - Composite: { type: composite, options: [${VAR1}, ${VAR2}, default] }
|
|
27
27
|
# - Primitives: Just use the value directly
|
|
28
28
|
|
|
29
|
+
variables:
|
|
30
|
+
client_id: &client_id
|
|
31
|
+
options:
|
|
32
|
+
- env: RETAIL_AI_DATABRICKS_CLIENT_ID # Service principal client ID
|
|
33
|
+
- scope: retail_consumer_goods
|
|
34
|
+
secret: RETAIL_AI_DATABRICKS_CLIENT_ID
|
|
35
|
+
client_secret: &client_secret
|
|
36
|
+
options:
|
|
37
|
+
- env: RETAIL_AI_DATABRICKS_CLIENT_SECRET # Service principal secret
|
|
38
|
+
- scope: retail_consumer_goods
|
|
39
|
+
secret: RETAIL_AI_DATABRICKS_CLIENT_SECRET
|
|
40
|
+
|
|
29
41
|
schemas:
|
|
30
42
|
retail_schema: &retail_schema
|
|
31
43
|
catalog_name: nfleming
|
|
@@ -42,6 +54,8 @@ resources:
|
|
|
42
54
|
lakebase_db: &lakebase_db
|
|
43
55
|
name: retail-consumer-goods
|
|
44
56
|
instance_name: retail-consumer-goods
|
|
57
|
+
client_id: *client_id
|
|
58
|
+
client_secret: *client_secret
|
|
45
59
|
|
|
46
60
|
# =============================================================================
|
|
47
61
|
# TOOLS WITH HUMAN-IN-THE-LOOP CONFIGURATIONS
|
|
@@ -15,14 +15,15 @@
|
|
|
15
15
|
variables:
|
|
16
16
|
client_id: &client_id
|
|
17
17
|
options:
|
|
18
|
-
- env: RETAIL_AI_DATABRICKS_CLIENT_ID # Service principal client ID
|
|
19
18
|
- scope: retail_consumer_goods
|
|
20
19
|
secret: RETAIL_AI_DATABRICKS_CLIENT_ID
|
|
20
|
+
- env: RETAIL_AI_DATABRICKS_CLIENT_ID # Service principal client ID
|
|
21
|
+
|
|
21
22
|
client_secret: &client_secret
|
|
22
23
|
options:
|
|
23
|
-
- env: RETAIL_AI_DATABRICKS_CLIENT_SECRET # Service principal secret
|
|
24
24
|
- scope: retail_consumer_goods
|
|
25
25
|
secret: RETAIL_AI_DATABRICKS_CLIENT_SECRET
|
|
26
|
+
- env: RETAIL_AI_DATABRICKS_CLIENT_SECRET # Service principal secret
|
|
26
27
|
|
|
27
28
|
schemas:
|
|
28
29
|
retail_schema: &retail_schema
|
|
@@ -2,7 +2,62 @@
|
|
|
2
2
|
|
|
3
3
|
These are the powerful features that make DAO production-ready. Don't worry if some seem complex — you can start simple and add these capabilities as you need them.
|
|
4
4
|
|
|
5
|
-
## 1.
|
|
5
|
+
## 1. Dual Deployment Targets
|
|
6
|
+
|
|
7
|
+
**What is this?** DAO agents can be deployed to either **Databricks Model Serving** or **Databricks Apps** using the same configuration, giving you flexibility in how you expose your agent.
|
|
8
|
+
|
|
9
|
+
**Why this matters:**
|
|
10
|
+
- **Model Serving**: Traditional endpoint for inference workloads, autoscaling, pay-per-token pricing
|
|
11
|
+
- **Databricks Apps**: Full web applications with custom UI, background jobs, and richer integrations
|
|
12
|
+
- **Single Configuration**: Switch deployment targets with one line change — no code rewrite needed
|
|
13
|
+
- **Environment Consistency**: Same YAML config works in both environments
|
|
14
|
+
|
|
15
|
+
**Comparison:**
|
|
16
|
+
|
|
17
|
+
| Feature | Model Serving | Databricks Apps |
|
|
18
|
+
|---------|--------------|-----------------|
|
|
19
|
+
| **Use Case** | Inference API endpoint | Full web application |
|
|
20
|
+
| **Scaling** | Auto-scales based on load | Manual scaling configuration |
|
|
21
|
+
| **UI** | API only | Custom web UI possible |
|
|
22
|
+
| **Pricing** | Pay per token/request | Compute-based |
|
|
23
|
+
| **Deployment Speed** | ~2-5 minutes | ~2-5 minutes |
|
|
24
|
+
| **Best For** | API integrations, high throughput | Interactive apps, custom UX |
|
|
25
|
+
|
|
26
|
+
**How to configure:**
|
|
27
|
+
|
|
28
|
+
```yaml
|
|
29
|
+
app:
|
|
30
|
+
name: my_agent
|
|
31
|
+
deployment_target: model_serving # or 'apps'
|
|
32
|
+
|
|
33
|
+
# Model Serving specific options (only used when deployment_target: model_serving)
|
|
34
|
+
endpoint_name: my_agent_endpoint
|
|
35
|
+
workload_size: Small
|
|
36
|
+
scale_to_zero: true
|
|
37
|
+
|
|
38
|
+
agents:
|
|
39
|
+
- *my_agent
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
**Deploy to Model Serving:**
|
|
43
|
+
```bash
|
|
44
|
+
dao-ai deploy -c config.yaml --target model_serving
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
**Deploy to Databricks Apps:**
|
|
48
|
+
```bash
|
|
49
|
+
dao-ai deploy -c config.yaml --target apps
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
**CLI override:** The `--target` flag always takes precedence over the YAML config, making it easy to deploy the same config to different environments.
|
|
53
|
+
|
|
54
|
+
**Behind the scenes:**
|
|
55
|
+
- Model Serving deployments create an MLflow model and serving endpoint
|
|
56
|
+
- Apps deployments create a Databricks App with MLflow experiment tracking
|
|
57
|
+
- Both share the same agent code, tools, and orchestration logic
|
|
58
|
+
- Environment variables and secrets are automatically configured for each platform
|
|
59
|
+
|
|
60
|
+
## 2. Multi-Tool Support
|
|
6
61
|
|
|
7
62
|
**What are tools?** Tools are actions an agent can perform — like querying a database, calling an API, or running custom code.
|
|
8
63
|
|
|
@@ -57,7 +112,7 @@ tools:
|
|
|
57
112
|
connection: *github_connection
|
|
58
113
|
```
|
|
59
114
|
|
|
60
|
-
##
|
|
115
|
+
## 3. On-Behalf-Of User Support
|
|
61
116
|
|
|
62
117
|
**What is this?** Many Databricks resources (like SQL warehouses, Genie spaces, and LLMs) can operate "on behalf of" the end user, using their permissions instead of the agent's service account credentials.
|
|
63
118
|
|
|
@@ -104,7 +159,7 @@ The same agent code enforces different permissions for each user automatically.
|
|
|
104
159
|
- The user must have the necessary permissions on the underlying resources
|
|
105
160
|
- Not all Databricks resources support on-behalf-of functionality
|
|
106
161
|
|
|
107
|
-
##
|
|
162
|
+
## 4. Advanced Caching (Genie Queries)
|
|
108
163
|
|
|
109
164
|
**Why caching matters:** When users ask similar questions repeatedly, you don't want to pay for the same AI processing over and over. Caching stores results so you can reuse them.
|
|
110
165
|
|
|
@@ -234,7 +289,7 @@ This works by embedding both the current question *and* recent conversation turn
|
|
|
234
289
|
|
|
235
290
|
For more details on semantic cache configuration, see [docs/semantic_cache_weight_configuration.md](semantic_cache_weight_configuration.md).
|
|
236
291
|
|
|
237
|
-
##
|
|
292
|
+
## 5. Vector Search Reranking
|
|
238
293
|
|
|
239
294
|
**The problem:** Vector search (semantic similarity) is fast but sometimes returns loosely related results. It's like a librarian who quickly grabs 50 books that *might* be relevant.
|
|
240
295
|
|
|
@@ -321,7 +376,7 @@ rerank:
|
|
|
321
376
|
|
|
322
377
|
**Note:** Model weights are downloaded automatically on first use (~34MB for MiniLM-L-12-v2).
|
|
323
378
|
|
|
324
|
-
##
|
|
379
|
+
## 6. Human-in-the-Loop Approvals
|
|
325
380
|
|
|
326
381
|
**Why this matters:** Some actions are too important to automate completely. For example, you might want human approval before an agent:
|
|
327
382
|
- Deletes data
|
|
@@ -343,7 +398,7 @@ tools:
|
|
|
343
398
|
review_prompt: "This operation will modify production data. Approve?"
|
|
344
399
|
```
|
|
345
400
|
|
|
346
|
-
##
|
|
401
|
+
## 7. Memory & State Persistence
|
|
347
402
|
|
|
348
403
|
**What is memory?** Your agent needs to remember past conversations. When a user asks "What about size XL?" the agent should remember they were talking about shirts.
|
|
349
404
|
|
|
@@ -395,7 +450,7 @@ memory:
|
|
|
395
450
|
- **PostgreSQL**: When you need external database features or already have PostgreSQL infrastructure
|
|
396
451
|
- **Lakebase**: When you want Databricks-native persistence with Unity Catalog governance
|
|
397
452
|
|
|
398
|
-
##
|
|
453
|
+
## 8. MLflow Prompt Registry Integration
|
|
399
454
|
|
|
400
455
|
**The problem:** Prompts (instructions you give to AI models) need constant refinement. Hardcoding them in YAML means every change requires redeployment.
|
|
401
456
|
|
|
@@ -427,7 +482,7 @@ agents:
|
|
|
427
482
|
prompt: *product_expert_prompt # Loaded from MLflow registry
|
|
428
483
|
```
|
|
429
484
|
|
|
430
|
-
##
|
|
485
|
+
## 9. Automated Prompt Optimization
|
|
431
486
|
|
|
432
487
|
**What is this?** Instead of manually tweaking prompts through trial and error, DAO can automatically test variations and find the best one.
|
|
433
488
|
|
|
@@ -452,7 +507,7 @@ optimizations:
|
|
|
452
507
|
num_candidates: 5
|
|
453
508
|
```
|
|
454
509
|
|
|
455
|
-
##
|
|
510
|
+
## 10. Guardrails & Response Quality Middleware
|
|
456
511
|
|
|
457
512
|
**What are guardrails?** Safety and quality controls that validate agent responses before they reach users. Think of them as quality assurance checkpoints.
|
|
458
513
|
|
|
@@ -670,7 +725,7 @@ agents:
|
|
|
670
725
|
prompt: *professional_tone_prompt
|
|
671
726
|
```
|
|
672
727
|
|
|
673
|
-
##
|
|
728
|
+
## 11. Conversation Summarization
|
|
674
729
|
|
|
675
730
|
**The problem:** AI models have a maximum amount of text they can process (the "context window"). Long conversations eventually exceed this limit.
|
|
676
731
|
|
|
@@ -697,7 +752,7 @@ The `LoggingSummarizationMiddleware` provides detailed observability:
|
|
|
697
752
|
INFO | Summarization: BEFORE 25 messages (~12500 tokens) → AFTER 3 messages (~2100 tokens) | Reduced by ~10400 tokens
|
|
698
753
|
```
|
|
699
754
|
|
|
700
|
-
##
|
|
755
|
+
## 12. Structured Output (Response Format)
|
|
701
756
|
|
|
702
757
|
**What is this?** A way to force your agent to return data in a specific JSON structure, making responses machine-readable and predictable.
|
|
703
758
|
|
|
@@ -749,7 +804,7 @@ See `config/examples/09_structured_output/structured_output.yaml` for a complete
|
|
|
749
804
|
|
|
750
805
|
---
|
|
751
806
|
|
|
752
|
-
##
|
|
807
|
+
## 13. Custom Input & Custom Output Support
|
|
753
808
|
|
|
754
809
|
**What is this?** A flexible system for passing custom configuration values to your agents and receiving enriched output with runtime state.
|
|
755
810
|
|
|
@@ -829,7 +884,7 @@ When invoked with the `custom_inputs` above, the prompt automatically populates:
|
|
|
829
884
|
- `session` state is automatically maintained and returned in `custom_outputs`
|
|
830
885
|
- Backward compatible with legacy flat custom_inputs format
|
|
831
886
|
|
|
832
|
-
##
|
|
887
|
+
## 14. Middleware (Input Validation, Logging, Monitoring)
|
|
833
888
|
|
|
834
889
|
**What is middleware?** Middleware are functions that wrap around agent execution to add cross-cutting concerns like validation, logging, authentication, and monitoring. They run before and after the agent processes requests.
|
|
835
890
|
|
|
@@ -1049,7 +1104,7 @@ agents:
|
|
|
1049
1104
|
|
|
1050
1105
|
---
|
|
1051
1106
|
|
|
1052
|
-
##
|
|
1107
|
+
## 15. Hook System
|
|
1053
1108
|
|
|
1054
1109
|
**What are hooks?** Hooks let you run custom code at specific moments in your agent's lifecycle — like "before starting" or "when shutting down".
|
|
1055
1110
|
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "dao-ai"
|
|
7
|
-
version = "0.1.
|
|
7
|
+
version = "0.1.13"
|
|
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" }
|
|
@@ -34,7 +34,7 @@ mlflow.set_tracking_uri("databricks")
|
|
|
34
34
|
mlflow.langchain.autolog()
|
|
35
35
|
|
|
36
36
|
# Get config path from environment or use default
|
|
37
|
-
config_path: str = os.environ.get("DAO_AI_CONFIG_PATH", "
|
|
37
|
+
config_path: str = os.environ.get("DAO_AI_CONFIG_PATH", "dao_ai.yaml")
|
|
38
38
|
|
|
39
39
|
# Load configuration using AppConfig.from_file (consistent with CLI, notebook, builder)
|
|
40
40
|
config: AppConfig = AppConfig.from_file(config_path)
|
|
@@ -310,6 +310,25 @@ def _extract_secrets_from_config(config: AppConfig) -> list[dict[str, Any]]:
|
|
|
310
310
|
A list of secret resource dictionaries with unique scope/key pairs
|
|
311
311
|
"""
|
|
312
312
|
secrets: dict[tuple[str, str], dict[str, Any]] = {}
|
|
313
|
+
used_names: set[str] = set()
|
|
314
|
+
|
|
315
|
+
def get_unique_resource_name(base_name: str) -> str:
|
|
316
|
+
"""Generate a unique resource name, adding suffix if needed."""
|
|
317
|
+
sanitized = _sanitize_resource_name(base_name)
|
|
318
|
+
if sanitized not in used_names:
|
|
319
|
+
used_names.add(sanitized)
|
|
320
|
+
return sanitized
|
|
321
|
+
# Name collision - add numeric suffix
|
|
322
|
+
counter = 1
|
|
323
|
+
while True:
|
|
324
|
+
# Leave room for suffix (e.g., "_1", "_2", etc.)
|
|
325
|
+
suffix = f"_{counter}"
|
|
326
|
+
max_base_len = 30 - len(suffix)
|
|
327
|
+
candidate = sanitized[:max_base_len] + suffix
|
|
328
|
+
if candidate not in used_names:
|
|
329
|
+
used_names.add(candidate)
|
|
330
|
+
return candidate
|
|
331
|
+
counter += 1
|
|
313
332
|
|
|
314
333
|
def extract_from_value(value: Any, path: str = "") -> None:
|
|
315
334
|
"""Recursively extract secrets from any value."""
|
|
@@ -317,9 +336,10 @@ def _extract_secrets_from_config(config: AppConfig) -> list[dict[str, Any]]:
|
|
|
317
336
|
secret_key = (value.scope, value.secret)
|
|
318
337
|
if secret_key not in secrets:
|
|
319
338
|
# Create a unique name for the secret resource
|
|
320
|
-
|
|
321
|
-
"
|
|
322
|
-
)
|
|
339
|
+
base_name = f"{value.scope}_{value.secret}".replace("-", "_").replace(
|
|
340
|
+
"/", "_"
|
|
341
|
+
)
|
|
342
|
+
resource_name = get_unique_resource_name(base_name)
|
|
323
343
|
secrets[secret_key] = {
|
|
324
344
|
"name": resource_name,
|
|
325
345
|
"type": "secret",
|
|
@@ -327,7 +347,9 @@ def _extract_secrets_from_config(config: AppConfig) -> list[dict[str, Any]]:
|
|
|
327
347
|
"key": value.secret,
|
|
328
348
|
"permissions": [{"level": "READ"}],
|
|
329
349
|
}
|
|
330
|
-
logger.debug(
|
|
350
|
+
logger.debug(
|
|
351
|
+
f"Found secret: {value.scope}/{value.secret} at {path} -> resource: {resource_name}"
|
|
352
|
+
)
|
|
331
353
|
elif isinstance(value, dict):
|
|
332
354
|
for k, v in value.items():
|
|
333
355
|
extract_from_value(v, f"{path}.{k}" if path else k)
|
|
@@ -742,6 +764,25 @@ def _extract_sdk_secrets_from_config(config: AppConfig) -> list[AppResource]:
|
|
|
742
764
|
A list of AppResource objects for secrets
|
|
743
765
|
"""
|
|
744
766
|
secrets: dict[tuple[str, str], AppResource] = {}
|
|
767
|
+
used_names: set[str] = set()
|
|
768
|
+
|
|
769
|
+
def get_unique_resource_name(base_name: str) -> str:
|
|
770
|
+
"""Generate a unique resource name, adding suffix if needed."""
|
|
771
|
+
sanitized = _sanitize_resource_name(base_name)
|
|
772
|
+
if sanitized not in used_names:
|
|
773
|
+
used_names.add(sanitized)
|
|
774
|
+
return sanitized
|
|
775
|
+
# Name collision - add numeric suffix
|
|
776
|
+
counter = 1
|
|
777
|
+
while True:
|
|
778
|
+
# Leave room for suffix (e.g., "_1", "_2", etc.)
|
|
779
|
+
suffix = f"_{counter}"
|
|
780
|
+
max_base_len = 30 - len(suffix)
|
|
781
|
+
candidate = sanitized[:max_base_len] + suffix
|
|
782
|
+
if candidate not in used_names:
|
|
783
|
+
used_names.add(candidate)
|
|
784
|
+
return candidate
|
|
785
|
+
counter += 1
|
|
745
786
|
|
|
746
787
|
def extract_from_value(value: Any) -> None:
|
|
747
788
|
"""Recursively extract secrets from any value."""
|
|
@@ -749,10 +790,10 @@ def _extract_sdk_secrets_from_config(config: AppConfig) -> list[AppResource]:
|
|
|
749
790
|
secret_key = (value.scope, value.secret)
|
|
750
791
|
if secret_key not in secrets:
|
|
751
792
|
# Create a unique name for the secret resource
|
|
752
|
-
|
|
753
|
-
"
|
|
754
|
-
)
|
|
755
|
-
resource_name =
|
|
793
|
+
base_name = f"{value.scope}_{value.secret}".replace("-", "_").replace(
|
|
794
|
+
"/", "_"
|
|
795
|
+
)
|
|
796
|
+
resource_name = get_unique_resource_name(base_name)
|
|
756
797
|
|
|
757
798
|
resource = AppResource(
|
|
758
799
|
name=resource_name,
|
|
@@ -764,7 +805,7 @@ def _extract_sdk_secrets_from_config(config: AppConfig) -> list[AppResource]:
|
|
|
764
805
|
)
|
|
765
806
|
secrets[secret_key] = resource
|
|
766
807
|
logger.debug(
|
|
767
|
-
f"Found secret for SDK resource: {value.scope}/{value.secret}"
|
|
808
|
+
f"Found secret for SDK resource: {value.scope}/{value.secret} -> resource: {resource_name}"
|
|
768
809
|
)
|
|
769
810
|
elif isinstance(value, dict):
|
|
770
811
|
for v in value.values():
|
|
@@ -969,12 +1010,21 @@ def generate_app_yaml(
|
|
|
969
1010
|
{"name": "MLFLOW_TRACKING_URI", "value": "databricks"},
|
|
970
1011
|
{"name": "MLFLOW_REGISTRY_URI", "value": "databricks-uc"},
|
|
971
1012
|
{"name": "MLFLOW_EXPERIMENT_ID", "valueFrom": "experiment"},
|
|
972
|
-
{"name": "DAO_AI_CONFIG_PATH", "value": "
|
|
1013
|
+
{"name": "DAO_AI_CONFIG_PATH", "value": "dao_ai.yaml"},
|
|
973
1014
|
]
|
|
974
1015
|
|
|
975
1016
|
# Extract environment variables from config.app.environment_vars
|
|
976
1017
|
config_env_vars = _extract_env_vars_from_config(config)
|
|
977
1018
|
|
|
1019
|
+
# Environment variables that are automatically provided by Databricks Apps
|
|
1020
|
+
# and should not be included in app.yaml
|
|
1021
|
+
platform_provided_env_vars = {"DATABRICKS_HOST"}
|
|
1022
|
+
|
|
1023
|
+
# Filter out platform-provided env vars from config
|
|
1024
|
+
config_env_vars = [
|
|
1025
|
+
e for e in config_env_vars if e["name"] not in platform_provided_env_vars
|
|
1026
|
+
]
|
|
1027
|
+
|
|
978
1028
|
# Merge config env vars, avoiding duplicates (config takes precedence)
|
|
979
1029
|
base_env_names = {e["name"] for e in env_vars}
|
|
980
1030
|
for config_env in config_env_vars:
|
|
@@ -7,13 +7,13 @@ uses the AgentServer for the Databricks Apps runtime.
|
|
|
7
7
|
|
|
8
8
|
Configuration Loading:
|
|
9
9
|
The config path is specified via the DAO_AI_CONFIG_PATH environment variable,
|
|
10
|
-
or defaults to
|
|
10
|
+
or defaults to dao_ai.yaml in the current directory.
|
|
11
11
|
|
|
12
12
|
Usage:
|
|
13
13
|
# With environment variable
|
|
14
14
|
DAO_AI_CONFIG_PATH=/path/to/config.yaml python -m dao_ai.apps.server
|
|
15
15
|
|
|
16
|
-
# With default
|
|
16
|
+
# With default dao_ai.yaml in current directory
|
|
17
17
|
python -m dao_ai.apps.server
|
|
18
18
|
"""
|
|
19
19
|
|
|
@@ -294,36 +294,37 @@ class IsDatabricksResource(ABC, BaseModel):
|
|
|
294
294
|
|
|
295
295
|
# Check for OBO first (highest priority)
|
|
296
296
|
if self.on_behalf_of_user:
|
|
297
|
-
#
|
|
298
|
-
|
|
299
|
-
|
|
300
|
-
|
|
301
|
-
|
|
302
|
-
|
|
297
|
+
# In Databricks Apps, use forwarded headers for per-user auth
|
|
298
|
+
from mlflow.genai.agent_server import get_request_headers
|
|
299
|
+
|
|
300
|
+
headers = get_request_headers()
|
|
301
|
+
logger.debug(f"Headers received: {list(headers.keys())}")
|
|
302
|
+
# Try both lowercase and title-case header names (HTTP headers are case-insensitive)
|
|
303
|
+
forwarded_token = headers.get("x-forwarded-access-token") or headers.get(
|
|
304
|
+
"X-Forwarded-Access-Token"
|
|
305
|
+
)
|
|
303
306
|
|
|
304
|
-
|
|
305
|
-
|
|
306
|
-
|
|
307
|
-
|
|
308
|
-
|
|
309
|
-
|
|
310
|
-
|
|
311
|
-
|
|
312
|
-
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
pass
|
|
307
|
+
if forwarded_token:
|
|
308
|
+
forwarded_user = headers.get("x-forwarded-user") or headers.get(
|
|
309
|
+
"X-Forwarded-User", "unknown"
|
|
310
|
+
)
|
|
311
|
+
logger.debug(
|
|
312
|
+
f"Creating WorkspaceClient for {self.__class__.__name__} "
|
|
313
|
+
f"with OBO using forwarded token from Databricks Apps",
|
|
314
|
+
forwarded_user=forwarded_user,
|
|
315
|
+
)
|
|
316
|
+
# Use workspace_host if configured, otherwise SDK will auto-detect
|
|
317
|
+
workspace_host_value: str | None = (
|
|
318
|
+
normalize_host(value_of(self.workspace_host))
|
|
319
|
+
if self.workspace_host
|
|
320
|
+
else None
|
|
321
|
+
)
|
|
322
|
+
return WorkspaceClient(
|
|
323
|
+
host=workspace_host_value,
|
|
324
|
+
token=forwarded_token,
|
|
325
|
+
auth_type="pat",
|
|
326
|
+
)
|
|
325
327
|
|
|
326
|
-
# Fall back to Model Serving OBO (existing behavior)
|
|
327
328
|
credentials_strategy: CredentialsStrategy = ModelServingUserCredentials()
|
|
328
329
|
logger.debug(
|
|
329
330
|
f"Creating WorkspaceClient for {self.__class__.__name__} "
|
|
@@ -152,25 +152,77 @@ class DatabricksProvider(ServiceProvider):
|
|
|
152
152
|
client_secret: str | None = None,
|
|
153
153
|
workspace_host: str | None = None,
|
|
154
154
|
) -> None:
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
|
|
160
|
-
|
|
155
|
+
# Store credentials for lazy initialization
|
|
156
|
+
self._pat = pat
|
|
157
|
+
self._client_id = client_id
|
|
158
|
+
self._client_secret = client_secret
|
|
159
|
+
self._workspace_host = workspace_host
|
|
160
|
+
|
|
161
|
+
# Lazy initialization for WorkspaceClient
|
|
162
|
+
self._w: WorkspaceClient | None = w
|
|
163
|
+
self._w_initialized = w is not None
|
|
164
|
+
|
|
165
|
+
# Lazy initialization for VectorSearchClient - only create when needed
|
|
166
|
+
# This avoids authentication errors in Databricks Apps where VSC
|
|
167
|
+
# requires explicit credentials but the platform uses ambient auth
|
|
168
|
+
self._vsc: VectorSearchClient | None = vsc
|
|
169
|
+
self._vsc_initialized = vsc is not None
|
|
170
|
+
|
|
171
|
+
# Lazy initialization for DatabricksFunctionClient
|
|
172
|
+
self._dfs: DatabricksFunctionClient | None = dfs
|
|
173
|
+
self._dfs_initialized = dfs is not None
|
|
174
|
+
|
|
175
|
+
@property
|
|
176
|
+
def w(self) -> WorkspaceClient:
|
|
177
|
+
"""Lazy initialization of WorkspaceClient."""
|
|
178
|
+
if not self._w_initialized:
|
|
179
|
+
self._w = _workspace_client(
|
|
180
|
+
pat=self._pat,
|
|
181
|
+
client_id=self._client_id,
|
|
182
|
+
client_secret=self._client_secret,
|
|
183
|
+
workspace_host=self._workspace_host,
|
|
161
184
|
)
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
185
|
+
self._w_initialized = True
|
|
186
|
+
return self._w # type: ignore[return-value]
|
|
187
|
+
|
|
188
|
+
@w.setter
|
|
189
|
+
def w(self, value: WorkspaceClient) -> None:
|
|
190
|
+
"""Set WorkspaceClient and mark as initialized."""
|
|
191
|
+
self._w = value
|
|
192
|
+
self._w_initialized = True
|
|
193
|
+
|
|
194
|
+
@property
|
|
195
|
+
def vsc(self) -> VectorSearchClient:
|
|
196
|
+
"""Lazy initialization of VectorSearchClient."""
|
|
197
|
+
if not self._vsc_initialized:
|
|
198
|
+
self._vsc = _vector_search_client(
|
|
199
|
+
pat=self._pat,
|
|
200
|
+
client_id=self._client_id,
|
|
201
|
+
client_secret=self._client_secret,
|
|
202
|
+
workspace_host=self._workspace_host,
|
|
168
203
|
)
|
|
169
|
-
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
173
|
-
|
|
204
|
+
self._vsc_initialized = True
|
|
205
|
+
return self._vsc # type: ignore[return-value]
|
|
206
|
+
|
|
207
|
+
@vsc.setter
|
|
208
|
+
def vsc(self, value: VectorSearchClient) -> None:
|
|
209
|
+
"""Set VectorSearchClient and mark as initialized."""
|
|
210
|
+
self._vsc = value
|
|
211
|
+
self._vsc_initialized = True
|
|
212
|
+
|
|
213
|
+
@property
|
|
214
|
+
def dfs(self) -> DatabricksFunctionClient:
|
|
215
|
+
"""Lazy initialization of DatabricksFunctionClient."""
|
|
216
|
+
if not self._dfs_initialized:
|
|
217
|
+
self._dfs = _function_client(w=self.w)
|
|
218
|
+
self._dfs_initialized = True
|
|
219
|
+
return self._dfs # type: ignore[return-value]
|
|
220
|
+
|
|
221
|
+
@dfs.setter
|
|
222
|
+
def dfs(self, value: DatabricksFunctionClient) -> None:
|
|
223
|
+
"""Set DatabricksFunctionClient and mark as initialized."""
|
|
224
|
+
self._dfs = value
|
|
225
|
+
self._dfs_initialized = True
|
|
174
226
|
|
|
175
227
|
def experiment_name(self, config: AppConfig) -> str:
|
|
176
228
|
current_user: User = self.w.current_user.me()
|
|
@@ -572,7 +624,7 @@ class DatabricksProvider(ServiceProvider):
|
|
|
572
624
|
source_config_path: str | None = config.source_config_path
|
|
573
625
|
if source_config_path:
|
|
574
626
|
# Read the config file and upload to workspace
|
|
575
|
-
config_file_name: str = "
|
|
627
|
+
config_file_name: str = "dao_ai.yaml"
|
|
576
628
|
workspace_config_path: str = f"{source_path}/{config_file_name}"
|
|
577
629
|
|
|
578
630
|
logger.info(
|
|
@@ -603,7 +655,7 @@ class DatabricksProvider(ServiceProvider):
|
|
|
603
655
|
logger.warning(
|
|
604
656
|
"No source config path available. "
|
|
605
657
|
"Ensure DAO_AI_CONFIG_PATH is set in the app environment or "
|
|
606
|
-
"
|
|
658
|
+
"dao_ai.yaml exists in the app source directory."
|
|
607
659
|
)
|
|
608
660
|
|
|
609
661
|
# Generate and upload app.yaml with dynamically discovered resources
|
|
@@ -634,7 +686,9 @@ class DatabricksProvider(ServiceProvider):
|
|
|
634
686
|
generate_user_api_scopes,
|
|
635
687
|
)
|
|
636
688
|
|
|
637
|
-
sdk_resources = generate_sdk_resources(
|
|
689
|
+
sdk_resources = generate_sdk_resources(
|
|
690
|
+
config, experiment_id=experiment.experiment_id
|
|
691
|
+
)
|
|
638
692
|
if sdk_resources:
|
|
639
693
|
logger.info(
|
|
640
694
|
"Discovered app resources from config",
|