dao-ai 0.0.36__py3-none-any.whl → 0.1.1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (59) hide show
  1. dao_ai/__init__.py +29 -0
  2. dao_ai/cli.py +195 -30
  3. dao_ai/config.py +770 -244
  4. dao_ai/genie/__init__.py +1 -22
  5. dao_ai/genie/cache/__init__.py +1 -2
  6. dao_ai/genie/cache/base.py +20 -70
  7. dao_ai/genie/cache/core.py +75 -0
  8. dao_ai/genie/cache/lru.py +44 -21
  9. dao_ai/genie/cache/semantic.py +390 -109
  10. dao_ai/genie/core.py +35 -0
  11. dao_ai/graph.py +27 -253
  12. dao_ai/hooks/__init__.py +9 -6
  13. dao_ai/hooks/core.py +22 -190
  14. dao_ai/memory/__init__.py +10 -0
  15. dao_ai/memory/core.py +23 -5
  16. dao_ai/memory/databricks.py +389 -0
  17. dao_ai/memory/postgres.py +2 -2
  18. dao_ai/messages.py +6 -4
  19. dao_ai/middleware/__init__.py +125 -0
  20. dao_ai/middleware/assertions.py +778 -0
  21. dao_ai/middleware/base.py +50 -0
  22. dao_ai/middleware/core.py +61 -0
  23. dao_ai/middleware/guardrails.py +415 -0
  24. dao_ai/middleware/human_in_the_loop.py +228 -0
  25. dao_ai/middleware/message_validation.py +554 -0
  26. dao_ai/middleware/summarization.py +192 -0
  27. dao_ai/models.py +1177 -108
  28. dao_ai/nodes.py +118 -161
  29. dao_ai/optimization.py +664 -0
  30. dao_ai/orchestration/__init__.py +52 -0
  31. dao_ai/orchestration/core.py +287 -0
  32. dao_ai/orchestration/supervisor.py +264 -0
  33. dao_ai/orchestration/swarm.py +226 -0
  34. dao_ai/prompts.py +126 -29
  35. dao_ai/providers/databricks.py +126 -381
  36. dao_ai/state.py +139 -21
  37. dao_ai/tools/__init__.py +8 -5
  38. dao_ai/tools/core.py +57 -4
  39. dao_ai/tools/email.py +280 -0
  40. dao_ai/tools/genie.py +47 -24
  41. dao_ai/tools/mcp.py +4 -3
  42. dao_ai/tools/memory.py +50 -0
  43. dao_ai/tools/python.py +4 -12
  44. dao_ai/tools/search.py +14 -0
  45. dao_ai/tools/slack.py +1 -1
  46. dao_ai/tools/unity_catalog.py +8 -6
  47. dao_ai/tools/vector_search.py +16 -9
  48. dao_ai/utils.py +72 -8
  49. dao_ai-0.1.1.dist-info/METADATA +1878 -0
  50. dao_ai-0.1.1.dist-info/RECORD +62 -0
  51. dao_ai/chat_models.py +0 -204
  52. dao_ai/guardrails.py +0 -112
  53. dao_ai/tools/genie/__init__.py +0 -236
  54. dao_ai/tools/human_in_the_loop.py +0 -100
  55. dao_ai-0.0.36.dist-info/METADATA +0 -951
  56. dao_ai-0.0.36.dist-info/RECORD +0 -47
  57. {dao_ai-0.0.36.dist-info → dao_ai-0.1.1.dist-info}/WHEEL +0 -0
  58. {dao_ai-0.0.36.dist-info → dao_ai-0.1.1.dist-info}/entry_points.txt +0 -0
  59. {dao_ai-0.0.36.dist-info → dao_ai-0.1.1.dist-info}/licenses/LICENSE +0 -0
