databao-agent 0.1.4.dev4__tar.gz → 0.1.4.dev8__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 (106) hide show
  1. {databao_agent-0.1.4.dev4 → databao_agent-0.1.4.dev8}/PKG-INFO +14 -11
  2. {databao_agent-0.1.4.dev4 → databao_agent-0.1.4.dev8}/README.md +11 -9
  3. {databao_agent-0.1.4.dev4/databao → databao_agent-0.1.4.dev8/databao/agent}/__init__.py +5 -5
  4. {databao_agent-0.1.4.dev4/databao → databao_agent-0.1.4.dev8/databao/agent}/api.py +15 -10
  5. {databao_agent-0.1.4.dev4/databao → databao_agent-0.1.4.dev8/databao/agent}/caches/disk_cache.py +1 -1
  6. {databao_agent-0.1.4.dev4/databao → databao_agent-0.1.4.dev8/databao/agent}/caches/in_mem_cache.py +1 -1
  7. databao_agent-0.1.4.dev8/databao/agent/configs/__init__.py +3 -0
  8. databao_agent-0.1.4.dev8/databao/agent/core/__init__.py +20 -0
  9. {databao_agent-0.1.4.dev4/databao → databao_agent-0.1.4.dev8/databao/agent}/core/agent.py +11 -21
  10. {databao_agent-0.1.4.dev4/databao → databao_agent-0.1.4.dev8/databao/agent}/core/data_source.py +1 -1
  11. {databao_agent-0.1.4.dev4/databao → databao_agent-0.1.4.dev8/databao/agent}/core/domain.py +21 -10
  12. {databao_agent-0.1.4.dev4/databao → databao_agent-0.1.4.dev8/databao/agent}/core/executor.py +12 -22
  13. {databao_agent-0.1.4.dev4/databao → databao_agent-0.1.4.dev8/databao/agent}/core/sources.py +2 -2
  14. {databao_agent-0.1.4.dev4/databao → databao_agent-0.1.4.dev8/databao/agent}/core/thread.py +8 -9
  15. {databao_agent-0.1.4.dev4/databao → databao_agent-0.1.4.dev8/databao/agent}/core/visualizer.py +1 -1
  16. {databao_agent-0.1.4.dev4/databao → databao_agent-0.1.4.dev8/databao/agent}/databases/__init__.py +2 -2
  17. {databao_agent-0.1.4.dev4/databao → databao_agent-0.1.4.dev8/databao/agent}/databases/bigquery_adapter.py +2 -2
  18. {databao_agent-0.1.4.dev4/databao → databao_agent-0.1.4.dev8/databao/agent}/databases/database_adapter.py +1 -1
  19. {databao_agent-0.1.4.dev4/databao → databao_agent-0.1.4.dev8/databao/agent}/databases/databases.py +8 -8
  20. {databao_agent-0.1.4.dev4/databao → databao_agent-0.1.4.dev8/databao/agent}/databases/duckdb_adapter.py +2 -2
  21. {databao_agent-0.1.4.dev4/databao → databao_agent-0.1.4.dev8/databao/agent}/databases/mysql_adapter.py +3 -3
  22. {databao_agent-0.1.4.dev4/databao → databao_agent-0.1.4.dev8/databao/agent}/databases/postgresql_adapter.py +2 -2
  23. {databao_agent-0.1.4.dev4/databao → databao_agent-0.1.4.dev8/databao/agent}/databases/snowflake_adapter.py +11 -4
  24. {databao_agent-0.1.4.dev4/databao → databao_agent-0.1.4.dev8/databao/agent}/databases/sqlite_adapter.py +2 -2
  25. databao_agent-0.1.4.dev8/databao/agent/dbt/__init__.py +3 -0
  26. {databao_agent-0.1.4.dev4/databao → databao_agent-0.1.4.dev8/databao/agent}/dbt/dbt.py +1 -1
  27. databao_agent-0.1.4.dev8/databao/agent/duckdb/__init__.py +13 -0
  28. {databao_agent-0.1.4.dev4/databao → databao_agent-0.1.4.dev8/databao/agent}/duckdb/react_tools.py +24 -3
  29. databao_agent-0.1.4.dev8/databao/agent/duckdb/schema_inspection.py +133 -0
  30. databao_agent-0.1.4.dev8/databao/agent/executors/__init__.py +6 -0
  31. {databao_agent-0.1.4.dev4/databao → databao_agent-0.1.4.dev8/databao/agent}/executors/base.py +78 -39
  32. databao_agent-0.1.4.dev8/databao/agent/executors/claude_code/claude_model_wrapper.py +313 -0
  33. databao_agent-0.1.4.dev8/databao/agent/executors/claude_code/executor.py +115 -0
  34. databao_agent-0.1.4.dev8/databao/agent/executors/claude_code/system_prompt.jinja +83 -0
  35. databao_agent-0.1.4.dev8/databao/agent/executors/claude_code/utils.py +81 -0
  36. databao_agent-0.1.4.dev8/databao/agent/executors/dbt/__init__.py +25 -0
  37. {databao_agent-0.1.4.dev4/databao → databao_agent-0.1.4.dev8/databao/agent}/executors/dbt/executor.py +21 -30
  38. {databao_agent-0.1.4.dev4/databao → databao_agent-0.1.4.dev8/databao/agent}/executors/dbt/graph.py +9 -9
  39. {databao_agent-0.1.4.dev4/databao → databao_agent-0.1.4.dev8/databao/agent}/executors/frontend/text_frontend.py +23 -3
  40. databao_agent-0.1.4.dev4/databao/executors/tools.py → databao_agent-0.1.4.dev8/databao/agent/executors/langchain_tools.py +18 -9
  41. databao_agent-0.1.4.dev8/databao/agent/executors/lighthouse/executor.py +188 -0
  42. {databao_agent-0.1.4.dev4/databao → databao_agent-0.1.4.dev8/databao/agent}/executors/lighthouse/graph.py +28 -32
  43. {databao_agent-0.1.4.dev4/databao → databao_agent-0.1.4.dev8/databao/agent}/executors/lighthouse/system_prompt.jinja +47 -1
  44. {databao_agent-0.1.4.dev4/databao → databao_agent-0.1.4.dev8/databao/agent}/executors/llm.py +1 -1
  45. {databao_agent-0.1.4.dev4/databao → databao_agent-0.1.4.dev8/databao/agent}/executors/prompt.py +1 -1
  46. {databao_agent-0.1.4.dev4/databao → databao_agent-0.1.4.dev8/databao/agent}/executors/react_duckdb/executor.py +7 -6
  47. databao_agent-0.1.4.dev8/databao/agent/executors/utils.py +69 -0
  48. databao_agent-0.1.4.dev8/databao/agent/integrations/dce/__init__.py +5 -0
  49. {databao_agent-0.1.4.dev4/databao → databao_agent-0.1.4.dev8/databao/agent}/integrations/dce/databao_context.py +2 -2
  50. {databao_agent-0.1.4.dev4/databao → databao_agent-0.1.4.dev8/databao/agent}/integrations/dce/databao_context_engine.py +1 -1
  51. {databao_agent-0.1.4.dev4/databao → databao_agent-0.1.4.dev8/databao/agent}/integrations/dce/databao_context_project_manager.py +1 -1
  52. databao_agent-0.1.4.dev8/databao/agent/mcp/__init__.py +11 -0
  53. {databao_agent-0.1.4.dev4/databao → databao_agent-0.1.4.dev8/databao/agent}/mcp/adapter.py +1 -1
  54. {databao_agent-0.1.4.dev4/databao → databao_agent-0.1.4.dev8/databao/agent}/mcp/manager.py +4 -4
  55. {databao_agent-0.1.4.dev4/databao → databao_agent-0.1.4.dev8/databao/agent}/multimodal/__init__.py +2 -2
  56. {databao_agent-0.1.4.dev4/databao → databao_agent-0.1.4.dev8/databao/agent}/multimodal/html_viewer.py +3 -3
  57. {databao_agent-0.1.4.dev4/databao → databao_agent-0.1.4.dev8/databao/agent}/multimodal/jupyter_widget.py +4 -4
  58. databao_agent-0.1.4.dev8/databao/agent/visualizers/__init__.py +0 -0
  59. {databao_agent-0.1.4.dev4/databao → databao_agent-0.1.4.dev8/databao/agent}/visualizers/dumb.py +1 -1
  60. {databao_agent-0.1.4.dev4/databao → databao_agent-0.1.4.dev8/databao/agent}/visualizers/vega_chat.py +5 -5
  61. {databao_agent-0.1.4.dev4 → databao_agent-0.1.4.dev8}/pyproject.toml +4 -10
  62. databao_agent-0.1.4.dev4/databao/configs/__init__.py +0 -3
  63. databao_agent-0.1.4.dev4/databao/core/__init__.py +0 -20
  64. databao_agent-0.1.4.dev4/databao/dbt/__init__.py +0 -3
  65. databao_agent-0.1.4.dev4/databao/duckdb/__init__.py +0 -9
  66. databao_agent-0.1.4.dev4/databao/duckdb/utils.py +0 -41
  67. databao_agent-0.1.4.dev4/databao/executors/__init__.py +0 -5
  68. databao_agent-0.1.4.dev4/databao/executors/dbt/__init__.py +0 -20
  69. databao_agent-0.1.4.dev4/databao/executors/lighthouse/executor.py +0 -76
  70. databao_agent-0.1.4.dev4/databao/integrations/dce/__init__.py +0 -5
  71. databao_agent-0.1.4.dev4/databao/mcp/__init__.py +0 -11
  72. {databao_agent-0.1.4.dev4 → databao_agent-0.1.4.dev8}/.gitignore +0 -0
  73. {databao_agent-0.1.4.dev4 → databao_agent-0.1.4.dev8}/LICENSE.md +0 -0
  74. {databao_agent-0.1.4.dev4 → databao_agent-0.1.4.dev8}/client/out/multimodal-html/index.html +0 -0
  75. {databao_agent-0.1.4.dev4 → databao_agent-0.1.4.dev8}/client/out/multimodal-jupyter/index.js +0 -0
  76. {databao_agent-0.1.4.dev4 → databao_agent-0.1.4.dev8}/client/out/multimodal-jupyter/style.css +0 -0
  77. {databao_agent-0.1.4.dev4/databao → databao_agent-0.1.4.dev8/databao/agent}/caches/__init__.py +0 -0
  78. {databao_agent-0.1.4.dev4/databao → databao_agent-0.1.4.dev8/databao/agent}/configs/agent.py +0 -0
  79. {databao_agent-0.1.4.dev4/databao → databao_agent-0.1.4.dev8/databao/agent}/configs/llm.py +0 -0
  80. {databao_agent-0.1.4.dev4/databao → databao_agent-0.1.4.dev8/databao/agent}/core/cache.py +0 -0
  81. {databao_agent-0.1.4.dev4/databao → databao_agent-0.1.4.dev8/databao/agent}/core/env.py +0 -0
  82. {databao_agent-0.1.4.dev4/databao → databao_agent-0.1.4.dev8/databao/agent}/core/opa.py +0 -0
  83. {databao_agent-0.1.4.dev4/databao → databao_agent-0.1.4.dev8/databao/agent}/databases/database_connection.py +0 -0
  84. {databao_agent-0.1.4.dev4/databao → databao_agent-0.1.4.dev8/databao/agent}/databases/utils.py +0 -0
  85. {databao_agent-0.1.4.dev4/databao → databao_agent-0.1.4.dev8/databao/agent}/duckdb/types.py +0 -0
  86. {databao_agent-0.1.4.dev4/databao/executors/frontend → databao_agent-0.1.4.dev8/databao/agent/executors/claude_code}/__init__.py +0 -0
  87. {databao_agent-0.1.4.dev4/databao → databao_agent-0.1.4.dev8/databao/agent}/executors/dbt/config.py +0 -0
  88. {databao_agent-0.1.4.dev4/databao → databao_agent-0.1.4.dev8/databao/agent}/executors/dbt/dbt_runner.py +0 -0
  89. {databao_agent-0.1.4.dev4/databao → databao_agent-0.1.4.dev8/databao/agent}/executors/dbt/errors.py +0 -0
  90. {databao_agent-0.1.4.dev4/databao → databao_agent-0.1.4.dev8/databao/agent}/executors/dbt/query_runner.py +0 -0
  91. {databao_agent-0.1.4.dev4/databao → databao_agent-0.1.4.dev8/databao/agent}/executors/dbt/system_prompt.jinja +0 -0
  92. {databao_agent-0.1.4.dev4/databao → databao_agent-0.1.4.dev8/databao/agent}/executors/dbt/task_instruction.jinja +0 -0
  93. {databao_agent-0.1.4.dev4/databao/executors/react_duckdb → databao_agent-0.1.4.dev8/databao/agent/executors/frontend}/__init__.py +0 -0
  94. {databao_agent-0.1.4.dev4/databao → databao_agent-0.1.4.dev8/databao/agent}/executors/frontend/messages.py +0 -0
  95. {databao_agent-0.1.4.dev4/databao → databao_agent-0.1.4.dev8/databao/agent}/executors/history_cleaning.py +0 -0
  96. {databao_agent-0.1.4.dev4/databao → databao_agent-0.1.4.dev8/databao/agent}/executors/lighthouse/__init__.py +0 -0
  97. {databao_agent-0.1.4.dev4/databao → databao_agent-0.1.4.dev8/databao/agent}/executors/query_expansion.py +0 -0
  98. {databao_agent-0.1.4.dev4/databao/integrations → databao_agent-0.1.4.dev8/databao/agent/executors/react_duckdb}/__init__.py +0 -0
  99. {databao_agent-0.1.4.dev4/databao/visualizers → databao_agent-0.1.4.dev8/databao/agent/integrations}/__init__.py +0 -0
  100. {databao_agent-0.1.4.dev4/databao → databao_agent-0.1.4.dev8/databao/agent}/mcp/config.py +0 -0
  101. {databao_agent-0.1.4.dev4/databao → databao_agent-0.1.4.dev8/databao/agent}/mcp/connection.py +0 -0
  102. {databao_agent-0.1.4.dev4/databao → databao_agent-0.1.4.dev8/databao/agent}/mcp/oauth.py +0 -0
  103. {databao_agent-0.1.4.dev4/databao → databao_agent-0.1.4.dev8/databao/agent}/multimodal/utils.py +0 -0
  104. {databao_agent-0.1.4.dev4/databao → databao_agent-0.1.4.dev8/databao/agent}/py.typed +0 -0
  105. {databao_agent-0.1.4.dev4/databao → databao_agent-0.1.4.dev8/databao/agent}/visualizers/vega_vis_tool.py +0 -0
  106. {databao_agent-0.1.4.dev4 → databao_agent-0.1.4.dev8}/hatch_build.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: databao-agent
