tabletalk 0.2.0__tar.gz → 0.4.0__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 (175) hide show
  1. tabletalk-0.4.0/.github/workflows/db_provider_tests.yml +84 -0
  2. tabletalk-0.4.0/.github/workflows/publish.yml +92 -0
  3. {tabletalk-0.2.0 → tabletalk-0.4.0}/.gitignore +17 -0
  4. tabletalk-0.4.0/PKG-INFO +272 -0
  5. tabletalk-0.4.0/README.md +242 -0
  6. {tabletalk-0.2.0 → tabletalk-0.4.0}/docs/Makefile +1 -1
  7. tabletalk-0.4.0/docs/api-reference.md +621 -0
  8. tabletalk-0.4.0/docs/architecture.md +41 -0
  9. tabletalk-0.4.0/docs/commands.md +75 -0
  10. tabletalk-0.4.0/docs/concepts.md +45 -0
  11. tabletalk-0.4.0/docs/conf.py +48 -0
  12. tabletalk-0.4.0/docs/configuration.md +71 -0
  13. tabletalk-0.4.0/docs/contexts.md +35 -0
  14. tabletalk-0.4.0/docs/contributing.md +182 -0
  15. tabletalk-0.4.0/docs/databases.md +38 -0
  16. tabletalk-0.4.0/docs/dbt-integration.md +21 -0
  17. tabletalk-0.4.0/docs/evals.md +64 -0
  18. tabletalk-0.4.0/docs/getting-started.md +46 -0
  19. tabletalk-0.4.0/docs/index.md +53 -0
  20. tabletalk-0.4.0/docs/llm-providers.md +203 -0
  21. tabletalk-0.4.0/docs/profiles.md +20 -0
  22. tabletalk-0.4.0/docs/refactor/current-state-audit.md +109 -0
  23. tabletalk-0.4.0/docs/refactor/deletion-plan.md +25 -0
  24. tabletalk-0.4.0/docs/refactor/evaluation-strategy.md +24 -0
  25. tabletalk-0.4.0/docs/refactor/licensing-audit.md +45 -0
  26. tabletalk-0.4.0/docs/refactor/market-positioning.md +42 -0
  27. tabletalk-0.4.0/docs/refactor/migration-plan.md +27 -0
  28. tabletalk-0.4.0/docs/refactor/product-thesis.md +65 -0
  29. tabletalk-0.4.0/docs/refactor/progress-audit.md +47 -0
  30. tabletalk-0.4.0/docs/refactor/reliability-model.md +40 -0
  31. tabletalk-0.4.0/docs/refactor/target-architecture.md +52 -0
  32. tabletalk-0.4.0/docs/refactor/user-journey.md +40 -0
  33. tabletalk-0.4.0/docs/safe-mode.md +146 -0
  34. tabletalk-0.4.0/docs/web-ui.md +103 -0
  35. tabletalk-0.4.0/examples/duckdb-analytics/README.md +19 -0
  36. tabletalk-0.4.0/examples/duckdb-analytics/agents/revenue.yaml +51 -0
  37. tabletalk-0.4.0/examples/duckdb-analytics/evals/fixtures/data.sql +14 -0
  38. tabletalk-0.4.0/examples/duckdb-analytics/evals/fixtures/schema.sql +19 -0
  39. tabletalk-0.4.0/examples/duckdb-analytics/evals/revenue.yaml +59 -0
  40. tabletalk-0.4.0/examples/duckdb-analytics/seed.py +14 -0
  41. tabletalk-0.4.0/examples/duckdb-analytics/tabletalk.yaml +17 -0
  42. tabletalk-0.4.0/examples/snowflake-production/README.md +27 -0
  43. tabletalk-0.4.0/examples/snowflake-production/agents/sales.yaml +37 -0
  44. tabletalk-0.4.0/examples/snowflake-production/evals/fixtures/data.sql +5 -0
  45. tabletalk-0.4.0/examples/snowflake-production/evals/fixtures/schema.sql +14 -0
  46. tabletalk-0.4.0/examples/snowflake-production/evals/sales.yaml +36 -0
  47. tabletalk-0.4.0/examples/snowflake-production/tabletalk.yaml +27 -0
  48. tabletalk-0.4.0/examples/sqlite-starter/README.md +25 -0
  49. tabletalk-0.4.0/examples/sqlite-starter/agents/sales.yaml +37 -0
  50. tabletalk-0.4.0/examples/sqlite-starter/evals/fixtures/data.sql +5 -0
  51. tabletalk-0.4.0/examples/sqlite-starter/evals/fixtures/schema.sql +6 -0
  52. tabletalk-0.4.0/examples/sqlite-starter/evals/sales.yaml +53 -0
  53. tabletalk-0.4.0/examples/sqlite-starter/tabletalk.yaml +17 -0
  54. {tabletalk-0.2.0 → tabletalk-0.4.0}/pyproject.toml +18 -20
  55. tabletalk-0.4.0/tabletalk/__init__.py +44 -0
  56. tabletalk-0.4.0/tabletalk/agents.py +284 -0
  57. tabletalk-0.4.0/tabletalk/app.py +227 -0
  58. tabletalk-0.4.0/tabletalk/cli.py +918 -0
  59. tabletalk-0.4.0/tabletalk/compiler/__init__.py +23 -0
  60. tabletalk-0.4.0/tabletalk/compiler/artifact.py +101 -0
  61. tabletalk-0.4.0/tabletalk/compiler/compiler.py +384 -0
  62. tabletalk-0.4.0/tabletalk/compiler/plan.py +52 -0
  63. tabletalk-0.4.0/tabletalk/dbt_manifest.py +208 -0
  64. tabletalk-0.4.0/tabletalk/domain/__init__.py +47 -0
  65. tabletalk-0.4.0/tabletalk/domain/errors.py +119 -0
  66. tabletalk-0.4.0/tabletalk/domain/models.py +141 -0
  67. tabletalk-0.4.0/tabletalk/domain/serialization.py +39 -0
  68. tabletalk-0.4.0/tabletalk/evals/__init__.py +32 -0
  69. tabletalk-0.4.0/tabletalk/evals/loader.py +323 -0
  70. tabletalk-0.4.0/tabletalk/evals/metrics.py +555 -0
  71. tabletalk-0.4.0/tabletalk/evals/models.py +138 -0
  72. tabletalk-0.4.0/tabletalk/evals/receipts.py +127 -0
  73. tabletalk-0.4.0/tabletalk/evals/reporters.py +70 -0
  74. tabletalk-0.4.0/tabletalk/evals/runner.py +316 -0
  75. tabletalk-0.4.0/tabletalk/evals/sql_analysis.py +81 -0
  76. tabletalk-0.4.0/tabletalk/factories.py +195 -0
  77. tabletalk-0.4.0/tabletalk/interfaces.py +491 -0
  78. tabletalk-0.4.0/tabletalk/project.py +679 -0
  79. {tabletalk-0.2.0 → tabletalk-0.4.0}/tabletalk/providers/duckdb_provider.py +14 -10
  80. tabletalk-0.4.0/tabletalk/providers/openai_provider.py +174 -0
  81. {tabletalk-0.2.0 → tabletalk-0.4.0}/tabletalk/providers/snowflake_provider.py +10 -10
  82. {tabletalk-0.2.0 → tabletalk-0.4.0}/tabletalk/providers/sqlite_provider.py +24 -10
  83. tabletalk-0.4.0/tabletalk/runtime/__init__.py +6 -0
  84. tabletalk-0.4.0/tabletalk/runtime/sql_validation.py +272 -0
  85. tabletalk-0.4.0/tabletalk/runtime/structured.py +983 -0
  86. tabletalk-0.4.0/tabletalk/static/app.js +265 -0
  87. tabletalk-0.4.0/tabletalk/static/index.html +129 -0
  88. tabletalk-0.4.0/tabletalk/static/styles.css +134 -0
  89. tabletalk-0.4.0/tabletalk/structured_output.py +96 -0
  90. {tabletalk-0.2.0 → tabletalk-0.4.0}/tabletalk/tests/conftest.py +5 -9
  91. {tabletalk-0.2.0 → tabletalk-0.4.0}/tabletalk/tests/providers/test_duckdb.py +8 -3
  92. {tabletalk-0.2.0 → tabletalk-0.4.0}/tabletalk/tests/providers/test_sqlite.py +7 -2
  93. tabletalk-0.4.0/tabletalk/tests/test_agent_evals.py +280 -0
  94. tabletalk-0.4.0/tabletalk/tests/test_agents.py +219 -0
  95. tabletalk-0.4.0/tabletalk/tests/test_app.py +299 -0
  96. tabletalk-0.4.0/tabletalk/tests/test_ask.py +174 -0
  97. tabletalk-0.4.0/tabletalk/tests/test_cli.py +281 -0
  98. tabletalk-0.4.0/tabletalk/tests/test_compiler.py +129 -0
  99. tabletalk-0.4.0/tabletalk/tests/test_dbt_manifest.py +109 -0
  100. tabletalk-0.4.0/tabletalk/tests/test_domain.py +135 -0
  101. tabletalk-0.4.0/tabletalk/tests/test_eval_receipts.py +122 -0
  102. tabletalk-0.4.0/tabletalk/tests/test_evals.py +195 -0
  103. {tabletalk-0.2.0 → tabletalk-0.4.0}/tabletalk/tests/test_factories.py +69 -60
  104. tabletalk-0.4.0/tabletalk/tests/test_interfaces.py +142 -0
  105. tabletalk-0.4.0/tabletalk/tests/test_live_ollama.py +78 -0
  106. tabletalk-0.4.0/tabletalk/tests/test_plan.py +32 -0
  107. tabletalk-0.4.0/tabletalk/tests/test_project.py +385 -0
  108. tabletalk-0.4.0/tabletalk/tests/test_sql_validation.py +148 -0
  109. tabletalk-0.4.0/tabletalk/tests/test_structured_output.py +63 -0
  110. tabletalk-0.4.0/tabletalk/tests/test_structured_runtime.py +552 -0
  111. tabletalk-0.4.0/tabletalk/tests/test_utils.py +69 -0
  112. tabletalk-0.4.0/tabletalk/utils.py +202 -0
  113. tabletalk-0.4.0/tabletalk.yaml +20 -0
  114. tabletalk-0.4.0/uv.lock +1921 -0
  115. tabletalk-0.2.0/.github/workflows/db_provider_tests.yml +0 -57
  116. tabletalk-0.2.0/.github/workflows/publish.yml +0 -31
  117. tabletalk-0.2.0/PKG-INFO +0 -494
  118. tabletalk-0.2.0/README.md +0 -451
  119. tabletalk-0.2.0/docs/conf.py +0 -27
  120. tabletalk-0.2.0/docs/dev/contexts.rst +0 -45
  121. tabletalk-0.2.0/docs/dev/local_development.rst +0 -127
  122. tabletalk-0.2.0/docs/dev/providers.rst +0 -164
  123. tabletalk-0.2.0/docs/dev/querying.rst +0 -201
  124. tabletalk-0.2.0/docs/index.rst +0 -26
  125. tabletalk-0.2.0/examples/ecommerce/README.md +0 -235
  126. tabletalk-0.2.0/examples/ecommerce/agents/customer_analyst.yaml +0 -44
  127. tabletalk-0.2.0/examples/ecommerce/agents/inventory_manager.yaml +0 -34
  128. tabletalk-0.2.0/examples/ecommerce/agents/marketing_analyst.yaml +0 -35
  129. tabletalk-0.2.0/examples/ecommerce/agents/revenue_analyst.yaml +0 -39
  130. tabletalk-0.2.0/examples/ecommerce/contexts/customers.yaml +0 -30
  131. tabletalk-0.2.0/examples/ecommerce/contexts/inventory.yaml +0 -41
  132. tabletalk-0.2.0/examples/ecommerce/contexts/marketing.yaml +0 -39
  133. tabletalk-0.2.0/examples/ecommerce/contexts/sales.yaml +0 -53
  134. tabletalk-0.2.0/examples/ecommerce/manifest/customers.txt +0 -5
  135. tabletalk-0.2.0/examples/ecommerce/manifest/inventory.txt +0 -7
  136. tabletalk-0.2.0/examples/ecommerce/manifest/marketing.txt +0 -7
  137. tabletalk-0.2.0/examples/ecommerce/manifest/sales.txt +0 -9
  138. tabletalk-0.2.0/examples/ecommerce/seed.py +0 -317
  139. tabletalk-0.2.0/examples/ecommerce/tabletalk.yaml +0 -51
  140. tabletalk-0.2.0/tabletalk/__init__.py +0 -27
  141. tabletalk-0.2.0/tabletalk/app.py +0 -369
  142. tabletalk-0.2.0/tabletalk/cli.py +0 -535
  143. tabletalk-0.2.0/tabletalk/factories.py +0 -155
  144. tabletalk-0.2.0/tabletalk/interfaces.py +0 -507
  145. tabletalk-0.2.0/tabletalk/profiles.py +0 -127
  146. tabletalk-0.2.0/tabletalk/providers/anthropic_provider.py +0 -59
  147. tabletalk-0.2.0/tabletalk/providers/azuresql_provider.py +0 -179
  148. tabletalk-0.2.0/tabletalk/providers/bigquery_provider.py +0 -98
  149. tabletalk-0.2.0/tabletalk/providers/mysql_provider.py +0 -186
  150. tabletalk-0.2.0/tabletalk/providers/openai_provider.py +0 -51
  151. tabletalk-0.2.0/tabletalk/providers/postgres_provider.py +0 -164
  152. tabletalk-0.2.0/tabletalk/static/index.html +0 -1271
  153. tabletalk-0.2.0/tabletalk/tests/providers/test_azuresql.py +0 -61
  154. tabletalk-0.2.0/tabletalk/tests/providers/test_bigquery.py +0 -60
  155. tabletalk-0.2.0/tabletalk/tests/providers/test_mysql.py +0 -129
  156. tabletalk-0.2.0/tabletalk/tests/providers/test_postgres.py +0 -114
  157. tabletalk-0.2.0/tabletalk/tests/test_app.py +0 -505
  158. tabletalk-0.2.0/tabletalk/tests/test_cli.py +0 -488
  159. tabletalk-0.2.0/tabletalk/tests/test_interfaces.py +0 -597
  160. tabletalk-0.2.0/tabletalk/tests/test_profiles.py +0 -378
  161. tabletalk-0.2.0/tabletalk/tests/test_utils.py +0 -218
  162. tabletalk-0.2.0/tabletalk/utils.py +0 -122
  163. tabletalk-0.2.0/tabletalk.yaml +0 -17
  164. tabletalk-0.2.0/uv.lock +0 -2416
  165. {tabletalk-0.2.0 → tabletalk-0.4.0}/.pre-commit-config.yaml +0 -0
  166. {tabletalk-0.2.0 → tabletalk-0.4.0}/.python-version +0 -0
  167. {tabletalk-0.2.0 → tabletalk-0.4.0}/LICENSE +0 -0
  168. {tabletalk-0.2.0 → tabletalk-0.4.0}/contexts/default_context.yaml +0 -0
  169. {tabletalk-0.2.0 → tabletalk-0.4.0}/docs/make.bat +0 -0
  170. {tabletalk-0.2.0 → tabletalk-0.4.0}/tabletalk/main.py +0 -0
  171. {tabletalk-0.2.0 → tabletalk-0.4.0}/tabletalk/providers/__init__.py +0 -0
  172. {tabletalk-0.2.0 → tabletalk-0.4.0}/tabletalk/static/logo.jpg +0 -0
  173. {tabletalk-0.2.0 → tabletalk-0.4.0}/tabletalk/tests/__init__.py +0 -0
  174. {tabletalk-0.2.0 → tabletalk-0.4.0}/tabletalk/tests/providers/__init__.py +0 -0
  175. {tabletalk-0.2.0 → tabletalk-0.4.0}/tabletalk/tests/providers/test_snowflake.py +0 -0