@@ -1,100 +0,0 @@
1
- from typing import Any, Optional
2
-
3
- from langchain_core.runnables import RunnableConfig
4
- from langchain_core.runnables.base import RunnableLike
5
- from langchain_core.tools import BaseTool
6
- from langchain_core.tools import tool as create_tool
7
- from langgraph.prebuilt.interrupt import HumanInterrupt, HumanInterruptConfig
8
- from langgraph.types import interrupt
9
- from loguru import logger
10
-
11
- from dao_ai.config import (
12
- BaseFunctionModel,
13
- HumanInTheLoopModel,
14
- )
15
-
16
-
17
- def add_human_in_the_loop(
18
- tool: RunnableLike,
19
- *,
20
- interrupt_config: HumanInterruptConfig | None = None,
21
- review_prompt: Optional[str] = "Please review the tool call",
22
- ) -> BaseTool:
23
- """
24
- Wrap a tool with human-in-the-loop functionality.
25
- This function takes a tool (either a callable or a BaseTool instance) and wraps it
26
- with a human-in-the-loop mechanism. When the tool is invoked, it will first
27
- request human review before executing the tool's logic. The human can choose to
28
- accept, edit the input, or provide a custom response.
29
-
30
- Args:
31
- tool (Callable[..., Any] | BaseTool): _description_
32
- interrupt_config (HumanInterruptConfig | None, optional): _description_. Defaults to None.
33
-
34
- Raises:
35
- ValueError: _description_
36
-
37
- Returns:
38
- BaseTool: _description_
39
- """
40
- if not isinstance(tool, BaseTool):
41
- tool = create_tool(tool)
42
-
43
- if interrupt_config is None:
44
- interrupt_config = {
45
- "allow_accept": True,
46
- "allow_edit": True,
47
- "allow_respond": True,
48
- }
49
-
50
- logger.debug(f"Wrapping tool {tool} with human-in-the-loop functionality")
51
-
52
- @create_tool(tool.name, description=tool.description, args_schema=tool.args_schema)
53
- async def call_tool_with_interrupt(config: RunnableConfig, **tool_input) -> Any:
54
- logger.debug(f"call_tool_with_interrupt: {tool.name} with input: {tool_input}")
55
- request: HumanInterrupt = {
56
- "action_request": {
57
- "action": tool.name,
58
- "args": tool_input,
59
- },
60
- "config": interrupt_config,
61
- "description": review_prompt,
62
- }
63
-
64
- logger.debug(f"Human interrupt request: {request}")
65
- response: dict[str, Any] = interrupt([request])[0]
66
- logger.debug(f"Human interrupt response: {response}")
67
-
68
- if response["type"] == "accept":
69
- tool_response = await tool.ainvoke(tool_input, config=config)
70
- elif response["type"] == "edit":
71
- tool_input = response["args"]["args"]
72
- tool_response = await tool.ainvoke(tool_input, config=config)
73
- elif response["type"] == "response":
74
- user_feedback = response["args"]
75
- tool_response = user_feedback
76
- else:
77
- raise ValueError(f"Unknown interrupt response type: {response['type']}")
78
-
79
- return tool_response
80
-
81
- return call_tool_with_interrupt
82
-
83
-
84
- def as_human_in_the_loop(
85
- tool: RunnableLike, function: BaseFunctionModel | str
86
- ) -> RunnableLike:
87
- if isinstance(function, BaseFunctionModel):
88
- human_in_the_loop: HumanInTheLoopModel | None = function.human_in_the_loop
89
- if human_in_the_loop:
90
- # Get tool name safely - handle RunnableBinding objects
91
- tool_name = getattr(tool, "name", None) or getattr(
92
- getattr(tool, "bound", None), "name", "unknown_tool"
93
- )
94
- logger.debug(f"Adding human-in-the-loop to tool: {tool_name}")
95
- tool = add_human_in_the_loop(
96
- tool=tool,
97
- interrupt_config=human_in_the_loop.interupt_config,
98
- review_prompt=human_in_the_loop.review_prompt,
99
- )
100
- return tool