3
- Version: 0.1.4.dev4
3
+ Version: 0.1.4.dev8
4
4
  Summary: databao-agent: NL queries for data
5
5
  Project-URL: Homepage, https://databao.app/
6
6
  Project-URL: Source, https://github.com/JetBrains/databao-agent
@@ -9,7 +9,8 @@ License-File: LICENSE.md
9
9
  Classifier: Operating System :: OS Independent
10
10
  Classifier: Programming Language :: Python :: 3
11
11
  Requires-Python: <3.15,>=3.11
12
- Requires-Dist: databao-context-engine[mysql,postgresql,snowflake]~=0.5.0
12
+ Requires-Dist: claude-agent-sdk>=0.1.48
13
+ Requires-Dist: databao-context-engine[mysql,postgresql,snowflake]~=0.6.0
13
14
  Requires-Dist: dbt-core~=1.9.0
14
15
  Requires-Dist: dbt-duckdb>=1.10.0
15
16
  Requires-Dist: diskcache>=5.6.3
@@ -137,19 +138,21 @@ engine = create_engine(
137
138
  ### 2. Create a Databao agent and register sources
138
139
 
139
140
  ```python
140
- import databao
141
- from databao import LLMConfig
141
+ import databao.agent as bao
142
142
 
143
143
  # Option A - Local: install and run any compatible local LLM
144
144
  # For list of compatible models, see "Local Models" below
145
- # llm_config = LLMConfig(name="ollama:gpt-oss:20b", temperature=0)
145
+ # llm_config = bao.LLMConfig(name="ollama:gpt-oss:20b", temperature=0)
146
146
 
147
147
  # Option B - Cloud (requires an API key, e.g. OPENAI_API_KEY)
148
- llm_config = LLMConfig(name="gpt-4o-mini", temperature=0)
149
- agent = databao.new_agent(name="demo", llm_config=llm_config)
148
+ llm_config = bao.LLMConfig(name="gpt-4o-mini", temperature=0)
150
149
 
151
150
  # Add your database to the agent
152
- agent.add_db(engine)
151
+ domain = bao.domain()
152
+ domain.add_db(engine)
153
+
154
+ agent = bao.agent(domain, name="demo", llm_config=llm_config)
155
+
153
156
  ```
154
157
 
155
158
  ### 3. Ask questions and materialize results
@@ -201,17 +204,17 @@ Databao agent works great with local LLMs — your data never leaves your machin
201
204
  ### Ollama
202
205
 
203
206
  1. Install [Ollama](https://ollama.com/download) for your OS and make sure it’s running
204
- 2. Use an `LLMConfig` with `name` of the form `"ollama:<model_name>"`:
207
+ 2. Use a `bao.LLMConfig` with `name` of the form `"ollama:<model_name>"`:
205
208
 
206
209
  ```python
207
- llm_config = LLMConfig(name="ollama:gpt-oss:20b", temperature=0)
210
+ llm_config = bao.LLMConfig(name="ollama:gpt-oss:20b", temperature=0)
208
211
  ```
209
212
 
210
213
  The model will be downloaded automatically if it doesn't exist. Or run `ollama pull <model_name>` to download manually.
211
214
 
212
215
  ### OpenAI-compatible servers
213
216
 
214
- You can use any OpenAI-compatible server by setting `api_base_url` in the `LLMConfig`.
217
+ You can use any OpenAI-compatible server by setting `api_base_url` in the `bao.LLMConfig`.
215
218
 
216
219
  For an example, see `examples/configs/qwen3-8b-oai.yaml`.
217
220
 
@@ -93,19 +93,21 @@ engine = create_engine(
93
93
  ### 2. Create a Databao agent and register sources
94
94
 
95
95
  ```python
96
- import databao
97
- from databao import LLMConfig
96
+ import databao.agent as bao
98
97
 
99
98
  # Option A - Local: install and run any compatible local LLM
100
99
  # For list of compatible models, see "Local Models" below
101
- # llm_config = LLMConfig(name="ollama:gpt-oss:20b", temperature=0)
100
+ # llm_config = bao.LLMConfig(name="ollama:gpt-oss:20b", temperature=0)
102
101
 
103
102
  # Option B - Cloud (requires an API key, e.g. OPENAI_API_KEY)
104
- llm_config = LLMConfig(name="gpt-4o-mini", temperature=0)
105
- agent = databao.new_agent(name="demo", llm_config=llm_config)
103
+ llm_config = bao.LLMConfig(name="gpt-4o-mini", temperature=0)
106
104
 
107
105
  # Add your database to the agent
108
- agent.add_db(engine)
106
+ domain = bao.domain()
107
+ domain.add_db(engine)
108
+
109
+ agent = bao.agent(domain, name="demo", llm_config=llm_config)
110
+
109
111
  ```
110
112
 
111
113
  ### 3. Ask questions and materialize results
@@ -157,17 +159,17 @@ Databao agent works great with local LLMs — your data never leaves your machin
157
159
  ### Ollama
158
160
 
159
161
  1. Install [Ollama](https://ollama.com/download) for your OS and make sure it’s running
160
- 2. Use an `LLMConfig` with `name` of the form `"ollama:<model_name>"`:
162
+ 2. Use a `bao.LLMConfig` with `name` of the form `"ollama:<model_name>"`:
161
163
 
162
164
  ```python
163
- llm_config = LLMConfig(name="ollama:gpt-oss:20b", temperature=0)
165
+ llm_config = bao.LLMConfig(name="ollama:gpt-oss:20b", temperature=0)
164
166
  ```
165
167
 
166
168
  The model will be downloaded automatically if it doesn't exist. Or run `ollama pull <model_name>` to download manually.
167
169
 
168
170
  ### OpenAI-compatible servers
169
171
 
170
- You can use any OpenAI-compatible server by setting `api_base_url` in the `LLMConfig`.
172
+ You can use any OpenAI-compatible server by setting `api_base_url` in the `bao.LLMConfig`.
171
173
 
172
174
  For an example, see `examples/configs/qwen3-8b-oai.yaml`.
173
175
 
@@ -1,14 +1,14 @@
1
1
  import importlib.metadata
2
2
 
3
3
  try:
4
- __version__ = importlib.metadata.version(__name__)
4
+ __version__ = importlib.metadata.version("databao-agent")
5
5
  except importlib.metadata.PackageNotFoundError:
6
6
  __version__ = "0.0.0" # Fallback for development mode
7
7
 
8
8
 
9
- from databao.api import agent, domain
10
- from databao.configs.llm import LLMConfig
11
- from databao.core import (
9
+ from databao.agent.api import agent, domain
10
+ from databao.agent.configs.llm import LLMConfig
11
+ from databao.agent.core import (
12
12
  Agent,
13
13
  Domain,
14
14
  ExecutionResult,
@@ -18,7 +18,7 @@ from databao.core import (
18
18
  VisualisationResult,
19
19
  Visualizer,
20
20
  )
21
- from databao.databases import DBConnection, DBConnectionConfig, DBConnectionRuntime
21
+ from databao.agent.databases import DBConnection, DBConnectionConfig, DBConnectionRuntime
22
22
 
23
23
  __all__ = [
24
24
  "Agent",
@@ -3,16 +3,19 @@ from typing import TextIO
3
3
 
4
4
  from typing_extensions import deprecated
5
5
 
6
- from databao.caches.in_mem_cache import InMemCache
7
- from databao.configs.agent import DEFAULT_AGENT_CONFIG, AgentConfig
8
- from databao.configs.llm import LLMConfig, LLMConfigDirectory
9
- from databao.core import Agent, Cache, Executor, Visualizer
10
- from databao.core.domain import Domain, _DCEProjectDomain, _InMemoryDomain
11
- from databao.executors import ReactDuckDBExecutor
12
- from databao.executors.dbt.config import DbtConfig
13
- from databao.executors.dbt.executor import DbtProjectExecutor
14
- from databao.executors.lighthouse.executor import LighthouseExecutor
15
- from databao.visualizers.vega_chat import VegaChatVisualizer
6
+ from databao.agent.caches.in_mem_cache import InMemCache
7
+ from databao.agent.configs.agent import DEFAULT_AGENT_CONFIG, AgentConfig
8
+ from databao.agent.configs.llm import LLMConfig, LLMConfigDirectory
9
+ from databao.agent.core import Agent, Cache, Executor, Visualizer
10
+ from databao.agent.core.domain import Domain, _DCEProjectDomain, _InMemoryDomain
11
+ from databao.agent.executors import (
12
+ ClaudeCodeExecutor,
13
+ DbtProjectExecutor,
14
+ LighthouseExecutor,
15
+ ReactDuckDBExecutor,
16
+ )
17
+ from databao.agent.executors.dbt.config import DbtConfig
18
+ from databao.agent.visualizers.vega_chat import VegaChatVisualizer
16
19
 
17
20
 
18
21
  def agent(
@@ -49,6 +52,8 @@ def agent(
49
52
  data_executor = DbtProjectExecutor(dbt_config=dbt_config, writer=writer)
50
53
  case "react_duckdb":
51
54
  data_executor = ReactDuckDBExecutor(writer=writer)
55
+ case "claude":
56
+ data_executor = ClaudeCodeExecutor(writer=writer)
52
57
  case _:
53
58
  raise ValueError(f"Invalid executor type: {executor_type}")
54
59
 
@@ -6,7 +6,7 @@ from typing import Any
6
6
 
7
7
  import diskcache # type: ignore[import-untyped]
8
8
 
9
- from databao.core import Cache
9
+ from databao.agent.core import Cache
10
10
 
11
11
 
12
12
  @dataclass(kw_only=True)
@@ -1,6 +1,6 @@
1
1
  from typing import Any
2
2
 
3
- from databao.core.cache import Cache
3
+ from databao.agent.core.cache import Cache
4
4
 
5
5
 
6
6
  class InMemCache(Cache):
@@ -0,0 +1,3 @@
1
+ from databao.agent.configs.llm import LLMConfig, LLMConfigDirectory
2
+
3
+ __all__ = ["LLMConfig", "LLMConfigDirectory"]
@@ -0,0 +1,20 @@
1
+ from databao.agent.core.agent import Agent
2
+ from databao.agent.core.cache import Cache
3
+ from databao.agent.core.domain import Domain
4
+ from databao.agent.core.executor import ExecutionResult, Executor
5
+ from databao.agent.core.opa import Opa
6
+ from databao.agent.core.thread import Thread
7
+ from databao.agent.core.visualizer import HistoryMode, VisualisationResult, Visualizer
8
+
9
+ __all__ = [
10
+ "Agent",
11
+ "Cache",
12
+ "Domain",
13
+ "ExecutionResult",
14
+ "Executor",
15
+ "HistoryMode",
16
+ "Opa",
17
+ "Thread",
18
+ "VisualisationResult",
19
+ "Visualizer",
20
+ ]
@@ -7,18 +7,18 @@ from langchain_core.language_models.chat_models import BaseChatModel
7
7
  from pandas import DataFrame
8
8
  from typing_extensions import deprecated
9
9
 
10
- from databao.core.data_source import DBDataSource, DFDataSource, Sources
11
- from databao.core.domain import Domain, _Domain
12
- from databao.core.thread import Thread
13
- from databao.databases import DBConnection
14
- from databao.mcp.manager import McpManager
10
+ from databao.agent.core.data_source import DBDataSource, DFDataSource, Sources
11
+ from databao.agent.core.domain import Domain, _Domain
12
+ from databao.agent.core.thread import Thread
13
+ from databao.agent.databases import DBConnection
14
+ from databao.agent.mcp.manager import McpManager
15
15
 
16
16
  if TYPE_CHECKING:
17
- from databao.configs.agent import AgentConfig
18
- from databao.configs.llm import LLMConfig
19
- from databao.core.cache import Cache
20
- from databao.core.executor import Executor
21
- from databao.core.visualizer import Visualizer
17
+ from databao.agent.configs.agent import AgentConfig
18
+ from databao.agent.configs.llm import LLMConfig
19
+ from databao.agent.core.cache import Cache
20
+ from databao.agent.core.executor import Executor
21
+ from databao.agent.core.visualizer import Visualizer
22
22
 
23
23
  logger = logging.getLogger(__name__)
24
24
 
@@ -55,7 +55,7 @@ class Agent:
55
55
  self.__llm_config = llm
56
56
  self.__agent_config = agent_config
57
57
 
58
- self.__executor = data_executor
58
+ self.__executor: Executor = data_executor
59
59
  self.__visualizer = visualizer
60
60
  self.__cache = cache
61
61
  self.__mcp: McpManager = McpManager()
@@ -67,16 +67,6 @@ class Agent:
67
67
  self.__stream_ask = stream_ask
68
68
  self.__stream_plot = stream_plot
69
69
 
70
- self._init_executor()
71
-
72
- def _init_executor(self) -> None:
73
- for db_source in self.sources.dbs.values():
74
- self.executor.register_db(db_source)
75
- for df_source in self.sources.dfs.values():
76
- self.executor.register_df(df_source)
77
- for dbt_source in self.sources.dbts.values():
78
- self.executor.register_dbt(dbt_source)
79
-
80
70
  @deprecated("Use Domain.add_db() and initialize Agent with Domain instead.")
81
71
  def add_db(self, conn: DBConnection, *, name: str | None = None, context: str | Path | None = None) -> None:
82
72
  raise NotImplementedError(
@@ -3,7 +3,7 @@ from pathlib import Path
3
3
 
4
4
  import pandas as pd
5
5
 
6
- from databao.databases import DBConnectionConfig
6
+ from databao.agent.databases import DBConnectionConfig
7
7
 
8
8
 
9
9
  @dataclass
@@ -1,5 +1,6 @@
1
1
  from __future__ import annotations
2
2
 
3
+ import re
3
4
  from abc import ABC
4
5
  from pathlib import Path
5
6
  from typing import Any, Protocol
@@ -13,9 +14,9 @@ from databao_context_engine import (
13
14
  )
14
15
  from pandas import DataFrame
15
16
 
16
- from databao.core.data_source import DataSource, DBDataSource, DBTDataSource, DFDataSource, Sources
17
- from databao.core.sources import SourcesManager
18
- from databao.databases import (
17
+ from databao.agent.core.data_source import DataSource, DBDataSource, DBTDataSource, DFDataSource, Sources
18
+ from databao.agent.core.sources import SourcesManager
19
+ from databao.agent.databases import (
19
20
  DBConnection,
20
21
  DBConnectionConfig,
21
22
  DBConnectionRuntime,
@@ -23,8 +24,19 @@ from databao.databases import (
23
24
  create_db_config_from_runtime,
24
25
  try_create_db_config_from_content,
25
26
  )
26
- from databao.dbt import create_dbt_config_file, try_extract_dbt_dir_from_content
27
- from databao.integrations.dce import DatabaoContextApi
27
+ from databao.agent.dbt import create_dbt_config_file, try_extract_dbt_dir_from_content
28
+ from databao.agent.integrations.dce import DatabaoContextApi
29
+
30
+ _SOURCE_NAME_PATTERN = re.compile(r"^[A-Za-z][A-Za-z0-9_]*$")
31
+
32
+
33
+ def _verify_source_name(name: str | None) -> None:
34
+ if name is not None and re.match(_SOURCE_NAME_PATTERN, name) is None:
35
+ # The provided source name should be simple enough for LLMs to use it.
36
+ # Otherwise, the agent would always have to correctly quote the provided name in SQL queries.
37
+ raise ValueError(
38
+ f"Invalid database name: '{name}'. The provided source name must match {_SOURCE_NAME_PATTERN.pattern}"
39
+ )
28
40
 
29
41
 
30
42
  class Domain(Protocol):
@@ -137,6 +149,7 @@ class _Domain(ABC, Domain):
137
149
  def _add_db(
138
150
  self, db: DBConnection, name: str | None = None, description: str | Path | None = None
139
151
  ) -> DBDataSource | None:
152
+ _verify_source_name(name)
140
153
  if isinstance(db, DBConnectionConfig):
141
154
  db_config = db
142
155
  elif isinstance(db, DBConnectionRuntime):
@@ -148,11 +161,13 @@ class _Domain(ABC, Domain):
148
161
  def _add_df(
149
162
  self, df: DataFrame, name: str | None = None, description: str | Path | None = None
150
163
  ) -> DFDataSource | None:
164
+ _verify_source_name(name)
151
165
  return self._sources_manager.add_df(df, name=name, description=description)
152
166
 
153
167
  def _add_dbt(
154
168
  self, dbt: str | Path, name: str | None = None, description: str | Path | None = None
155
169
  ) -> DBTDataSource | None:
170
+ _verify_source_name(name)
156
171
  if isinstance(dbt, str):
157
172
  dbt = Path(dbt)
158
173
  return self._sources_manager.add_dbt(dbt, name=name, description=description)
@@ -214,11 +229,7 @@ class _DCEProjectDomain(_Domain):
214
229
  return self._dce.search_context(retrieve_text, datasource_ids=datasource_ids)
215
230
 
216
231
  def is_context_built(self) -> bool:
217
- if self._dce.is_context_built():
218
- return True
219
- # NOTE: (@gas) dbt datasources are configured in DCE but may not appear in the
220
- # introspected list; treat them as "built" when present.
221
- return len(self._configured) > 0
232
+ return self._dce.is_context_built()
222
233
 
223
234
  @property
224
235
  def supports_context(self) -> bool:
@@ -1,20 +1,22 @@
1
1
  import base64
2
+ import logging
2
3
  import re
3
4
  from abc import ABC, abstractmethod
4
5
  from typing import TYPE_CHECKING, Any, ClassVar, Literal, TextIO
5
6
 
6
- from langchain_core.tools import BaseTool
7
7
  from pandas import DataFrame
8
8
  from pydantic import BaseModel, ConfigDict
9
9
 
10
- from databao.core.data_source import DBDataSource, DBTDataSource, DFDataSource
11
- from databao.core.domain import Domain
10
+ from databao.agent.core.domain import Domain
12
11
 
13
12
  if TYPE_CHECKING:
14
- from databao import LLMConfig
15
- from databao.configs.agent import AgentConfig
16
- from databao.core.cache import Cache
17
- from databao.core.opa import Opa
13
+ from databao.agent import LLMConfig
14
+ from databao.agent.configs.agent import AgentConfig
15
+ from databao.agent.core.cache import Cache
16
+ from databao.agent.core.opa import Opa
17
+
18
+
19
+ logger = logging.getLogger(__name__)
18
20
 
19
21
 
20
22
  class OutputModalityHints(BaseModel):
@@ -146,20 +148,8 @@ class Executor(ABC):
146
148
  """
147
149
 
148
150
  @abstractmethod
149
- def register_db(self, source: DBDataSource) -> None:
150
- pass
151
-
152
- @abstractmethod
153
- def register_df(self, source: DFDataSource) -> None:
154
- pass
155
-
156
- @abstractmethod
157
- def register_dbt(self, source: DBTDataSource) -> None:
158
- pass
159
-
160
- @abstractmethod
161
- def register_tools(self, tools: list[BaseTool]) -> None:
162
- """Register additional LangChain tools to be available during execution."""
151
+ def register_tools(self, tools: list[Any]) -> None:
152
+ """Register additional tools to be available during execution."""
163
153
 
164
154
  @abstractmethod
165
155
  def drop_last_opa_group(self, cache: "Cache", n: int = 1) -> None:
@@ -196,7 +186,7 @@ class Executor(ABC):
196
186
  @staticmethod
197
187
  def prepare_for_execution(domain: "Domain") -> None:
198
188
  if domain.supports_context and not domain.is_context_built():
199
- print(
189
+ logger.warning(
200
190
  "Context has not been built yet. Building it now — this may take a while. "
201
191
  "To avoid this delay, call domain.build_context() before starting execution."
202
192
  )
@@ -2,8 +2,8 @@ from pathlib import Path
2
2
 
3
3
  from pandas import DataFrame
4
4
 
5
- from databao.core.data_source import DBDataSource, DBTDataSource, DFDataSource, Sources
6
- from databao.databases import DBConnectionConfig
5
+ from databao.agent.core.data_source import DBDataSource, DBTDataSource, DFDataSource, Sources
6
+ from databao.agent.databases import DBConnectionConfig
7
7
 
8
8
 
9
9
  class SourcesManager:
@@ -4,15 +4,14 @@ from typing import TYPE_CHECKING, Any, Self, TextIO
4
4
 
5
5
  from pandas import DataFrame
6
6
 
7
- from databao.core.env import in_jupyter_kernel
8
- from databao.core.executor import ExecutionResult, OutputModalityHints
9
- from databao.core.opa import Opa
10
- from databao.core.visualizer import VisualisationResult
7
+ from databao.agent.core.env import in_jupyter_kernel
8
+ from databao.agent.core.executor import ExecutionResult, OutputModalityHints
9
+ from databao.agent.core.opa import Opa
10
+ from databao.agent.core.visualizer import VisualisationResult
11
11
 
12
12
  if TYPE_CHECKING:
13
- from databao.core.agent import Agent
14
- from databao.core.visualizer import VisualisationResult
15
- from databao.multimodal.jupyter_widget import MultimodalWidget
13
+ from databao.agent.core.agent import Agent
14
+ from databao.agent.multimodal.jupyter_widget import MultimodalWidget
16
15
 
17
16
 
18
17
  class Thread:
@@ -198,11 +197,11 @@ class Thread:
198
197
  ValueError: If visualization generation fails.
199
198
  """
200
199
  if in_jupyter_kernel():
201
- from databao.multimodal import create_jupyter_widget
200
+ from databao.agent.multimodal import create_jupyter_widget
202
201
 
203
202
  return create_jupyter_widget(self)
204
203
 
205
- from databao.multimodal import open_html_content
204
+ from databao.agent.multimodal import open_html_content
206
205
 
207
206
  return open_html_content(self)
208
207
 
@@ -5,7 +5,7 @@ from typing import Any, ClassVar, Literal
5
5
 
6
6
  from pydantic import BaseModel, ConfigDict, Field
7
7
 
8
- from databao.core.executor import ExecutionResult
8
+ from databao.agent.core.executor import ExecutionResult
9
9
 
10
10
  _logger = logging.getLogger(__name__)
11
11
 
@@ -7,8 +7,8 @@ from databao_context_engine import (
7
7
  )
8
8
  from databao_context_engine.plugins.databases.bigquery.config_file import BigQueryConnectionProperties
9
9
 
10
- from databao.databases.database_connection import DBConnection, DBConnectionConfig, DBConnectionRuntime
11
- from databao.databases.databases import (
10
+ from databao.agent.databases.database_connection import DBConnection, DBConnectionConfig, DBConnectionRuntime
11
+ from databao.agent.databases.databases import (
12
12
  create_db_config_file,
13
13
  create_db_config_from_runtime,
14
14
  register_db_in_duckdb,
@@ -12,8 +12,8 @@ from databao_context_engine.plugins.databases.bigquery.config_file import (
12
12
  )
13
13
  from sqlalchemy import Connection, Engine, make_url
14
14
 
15
- from databao.databases.database_adapter import DatabaseAdapter
16
- from databao.databases.database_connection import DBConnection, DBConnectionConfig, DBConnectionRuntime
15
+ from databao.agent.databases.database_adapter import DatabaseAdapter
16
+ from databao.agent.databases.database_connection import DBConnection, DBConnectionConfig, DBConnectionRuntime
17
17
 
18
18
  PROJECT_KEY = "project"
19
19
  DATASET_KEY = "dataset"
@@ -5,7 +5,7 @@ from _duckdb import DuckDBPyConnection
5
5
  from databao_context_engine import DatasourceType
6
6
  from databao_context_engine.pluginlib.build_plugin import AbstractConfigFile
7
7
 
8
- from databao.databases.database_connection import (
8
+ from databao.agent.databases.database_connection import (
9
9
  DBConnection,
10
10
  DBConnectionConfig,
11
11
  DBConnectionRuntime,
@@ -3,17 +3,17 @@ from typing import Any
3
3
  from _duckdb import DuckDBPyConnection
4
4
  from databao_context_engine.pluginlib.build_plugin import AbstractConfigFile, DatasourceType
5
5
 
6
- from databao.databases.bigquery_adapter import BigQueryAdapter
7
- from databao.databases.database_adapter import DatabaseAdapter
8
- from databao.databases.database_connection import (
6
+ from databao.agent.databases.bigquery_adapter import BigQueryAdapter
7
+ from databao.agent.databases.database_adapter import DatabaseAdapter
8
+ from databao.agent.databases.database_connection import (
9
9
  DBConnectionConfig,
10
10
  DBConnectionRuntime,
11
11
  )
12
- from databao.databases.duckdb_adapter import DuckDBAdapter
13
- from databao.databases.mysql_adapter import MySQLAdapter
14
- from databao.databases.postgresql_adapter import PostgreSQLAdapter
15
- from databao.databases.snowflake_adapter import SnowflakeAdapter
16
- from databao.databases.sqlite_adapter import SQLiteAdapter
12
+ from databao.agent.databases.duckdb_adapter import DuckDBAdapter
13
+ from databao.agent.databases.mysql_adapter import MySQLAdapter
14
+ from databao.agent.databases.postgresql_adapter import PostgreSQLAdapter
15
+ from databao.agent.databases.snowflake_adapter import SnowflakeAdapter
16
+ from databao.agent.databases.sqlite_adapter import SQLiteAdapter
17
17
 
18
18
  DATABASE_ADAPTERS: list[DatabaseAdapter] = [
19
19
  BigQueryAdapter(),
@@ -4,8 +4,8 @@ from _duckdb import DuckDBPyConnection
4
4
  from databao_context_engine import DatasourceType, DuckDBConfigFile, DuckDBConnectionConfig
5
5
  from databao_context_engine.pluginlib.build_plugin import AbstractConfigFile
6
6
 
7
- from databao.databases.database_adapter import DatabaseAdapter
8
- from databao.databases.database_connection import DBConnection, DBConnectionConfig, DBConnectionRuntime
7
+ from databao.agent.databases.database_adapter import DatabaseAdapter
8
+ from databao.agent.databases.database_connection import DBConnection, DBConnectionConfig, DBConnectionRuntime
9
9
 
10
10
 
11
11
  class DuckDBAdapter(DatabaseAdapter):
@@ -5,9 +5,9 @@ from databao_context_engine import DatasourceType, MySQLConfigFile, MySQLConnect
5
5
  from databao_context_engine.pluginlib.build_plugin import AbstractConfigFile
6
6
  from sqlalchemy import URL, Connection, Engine, make_url
7
7
 
8
- from databao.databases.database_adapter import DatabaseAdapter
9
- from databao.databases.database_connection import DBConnection, DBConnectionConfig, DBConnectionRuntime
10
- from databao.databases.utils import str_dict
8
+ from databao.agent.databases.database_adapter import DatabaseAdapter
9
+ from databao.agent.databases.database_connection import DBConnection, DBConnectionConfig, DBConnectionRuntime
10
+ from databao.agent.databases.utils import str_dict
11
11
 
12
12
  USER_KEY = "user"
13
13
  PASSWORD_KEY = "password"
@@ -5,8 +5,8 @@ from databao_context_engine import DatasourceType, PostgresConfigFile, PostgresC
5
5
  from databao_context_engine.pluginlib.build_plugin import AbstractConfigFile
6
6
  from sqlalchemy import URL, Connection, Engine, make_url
7
7
 
8
- from databao.databases.database_adapter import DatabaseAdapter
9
- from databao.databases.database_connection import DBConnection, DBConnectionConfig, DBConnectionRuntime
8
+ from databao.agent.databases.database_adapter import DatabaseAdapter
9
+ from databao.agent.databases.database_connection import DBConnection, DBConnectionConfig, DBConnectionRuntime
10
10
 
11
11
  USER_KEY = "user"
12
12
  PASSWORD_KEY = "password"
@@ -11,10 +11,11 @@ from databao_context_engine import (
11
11
  SnowflakeSSOAuth,
12
12
  )
13
13
  from databao_context_engine.pluginlib.build_plugin import AbstractConfigFile
14
+ from snowflake.connector.network import SNOWFLAKE_HOST_SUFFIX
14
15
  from sqlalchemy import Connection, Engine, make_url
15
16
 
16
- from databao.databases.database_adapter import DatabaseAdapter
17
- from databao.databases.database_connection import DBConnection, DBConnectionConfig, DBConnectionRuntime
17
+ from databao.agent.databases.database_adapter import DatabaseAdapter
18
+ from databao.agent.databases.database_connection import DBConnection, DBConnectionConfig, DBConnectionRuntime
18
19
 
19
20
  WAREHOUSE_KEY = "warehouse"
20
21
  ACCOUNT_KEY = "account"
@@ -92,8 +93,13 @@ class SnowflakeAdapter(DatabaseAdapter):
92
93
  if "dbname" in content:
93
94
  content[DATABASE_KEY] = content.pop("dbname")
94
95
 
96
+ host: str | None = content.pop("host", None)
97
+ account: str = content.get(ACCOUNT_KEY, "")
98
+ if host and host.endswith(SNOWFLAKE_HOST_SUFFIX):
99
+ account = host[: -len(SNOWFLAKE_HOST_SUFFIX)]
100
+
95
101
  return SnowflakeConnectionProperties(
96
- account=content.get(ACCOUNT_KEY),
102
+ account=account,
97
103
  warehouse=content.get(WAREHOUSE_KEY),
98
104
  database=content.get(DATABASE_KEY),
99
105
  user=content.get(USER_KEY),
@@ -127,8 +133,9 @@ class SnowflakeAdapter(DatabaseAdapter):
127
133
  def _create_secret_sql(config: SnowflakeConnectionProperties, name: str) -> str:
128
134
  params: dict[str, str] = {
129
135
  ACCOUNT_KEY: config.account,
130
- USER_KEY: config.user,
131
136
  }
137
+ if config.user:
138
+ params[USER_KEY] = config.user
132
139
  if config.database:
133
140
  params[DATABASE_KEY] = config.database
134
141
  if config.warehouse:
@@ -5,8 +5,8 @@ from databao_context_engine import DatasourceType, SQLiteConfigFile, SQLiteConne
5
5
  from databao_context_engine.pluginlib.build_plugin import AbstractConfigFile
6
6
  from sqlalchemy import Connection, Engine, make_url
7
7
 
8
- from databao.databases.database_adapter import DatabaseAdapter
9
- from databao.databases.database_connection import DBConnection, DBConnectionConfig, DBConnectionRuntime
8
+ from databao.agent.databases.database_adapter import DatabaseAdapter
9
+ from databao.agent.databases.database_connection import DBConnection, DBConnectionConfig, DBConnectionRuntime
10
10
 
11
11
 
12
12
  class SQLiteAdapter(DatabaseAdapter):
@@ -0,0 +1,3 @@
1
+ from databao.agent.dbt.dbt import create_dbt_config_file, try_extract_dbt_dir_from_content
2
+
3
+ __all__ = ["create_dbt_config_file", "try_extract_dbt_dir_from_content"]