@@ -0,0 +1,84 @@
1
+ name: Test supported providers
2
+
3
+ on:
4
+ push:
5
+ branches: [main]
6
+ pull_request:
7
+ branches: [main]
8
+ workflow_dispatch:
9
+
10
+ permissions:
11
+ contents: read
12
+
13
+ jobs:
14
+ test:
15
+ name: Python ${{ matrix.python-version }}
16
+ runs-on: ubuntu-latest
17
+ strategy:
18
+ fail-fast: false
19
+ matrix:
20
+ python-version: ["3.10", "3.11", "3.12"]
21
+
22
+ steps:
23
+ - uses: actions/checkout@v6
24
+
25
+ - name: Install uv
26
+ uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
27
+ with:
28
+ enable-cache: true
29
+ cache-suffix: py${{ matrix.python-version }}
30
+
31
+ - name: Set up Python
32
+ uses: actions/setup-python@v6
33
+ with:
34
+ python-version: ${{ matrix.python-version }}
35
+
36
+ - name: Install supported database extras
37
+ run: uv sync --all-extras
38
+
39
+ - name: Run tests
40
+ run: uv run pytest -q
41
+
42
+ - name: Run static checks
43
+ run: |
44
+ uv run ruff check tabletalk
45
+ uv run mypy tabletalk
46
+
47
+ package:
48
+ name: Verify PyPI distribution
49
+ runs-on: ubuntu-latest
50
+
51
+ steps:
52
+ - uses: actions/checkout@v6
53
+
54
+ - name: Install uv
55
+ uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
56
+
57
+ - name: Set up Python
58
+ uses: actions/setup-python@v6
59
+ with:
60
+ python-version: "3.11"
61
+
62
+ - name: Build distribution
63
+ run: uv build
64
+
65
+ - name: Validate PyPI metadata
66
+ run: uvx twine check --strict dist/*
67
+
68
+ - name: Verify wheel contents and installation
69
+ run: |
70
+ python - <<'PY'
71
+ from pathlib import Path
72
+ from zipfile import ZipFile
73
+
74
+ wheel = next(Path("dist").glob("*.whl"))
75
+ with ZipFile(wheel) as archive:
76
+ names = archive.namelist()
77
+ assert not any("/tests/" in name for name in names)
78
+ assert not any(".data/data/tabletalk/static/" in name for name in names)
79
+ assert "tabletalk/static/index.html" in names
80
+ PY
81
+ uv venv .package-test
82
+ uv pip install --python .package-test/bin/python dist/*.whl
83
+ .package-test/bin/tabletalk --version
84
+ .package-test/bin/python -c "from tabletalk import Agent, EvalSuite, Project"
@@ -0,0 +1,92 @@
1
+ name: Publish to PyPI
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+
7
+ permissions:
8
+ contents: read
9
+
10
+ jobs:
11
+ build:
12
+ name: Build and verify distribution
13
+ runs-on: ubuntu-latest
14
+
15
+ steps:
16
+ - uses: actions/checkout@v6
17
+
18
+ - name: Install uv
19
+ uses: astral-sh/setup-uv@08807647e7069bb48b6ef5acd8ec9567f424441b # v8.1.0
20
+ with:
21
+ enable-cache: true
22
+
23
+ - name: Set up Python
24
+ uses: actions/setup-python@v6
25
+ with:
26
+ python-version: "3.11"
27
+
28
+ - name: Verify release tag matches package version
29
+ run: |
30
+ PACKAGE_VERSION="$(python -c 'import tomllib; print(tomllib.load(open("pyproject.toml", "rb"))["project"]["version"])')"
31
+ test "${GITHUB_REF_NAME#v}" = "$PACKAGE_VERSION"
32
+
33
+ - name: Build wheel and source distribution
34
+ run: uv build
35
+
36
+ - name: Validate PyPI metadata
37
+ run: uvx twine check --strict dist/*
38
+
39
+ - name: Inspect wheel contents
40
+ run: |
41
+ python - <<'PY'
42
+ from pathlib import Path
43
+ from zipfile import ZipFile
44
+
45
+ wheel = next(Path("dist").glob("*.whl"))
46
+ with ZipFile(wheel) as archive:
47
+ names = archive.namelist()
48
+ assert not any("/tests/" in name for name in names)
49
+ assert not any(".data/data/tabletalk/static/" in name for name in names)
50
+ for required in (
51
+ "tabletalk/static/index.html",
52
+ "tabletalk/static/app.js",
53
+ "tabletalk/static/styles.css",
54
+ ):
55
+ assert required in names, f"missing wheel asset: {required}"
56
+ PY
57
+
58
+ - name: Verify wheel installation
59
+ run: |
60
+ uv venv .package-test
61
+ uv pip install --python .package-test/bin/python dist/*.whl
62
+ .package-test/bin/tabletalk --version
63
+ .package-test/bin/python -c "from tabletalk import Agent, EvalSuite, Project"
64
+
65
+ - name: Upload verified distributions
66
+ uses: actions/upload-artifact@v7
67
+ with:
68
+ name: python-package-distributions
69
+ path: dist/
70
+ if-no-files-found: error
71
+
72
+ publish:
73
+ name: Publish verified distribution
74
+ needs: build
75
+ runs-on: ubuntu-latest
76
+ environment:
77
+ name: pypi
78
+ url: https://pypi.org/p/tabletalk
79
+ permissions:
80
+ id-token: write
81
+
82
+ steps:
83
+ - name: Download verified distributions
84
+ uses: actions/download-artifact@v8
85
+ with:
86
+ name: python-package-distributions
87
+ path: dist/
88
+
89
+ - name: Publish to PyPI using trusted publishing
90
+ uses: pypa/gh-action-pypi-publish@release/v1
91
+ with:
92
+ packages-dir: dist/
@@ -65,8 +65,25 @@ user_settings.json
65
65
 
66
66
  # Database
67
67
  *.db
68
+ *.duckdb
69
+ *.duckdb.wal
70
+ examples/ecommerce/evals/fixtures/*.duckdb
68
71
  __pycache__
69
72
 
73
+ # TableTalk generated output and per-user runtime state
74
+ /examples/*/manifest/
75
+ .tabletalk_history.jsonl
76
+ .tabletalk_favorites.json
77
+ .tabletalk_audit.jsonl
78
+ .tabletalk_schedules.json
79
+ .tabletalk_history/
80
+ .tabletalk_memory/
81
+
82
+ # dbt generated and per-user state
83
+ .user.yml
84
+ /examples/*/dbt_project/dbt_packages/
85
+ /examples/*/dbt_project/logs/
86
+
70
87
  # PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm
71
88
  __pypackages__/
72
89
 
@@ -0,0 +1,272 @@
1
+ Metadata-Version: 2.4
2
+ Name: tabletalk
3
+ Version: 0.4.0
4
+ Summary: Natural language to SQL — the dbt companion for AI-powered data workflows
5
+ Project-URL: Homepage, https://github.com/wtbates99/tabletalk
6
+ Project-URL: Repository, https://github.com/wtbates99/tabletalk
7
+ Author-email: william bates <wtbates99@gmail.com>
8
+ License: CC BY-NC 4.0
9
+ License-File: LICENSE
10
+ Keywords: ai,database,dbt,llm,natural-language,sql
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Programming Language :: Python :: 3.10
13
+ Classifier: Programming Language :: Python :: 3.11
14
+ Classifier: Programming Language :: Python :: 3.12
15
+ Requires-Python: >=3.10
16
+ Requires-Dist: click>=8.0
17
+ Requires-Dist: flask>=3.0
18
+ Requires-Dist: openai>=1.0.0
19
+ Requires-Dist: pyyaml>=6.0
20
+ Requires-Dist: rich>=13.0
21
+ Requires-Dist: sqlglot>=25.0
22
+ Provides-Extra: all
23
+ Requires-Dist: duckdb>=0.9; extra == 'all'
24
+ Requires-Dist: snowflake-connector-python>=3.0; extra == 'all'
25
+ Provides-Extra: duckdb
26
+ Requires-Dist: duckdb>=0.9; extra == 'duckdb'
27
+ Provides-Extra: snowflake
28
+ Requires-Dist: snowflake-connector-python>=3.0; extra == 'snowflake'
29
+ Description-Content-Type: text/markdown
30
+
31
+ # TableTalk
32
+
33
+ TableTalk defines trusted data agents as code. An Agent declares the relations,
34
+ semantics, policies, and regression suites it may use. TableTalk compiles that
35
+ source into a content-addressed artifact, shows a semantic plan, runs
36
+ execution-based evals, and only applies the exact artifact that passed.
37
+
38
+ At runtime, an applied Agent produces a structured interpretation and query
39
+ plan, validates generated SQL against its compiled scope, executes a read-only
40
+ query, and returns claims tied to evidence and reproducible calculations.
41
+ Missing models, database failures, empty evidence, and unsupported claims are
42
+ reported explicitly. They are never replaced by heuristic or locally generated
43
+ answers.
44
+
45
+ ## Free local development
46
+
47
+ Local development defaults to Ollama's free cloud model
48
+ `gemma4:31b-cloud`. Ollama runs the OpenAI-compatible endpoint locally; the
49
+ model itself is the cloud model.
50
+
51
+ ```bash
52
+ ollama signin
53
+ ollama pull gemma4:31b-cloud
54
+
55
+ uv sync --extra duckdb
56
+ uv run tabletalk init
57
+ uv run tabletalk compile
58
+ uv run tabletalk plan
59
+ uv run tabletalk eval
60
+ uv run tabletalk apply
61
+ uv run tabletalk ask starter "How many customers are there?"
62
+ ```
63
+
64
+ The generated `tabletalk.yaml` contains:
65
+
66
+ ```yaml
67
+ llm:
68
+ provider: ollama
69
+ model: gemma4:31b-cloud
70
+ base_url: http://localhost:11434/v1
71
+ api_key: ollama
72
+ temperature: 0
73
+ ```
74
+
75
+ Production is not tied to Gemma or Ollama. Configure any compatible model
76
+ endpoint explicitly. TableTalk does not silently switch models or providers.
77
+
78
+ ## Install
79
+
80
+ ```bash
81
+ pip install tabletalk
82
+ pip install "tabletalk[duckdb]" # optional DuckDB driver
83
+ pip install "tabletalk[snowflake]" # optional Snowflake driver
84
+ ```
85
+
86
+ SQLite is included with Python. The supported database surface is deliberately
87
+ limited to SQLite, DuckDB, and Snowflake.
88
+
89
+ ## Project layout
90
+
91
+ ```text
92
+ .
93
+ ├── tabletalk.yaml
94
+ ├── agents/
95
+ │ └── starter.yaml
96
+ ├── evals/
97
+ │ └── starter.yaml
98
+ └── .tabletalk/ # generated, content-addressed local state
99
+ ├── artifacts/
100
+ ├── evals/
101
+ ├── history/
102
+ └── state.json
103
+ ```
104
+
105
+ An Agent is a versioned resource:
106
+
107
+ ```yaml
108
+ kind: Agent
109
+ version: "1"
110
+ name: starter
111
+ description: Answers customer questions from the approved dataset.
112
+ connection: default
113
+ relations:
114
+ include:
115
+ - main.customers
116
+ semantics:
117
+ metrics:
118
+ customer_count:
119
+ expression: count(id)
120
+ relation: main.customers
121
+ policies:
122
+ read_only: true
123
+ require_evidence: true
124
+ max_rows: 500
125
+ timeout_seconds: 30
126
+ evals:
127
+ - starter_regression
128
+ ```
129
+
130
+ An EvalSuite binds executable expectations to that Agent:
131
+
132
+ ```yaml
133
+ kind: EvalSuite
134
+ version: 1
135
+ name: starter_regression
136
+ agent: starter
137
+ environment:
138
+ connection: default
139
+ cases:
140
+ - name: customer_count
141
+ messages:
142
+ - role: user
143
+ content: How many customers are there?
144
+ expected:
145
+ result:
146
+ type: scalar
147
+ value: 3
148
+ ```
149
+
150
+ ## Lifecycle
151
+
152
+ ```bash
153
+ tabletalk connect
154
+ tabletalk discover
155
+ tabletalk compile
156
+ tabletalk plan
157
+ tabletalk eval
158
+ tabletalk apply
159
+ tabletalk ask AGENT "QUESTION"
160
+ tabletalk serve
161
+ ```
162
+
163
+ - `connect` creates or tests a project connection without writing secrets into
164
+ generated artifacts.
165
+ - `discover` shows visible database metadata and can write a scoped Agent.
166
+ - `compile` is deterministic and does not invoke a model.
167
+ - `plan` compares canonical candidate and applied artifacts.
168
+ - `eval` runs the exact candidate through the real structured runtime.
169
+ - `apply` requires passing receipts for every required suite and updates all
170
+ selected Agents atomically.
171
+ - `ask` and `serve` use applied artifacts only and expose evidence, SQL,
172
+ verification, and technical receipts.
173
+
174
+ Supporting inspection commands are available under `agents` and `connections`.
175
+ Run `tabletalk COMMAND --help` for exact options. Exit codes distinguish usage
176
+ errors, configuration failures, eval failures, and runtime failures.
177
+
178
+ ## Database configuration
179
+
180
+ SQLite:
181
+
182
+ ```yaml
183
+ connections:
184
+ default:
185
+ type: sqlite
186
+ database_path: ./data.db
187
+ read_only: true
188
+ ```
189
+
190
+ DuckDB:
191
+
192
+ ```yaml
193
+ connections:
194
+ default:
195
+ type: duckdb
196
+ database_path: ./analytics.duckdb
197
+ read_only: true
198
+ ```
199
+
200
+ Snowflake secrets should come from environment variables, not source files:
201
+
202
+ ```yaml
203
+ connections:
204
+ default:
205
+ type: snowflake
206
+ account: ${SNOWFLAKE_ACCOUNT}
207
+ user: ${SNOWFLAKE_USER}
208
+ password: ${SNOWFLAKE_PASSWORD}
209
+ database: ANALYTICS
210
+ warehouse: COMPUTE_WH
211
+ schema: PUBLIC
212
+ role: TABLETALK_READER
213
+ ```
214
+
215
+ Use a database identity that is independently restricted to read-only access.
216
+ SQL AST validation is an additional boundary, not a replacement for database
217
+ permissions.
218
+
219
+ ## dbt metadata
220
+
221
+ Point TableTalk at a dbt project or manifest:
222
+
223
+ ```yaml
224
+ dbt:
225
+ project_dir: ../analytics
226
+ target_dir: target
227
+ ```
228
+
229
+ Compilation incorporates available descriptions, lineage, tests,
230
+ materializations, tags, groups, and ownership into the canonical artifact.
231
+ A changed dbt manifest changes the candidate digest and must pass evals again.
232
+
233
+ ## Examples and verification
234
+
235
+ - [`examples/sqlite-starter`](examples/sqlite-starter) — smallest local path
236
+ - [`examples/duckdb-analytics`](examples/duckdb-analytics) — analytics joins and
237
+ a join-multiplication regression
238
+ - [`examples/snowflake-production`](examples/snowflake-production) — env-only
239
+ Snowflake credentials with a local DuckDB eval fixture
240
+
241
+ Run the deterministic suite:
242
+
243
+ ```bash
244
+ uv run pytest -q
245
+ uv run ruff check tabletalk
246
+ uv run mypy tabletalk
247
+ ```
248
+
249
+ The live Gemma smoke test is opt-in because it needs an authenticated Ollama
250
+ daemon:
251
+
252
+ ```bash
253
+ TABLETALK_RUN_LIVE_OLLAMA=1 \
254
+ uv run pytest -q -m live_ollama tabletalk/tests/test_live_ollama.py
255
+ ```
256
+
257
+ ## Security and data handling
258
+
259
+ - Query execution is read-only and limited to one parsed query.
260
+ - Agent relation, column, join, row, and timeout policies are enforced before
261
+ execution.
262
+ - Applied state references immutable artifact and eval-receipt digests.
263
+ - Local invocation history stores metadata and receipts, not raw result rows.
264
+ - Credential-shaped values are redacted from history and HTTP responses.
265
+ - A model or database outage produces a typed failure; no cached prose,
266
+ alternate provider, or heuristic response is substituted.
267
+
268
+ ## License
269
+
270
+ The current package metadata retains CC BY-NC 4.0 while the repository's
271
+ ownership and third-party asset audit remains unresolved. See
272
+ [`docs/refactor/licensing-audit.md`](docs/refactor/licensing-audit.md).
@@ -0,0 +1,242 @@
1
+ # TableTalk
2
+
3
+ TableTalk defines trusted data agents as code. An Agent declares the relations,
4
+ semantics, policies, and regression suites it may use. TableTalk compiles that
5
+ source into a content-addressed artifact, shows a semantic plan, runs
6
+ execution-based evals, and only applies the exact artifact that passed.
7
+
8
+ At runtime, an applied Agent produces a structured interpretation and query
9
+ plan, validates generated SQL against its compiled scope, executes a read-only
10
+ query, and returns claims tied to evidence and reproducible calculations.
11
+ Missing models, database failures, empty evidence, and unsupported claims are
12
+ reported explicitly. They are never replaced by heuristic or locally generated
13
+ answers.
14
+
15
+ ## Free local development
16
+
17
+ Local development defaults to Ollama's free cloud model
18
+ `gemma4:31b-cloud`. Ollama runs the OpenAI-compatible endpoint locally; the
19
+ model itself is the cloud model.
20
+
21
+ ```bash
22
+ ollama signin
23
+ ollama pull gemma4:31b-cloud
24
+
25
+ uv sync --extra duckdb
26
+ uv run tabletalk init
27
+ uv run tabletalk compile
28
+ uv run tabletalk plan
29
+ uv run tabletalk eval
30
+ uv run tabletalk apply
31
+ uv run tabletalk ask starter "How many customers are there?"
32
+ ```
33
+
34
+ The generated `tabletalk.yaml` contains:
35
+
36
+ ```yaml
37
+ llm:
38
+ provider: ollama
39
+ model: gemma4:31b-cloud
40
+ base_url: http://localhost:11434/v1
41
+ api_key: ollama
42
+ temperature: 0
43
+ ```
44
+
45
+ Production is not tied to Gemma or Ollama. Configure any compatible model
46
+ endpoint explicitly. TableTalk does not silently switch models or providers.
47
+
48
+ ## Install
49
+
50
+ ```bash
51
+ pip install tabletalk
52
+ pip install "tabletalk[duckdb]" # optional DuckDB driver
53
+ pip install "tabletalk[snowflake]" # optional Snowflake driver
54
+ ```
55
+
56
+ SQLite is included with Python. The supported database surface is deliberately
57
+ limited to SQLite, DuckDB, and Snowflake.
58
+
59
+ ## Project layout
60
+
61
+ ```text
62
+ .
63
+ ├── tabletalk.yaml
64
+ ├── agents/
65
+ │ └── starter.yaml
66
+ ├── evals/
67
+ │ └── starter.yaml
68
+ └── .tabletalk/ # generated, content-addressed local state
69
+ ├── artifacts/
70
+ ├── evals/
71
+ ├── history/
72
+ └── state.json
73
+ ```
74
+
75
+ An Agent is a versioned resource:
76
+
77
+ ```yaml
78
+ kind: Agent
79
+ version: "1"
80
+ name: starter
81
+ description: Answers customer questions from the approved dataset.
82
+ connection: default
83
+ relations:
84
+ include:
85
+ - main.customers
86
+ semantics:
87
+ metrics:
88
+ customer_count:
89
+ expression: count(id)
90
+ relation: main.customers
91
+ policies:
92
+ read_only: true
93
+ require_evidence: true
94
+ max_rows: 500
95
+ timeout_seconds: 30
96
+ evals:
97
+ - starter_regression
98
+ ```
99
+
100
+ An EvalSuite binds executable expectations to that Agent:
101
+
102
+ ```yaml
103
+ kind: EvalSuite
104
+ version: 1
105
+ name: starter_regression
106
+ agent: starter
107
+ environment:
108
+ connection: default
109
+ cases:
110
+ - name: customer_count
111
+ messages:
112
+ - role: user
113
+ content: How many customers are there?
114
+ expected:
115
+ result:
116
+ type: scalar
117
+ value: 3
118
+ ```
119
+
120
+ ## Lifecycle
121
+
122
+ ```bash
123
+ tabletalk connect
124
+ tabletalk discover
125
+ tabletalk compile
126
+ tabletalk plan
127
+ tabletalk eval
128
+ tabletalk apply
129
+ tabletalk ask AGENT "QUESTION"
130
+ tabletalk serve
131
+ ```
132
+
133
+ - `connect` creates or tests a project connection without writing secrets into
134
+ generated artifacts.
135
+ - `discover` shows visible database metadata and can write a scoped Agent.
136
+ - `compile` is deterministic and does not invoke a model.
137
+ - `plan` compares canonical candidate and applied artifacts.
138
+ - `eval` runs the exact candidate through the real structured runtime.
139
+ - `apply` requires passing receipts for every required suite and updates all
140
+ selected Agents atomically.
141
+ - `ask` and `serve` use applied artifacts only and expose evidence, SQL,
142
+ verification, and technical receipts.
143
+
144
+ Supporting inspection commands are available under `agents` and `connections`.
145
+ Run `tabletalk COMMAND --help` for exact options. Exit codes distinguish usage
146
+ errors, configuration failures, eval failures, and runtime failures.
147
+
148
+ ## Database configuration
149
+
150
+ SQLite:
151
+
152
+ ```yaml
153
+ connections:
154
+ default:
155
+ type: sqlite
156
+ database_path: ./data.db
157
+ read_only: true
158
+ ```
159
+
160
+ DuckDB:
161
+
162
+ ```yaml
163
+ connections:
164
+ default:
165
+ type: duckdb
166
+ database_path: ./analytics.duckdb
167
+ read_only: true
168
+ ```
169
+
170
+ Snowflake secrets should come from environment variables, not source files:
171
+
172
+ ```yaml
173
+ connections:
174
+ default:
175
+ type: snowflake
176
+ account: ${SNOWFLAKE_ACCOUNT}
177
+ user: ${SNOWFLAKE_USER}
178
+ password: ${SNOWFLAKE_PASSWORD}
179
+ database: ANALYTICS
180
+ warehouse: COMPUTE_WH
181
+ schema: PUBLIC
182
+ role: TABLETALK_READER
183
+ ```
184
+
185
+ Use a database identity that is independently restricted to read-only access.
186
+ SQL AST validation is an additional boundary, not a replacement for database
187
+ permissions.
188
+
189
+ ## dbt metadata
190
+
191
+ Point TableTalk at a dbt project or manifest:
192
+
193
+ ```yaml
194
+ dbt:
195
+ project_dir: ../analytics
196
+ target_dir: target
197
+ ```
198
+
199
+ Compilation incorporates available descriptions, lineage, tests,
200
+ materializations, tags, groups, and ownership into the canonical artifact.
201
+ A changed dbt manifest changes the candidate digest and must pass evals again.
202
+
203
+ ## Examples and verification
204
+
205
+ - [`examples/sqlite-starter`](examples/sqlite-starter) — smallest local path
206
+ - [`examples/duckdb-analytics`](examples/duckdb-analytics) — analytics joins and
207
+ a join-multiplication regression
208
+ - [`examples/snowflake-production`](examples/snowflake-production) — env-only
209
+ Snowflake credentials with a local DuckDB eval fixture
210
+
211
+ Run the deterministic suite:
212
+
213
+ ```bash
214
+ uv run pytest -q
215
+ uv run ruff check tabletalk
216
+ uv run mypy tabletalk
217
+ ```
218
+
219
+ The live Gemma smoke test is opt-in because it needs an authenticated Ollama
220
+ daemon:
221
+
222
+ ```bash
223
+ TABLETALK_RUN_LIVE_OLLAMA=1 \
224
+ uv run pytest -q -m live_ollama tabletalk/tests/test_live_ollama.py
225
+ ```
226
+
227
+ ## Security and data handling
228
+
229
+ - Query execution is read-only and limited to one parsed query.
230
+ - Agent relation, column, join, row, and timeout policies are enforced before
231
+ execution.
232
+ - Applied state references immutable artifact and eval-receipt digests.
233
+ - Local invocation history stores metadata and receipts, not raw result rows.
234
+ - Credential-shaped values are redacted from history and HTTP responses.
235
+ - A model or database outage produces a typed failure; no cached prose,
236
+ alternate provider, or heuristic response is substituted.
237
+
238
+ ## License
239
+
240
+ The current package metadata retains CC BY-NC 4.0 while the repository's
241
+ ownership and third-party asset audit remains unresolved. See
242
+ [`docs/refactor/licensing-audit.md`](docs/refactor/licensing-audit.md).