querypilot 0.1.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 (91) hide show
  1. querypilot-0.1.0/.eval/baseline.json +340 -0
  2. querypilot-0.1.0/.github/ISSUE_TEMPLATE/bug_report.yml +54 -0
  3. querypilot-0.1.0/.github/ISSUE_TEMPLATE/config.yml +5 -0
  4. querypilot-0.1.0/.github/ISSUE_TEMPLATE/feature_request.yml +38 -0
  5. querypilot-0.1.0/.github/PULL_REQUEST_TEMPLATE.md +20 -0
  6. querypilot-0.1.0/.github/workflows/eval.yml +71 -0
  7. querypilot-0.1.0/.github/workflows/release.yml +46 -0
  8. querypilot-0.1.0/.gitignore +7 -0
  9. querypilot-0.1.0/CHANGELOG.md +87 -0
  10. querypilot-0.1.0/CODE_OF_CONDUCT.md +134 -0
  11. querypilot-0.1.0/CONTRIBUTING.md +67 -0
  12. querypilot-0.1.0/LICENSE +21 -0
  13. querypilot-0.1.0/PKG-INFO +601 -0
  14. querypilot-0.1.0/README.md +548 -0
  15. querypilot-0.1.0/SECURITY.md +39 -0
  16. querypilot-0.1.0/pyproject.toml +92 -0
  17. querypilot-0.1.0/src/querypilot/__init__.py +36 -0
  18. querypilot-0.1.0/src/querypilot/access/__init__.py +3 -0
  19. querypilot-0.1.0/src/querypilot/access/policy.py +32 -0
  20. querypilot-0.1.0/src/querypilot/adapters/__init__.py +1 -0
  21. querypilot-0.1.0/src/querypilot/adapters/anthropic.py +49 -0
  22. querypilot-0.1.0/src/querypilot/adapters/openai.py +53 -0
  23. querypilot-0.1.0/src/querypilot/audit/__init__.py +10 -0
  24. querypilot-0.1.0/src/querypilot/audit/sinks.py +46 -0
  25. querypilot-0.1.0/src/querypilot/audit/types.py +53 -0
  26. querypilot-0.1.0/src/querypilot/cli.py +401 -0
  27. querypilot-0.1.0/src/querypilot/connectors/__init__.py +5 -0
  28. querypilot-0.1.0/src/querypilot/connectors/base.py +24 -0
  29. querypilot-0.1.0/src/querypilot/connectors/postgres.py +48 -0
  30. querypilot-0.1.0/src/querypilot/connectors/sqlite.py +49 -0
  31. querypilot-0.1.0/src/querypilot/core/__init__.py +1 -0
  32. querypilot-0.1.0/src/querypilot/core/client.py +286 -0
  33. querypilot-0.1.0/src/querypilot/core/config.py +29 -0
  34. querypilot-0.1.0/src/querypilot/core/safety_defaults.py +12 -0
  35. querypilot-0.1.0/src/querypilot/core/types.py +89 -0
  36. querypilot-0.1.0/src/querypilot/evals/__init__.py +81 -0
  37. querypilot-0.1.0/src/querypilot/evals/check.py +222 -0
  38. querypilot-0.1.0/src/querypilot/evals/compare.py +286 -0
  39. querypilot-0.1.0/src/querypilot/evals/cost.py +202 -0
  40. querypilot-0.1.0/src/querypilot/evals/factory.py +83 -0
  41. querypilot-0.1.0/src/querypilot/evals/init.py +104 -0
  42. querypilot-0.1.0/src/querypilot/evals/loader.py +179 -0
  43. querypilot-0.1.0/src/querypilot/evals/pipeline.py +484 -0
  44. querypilot-0.1.0/src/querypilot/evals/replay.py +217 -0
  45. querypilot-0.1.0/src/querypilot/evals/report.py +246 -0
  46. querypilot-0.1.0/src/querypilot/evals/suite.py +91 -0
  47. querypilot-0.1.0/src/querypilot/evals/suite_runner.py +361 -0
  48. querypilot-0.1.0/src/querypilot/execution/__init__.py +1 -0
  49. querypilot-0.1.0/src/querypilot/execution/formatter.py +11 -0
  50. querypilot-0.1.0/src/querypilot/execution/runner.py +13 -0
  51. querypilot-0.1.0/src/querypilot/generation/__init__.py +9 -0
  52. querypilot-0.1.0/src/querypilot/generation/llm.py +180 -0
  53. querypilot-0.1.0/src/querypilot/generation/prompt_builder.py +49 -0
  54. querypilot-0.1.0/src/querypilot/generation/sql_generator.py +82 -0
  55. querypilot-0.1.0/src/querypilot/mcp/__init__.py +3 -0
  56. querypilot-0.1.0/src/querypilot/mcp/server.py +51 -0
  57. querypilot-0.1.0/src/querypilot/py.typed +0 -0
  58. querypilot-0.1.0/src/querypilot/schema/__init__.py +3 -0
  59. querypilot-0.1.0/src/querypilot/schema/introspector.py +8 -0
  60. querypilot-0.1.0/src/querypilot/schema/search.py +33 -0
  61. querypilot-0.1.0/src/querypilot/server/__init__.py +3 -0
  62. querypilot-0.1.0/src/querypilot/server/app.py +157 -0
  63. querypilot-0.1.0/src/querypilot/validation/__init__.py +3 -0
  64. querypilot-0.1.0/src/querypilot/validation/policies.py +3 -0
  65. querypilot-0.1.0/src/querypilot/validation/validator.py +592 -0
  66. querypilot-0.1.0/suites/safety.yaml +55 -0
  67. querypilot-0.1.0/suites/smoke.yaml +45 -0
  68. querypilot-0.1.0/tests/conftest.py +42 -0
  69. querypilot-0.1.0/tests/evals/__init__.py +0 -0
  70. querypilot-0.1.0/tests/evals/test_check.py +338 -0
  71. querypilot-0.1.0/tests/evals/test_cli.py +550 -0
  72. querypilot-0.1.0/tests/evals/test_compare.py +449 -0
  73. querypilot-0.1.0/tests/evals/test_cost.py +314 -0
  74. querypilot-0.1.0/tests/evals/test_factory.py +140 -0
  75. querypilot-0.1.0/tests/evals/test_loader.py +464 -0
  76. querypilot-0.1.0/tests/evals/test_pipeline.py +341 -0
  77. querypilot-0.1.0/tests/evals/test_replay.py +414 -0
  78. querypilot-0.1.0/tests/evals/test_report.py +269 -0
  79. querypilot-0.1.0/tests/evals/test_suite_runner.py +298 -0
  80. querypilot-0.1.0/tests/fixtures/demo.db +0 -0
  81. querypilot-0.1.0/tests/fixtures/seed_demo.py +160 -0
  82. querypilot-0.1.0/tests/test_access_policy.py +187 -0
  83. querypilot-0.1.0/tests/test_adapters.py +42 -0
  84. querypilot-0.1.0/tests/test_audit.py +62 -0
  85. querypilot-0.1.0/tests/test_llm_generation.py +142 -0
  86. querypilot-0.1.0/tests/test_mcp_runtime.py +74 -0
  87. querypilot-0.1.0/tests/test_postgres_connector.py +74 -0
  88. querypilot-0.1.0/tests/test_querypilot_flow.py +38 -0
  89. querypilot-0.1.0/tests/test_server_runtime.py +129 -0
  90. querypilot-0.1.0/tests/test_sqlite_connector.py +41 -0
  91. querypilot-0.1.0/tests/test_validation.py +217 -0
@@ -0,0 +1,340 @@
1
+ {
2
+ "suite_name": "smoke",
3
+ "generator_name": "demo",
4
+ "model_name": null,
5
+ "database_url": "sqlite:///tests/fixtures/demo.db",
6
+ "querypilot_version": "0.1.0",
7
+ "started_at": "2026-04-28T03:58:33.362161Z",
8
+ "finished_at": "2026-04-28T03:58:33.386932Z",
9
+ "duration_ms": 24,
10
+ "total_cases": 3,
11
+ "passed": 3,
12
+ "failed": 0,
13
+ "pass_rate": 1.0,
14
+ "safety_pass_rate": 1.0,
15
+ "correctness_rate": 1.0,
16
+ "repair_rate": 0.0,
17
+ "first_pass_rate": 1.0,
18
+ "avg_repair_attempts": 0.0,
19
+ "avg_latency_ms": 7,
20
+ "p50_latency_ms": 2,
21
+ "p95_latency_ms": 17,
22
+ "avg_generate_ms": 0,
23
+ "avg_validate_ms": 1,
24
+ "avg_repair_ms_when_triggered": 0,
25
+ "avg_execute_ms": 0,
26
+ "total_prompt_tokens": 0,
27
+ "total_completion_tokens": 0,
28
+ "estimated_cost_usd": 0.0,
29
+ "tag_rollups": {
30
+ "revenue": {
31
+ "tag": "revenue",
32
+ "total": 1,
33
+ "passed": 1,
34
+ "pass_rate": 1.0
35
+ },
36
+ "ranking": {
37
+ "tag": "ranking",
38
+ "total": 1,
39
+ "passed": 1,
40
+ "pass_rate": 1.0
41
+ },
42
+ "aggregation": {
43
+ "tag": "aggregation",
44
+ "total": 1,
45
+ "passed": 1,
46
+ "pass_rate": 1.0
47
+ },
48
+ "listing": {
49
+ "tag": "listing",
50
+ "total": 1,
51
+ "passed": 1,
52
+ "pass_rate": 1.0
53
+ }
54
+ },
55
+ "failure_breakdown": {},
56
+ "thresholds": {
57
+ "pass_rate": 0.95,
58
+ "safety_pass_rate": 1.0,
59
+ "correctness_rate": 0.9,
60
+ "max_p95_latency_ms": 5000,
61
+ "max_avg_cost_usd": null
62
+ },
63
+ "threshold_violations": [],
64
+ "case_results": [
65
+ {
66
+ "id": "top_customers_by_revenue",
67
+ "passed": true,
68
+ "failure_category": null,
69
+ "question": "Top customers by revenue",
70
+ "candidate_sql": "SELECT customer_name, revenue FROM customers ORDER BY revenue DESC LIMIT 100",
71
+ "rewritten_sql": "SELECT customer_name, revenue FROM customers ORDER BY revenue DESC LIMIT 100",
72
+ "gold_sql": "SELECT customer_name, revenue\nFROM customers\nORDER BY revenue DESC\nLIMIT 100\n",
73
+ "correctness_passed": true,
74
+ "safety_passed": false,
75
+ "validation_passed": true,
76
+ "execution_passed": true,
77
+ "repair_attempts": 0,
78
+ "validation_errors": [],
79
+ "rowset_match": {
80
+ "matched": true,
81
+ "order_sensitive": true,
82
+ "column_mismatch": [],
83
+ "missing_rows": [],
84
+ "extra_rows": [],
85
+ "mismatched_values": [],
86
+ "normalized_gold_rows": [
87
+ {
88
+ "customer_name": "Acme Corp",
89
+ "revenue": 120000
90
+ },
91
+ {
92
+ "customer_name": "Globex",
93
+ "revenue": 95000
94
+ },
95
+ {
96
+ "customer_name": "Hooli",
97
+ "revenue": 50000
98
+ },
99
+ {
100
+ "customer_name": "Initech",
101
+ "revenue": 40000
102
+ },
103
+ {
104
+ "customer_name": "Soylent",
105
+ "revenue": 18000
106
+ }
107
+ ],
108
+ "normalized_candidate_rows": [
109
+ {
110
+ "customer_name": "Acme Corp",
111
+ "revenue": 120000
112
+ },
113
+ {
114
+ "customer_name": "Globex",
115
+ "revenue": 95000
116
+ },
117
+ {
118
+ "customer_name": "Hooli",
119
+ "revenue": 50000
120
+ },
121
+ {
122
+ "customer_name": "Initech",
123
+ "revenue": 40000
124
+ },
125
+ {
126
+ "customer_name": "Soylent",
127
+ "revenue": 18000
128
+ }
129
+ ]
130
+ },
131
+ "timings": {
132
+ "generate_ms": 2,
133
+ "validate_ms": 4,
134
+ "repair_ms": 0,
135
+ "execute_ms": 1,
136
+ "gold_execute_ms": 0,
137
+ "compare_ms": 0,
138
+ "total_ms": 19
139
+ },
140
+ "token_usage": null,
141
+ "estimated_cost_usd": null,
142
+ "tags": [
143
+ "revenue",
144
+ "ranking"
145
+ ],
146
+ "error": null,
147
+ "traceback": null
148
+ },
149
+ {
150
+ "id": "customer_count",
151
+ "passed": true,
152
+ "failure_category": null,
153
+ "question": "Count of customers",
154
+ "candidate_sql": "SELECT COUNT(*) AS count FROM customers LIMIT 100",
155
+ "rewritten_sql": "SELECT COUNT(*) AS count FROM customers LIMIT 100",
156
+ "gold_sql": "SELECT COUNT(*) AS count FROM customers",
157
+ "correctness_passed": true,
158
+ "safety_passed": false,
159
+ "validation_passed": true,
160
+ "execution_passed": true,
161
+ "repair_attempts": 0,
162
+ "validation_errors": [],
163
+ "rowset_match": {
164
+ "matched": true,
165
+ "order_sensitive": false,
166
+ "column_mismatch": [],
167
+ "missing_rows": [],
168
+ "extra_rows": [],
169
+ "mismatched_values": [],
170
+ "normalized_gold_rows": [
171
+ {
172
+ "count": 5
173
+ }
174
+ ],
175
+ "normalized_candidate_rows": [
176
+ {
177
+ "count": 5
178
+ }
179
+ ]
180
+ },
181
+ "timings": {
182
+ "generate_ms": 0,
183
+ "validate_ms": 0,
184
+ "repair_ms": 0,
185
+ "execute_ms": 0,
186
+ "gold_execute_ms": 0,
187
+ "compare_ms": 0,
188
+ "total_ms": 2
189
+ },
190
+ "token_usage": null,
191
+ "estimated_cost_usd": null,
192
+ "tags": [
193
+ "aggregation"
194
+ ],
195
+ "error": null,
196
+ "traceback": null
197
+ },
198
+ {
199
+ "id": "list_invoices",
200
+ "passed": true,
201
+ "failure_category": null,
202
+ "question": "Show invoices",
203
+ "candidate_sql": "SELECT * FROM invoices LIMIT 100",
204
+ "rewritten_sql": "SELECT * FROM invoices LIMIT 100",
205
+ "gold_sql": "SELECT * FROM invoices LIMIT 100",
206
+ "correctness_passed": true,
207
+ "safety_passed": false,
208
+ "validation_passed": true,
209
+ "execution_passed": true,
210
+ "repair_attempts": 0,
211
+ "validation_errors": [],
212
+ "rowset_match": {
213
+ "matched": true,
214
+ "order_sensitive": false,
215
+ "column_mismatch": [],
216
+ "missing_rows": [],
217
+ "extra_rows": [],
218
+ "mismatched_values": [],
219
+ "normalized_gold_rows": [
220
+ {
221
+ "id": 1,
222
+ "customer_id": 1,
223
+ "month": "2026-03",
224
+ "revenue": 10000,
225
+ "status": "paid"
226
+ },
227
+ {
228
+ "id": 2,
229
+ "customer_id": 1,
230
+ "month": "2026-04",
231
+ "revenue": 10000,
232
+ "status": "paid"
233
+ },
234
+ {
235
+ "id": 3,
236
+ "customer_id": 2,
237
+ "month": "2026-03",
238
+ "revenue": 8000,
239
+ "status": "paid"
240
+ },
241
+ {
242
+ "id": 4,
243
+ "customer_id": 2,
244
+ "month": "2026-04",
245
+ "revenue": 8000,
246
+ "status": "paid"
247
+ },
248
+ {
249
+ "id": 5,
250
+ "customer_id": 3,
251
+ "month": "2026-04",
252
+ "revenue": 3500,
253
+ "status": "open"
254
+ },
255
+ {
256
+ "id": 6,
257
+ "customer_id": 4,
258
+ "month": "2026-03",
259
+ "revenue": 5000,
260
+ "status": "paid"
261
+ },
262
+ {
263
+ "id": 7,
264
+ "customer_id": 5,
265
+ "month": "2026-04",
266
+ "revenue": 1500,
267
+ "status": "open"
268
+ }
269
+ ],
270
+ "normalized_candidate_rows": [
271
+ {
272
+ "id": 1,
273
+ "customer_id": 1,
274
+ "month": "2026-03",
275
+ "revenue": 10000,
276
+ "status": "paid"
277
+ },
278
+ {
279
+ "id": 2,
280
+ "customer_id": 1,
281
+ "month": "2026-04",
282
+ "revenue": 10000,
283
+ "status": "paid"
284
+ },
285
+ {
286
+ "id": 3,
287
+ "customer_id": 2,
288
+ "month": "2026-03",
289
+ "revenue": 8000,
290
+ "status": "paid"
291
+ },
292
+ {
293
+ "id": 4,
294
+ "customer_id": 2,
295
+ "month": "2026-04",
296
+ "revenue": 8000,
297
+ "status": "paid"
298
+ },
299
+ {
300
+ "id": 5,
301
+ "customer_id": 3,
302
+ "month": "2026-04",
303
+ "revenue": 3500,
304
+ "status": "open"
305
+ },
306
+ {
307
+ "id": 6,
308
+ "customer_id": 4,
309
+ "month": "2026-03",
310
+ "revenue": 5000,
311
+ "status": "paid"
312
+ },
313
+ {
314
+ "id": 7,
315
+ "customer_id": 5,
316
+ "month": "2026-04",
317
+ "revenue": 1500,
318
+ "status": "open"
319
+ }
320
+ ]
321
+ },
322
+ "timings": {
323
+ "generate_ms": 0,
324
+ "validate_ms": 0,
325
+ "repair_ms": 0,
326
+ "execute_ms": 0,
327
+ "gold_execute_ms": 0,
328
+ "compare_ms": 0,
329
+ "total_ms": 2
330
+ },
331
+ "token_usage": null,
332
+ "estimated_cost_usd": null,
333
+ "tags": [
334
+ "listing"
335
+ ],
336
+ "error": null,
337
+ "traceback": null
338
+ }
339
+ ]
340
+ }
@@ -0,0 +1,54 @@
1
+ name: Bug report
2
+ description: Something in QueryPilot doesn't behave as documented
3
+ labels: [bug]
4
+ body:
5
+ - type: textarea
6
+ id: what-happened
7
+ attributes:
8
+ label: What happened?
9
+ description: A clear description of the bug.
10
+ placeholder: The validator accepted ... / `querypilot eval run` crashed with ...
11
+ validations:
12
+ required: true
13
+
14
+ - type: textarea
15
+ id: repro
16
+ attributes:
17
+ label: Minimal reproduction
18
+ description: The smallest code snippet, SQL statement, or CLI invocation that triggers it.
19
+ render: python
20
+ validations:
21
+ required: true
22
+
23
+ - type: textarea
24
+ id: expected
25
+ attributes:
26
+ label: Expected behavior
27
+ validations:
28
+ required: true
29
+
30
+ - type: input
31
+ id: version
32
+ attributes:
33
+ label: QueryPilot version
34
+ placeholder: "0.1.0"
35
+ validations:
36
+ required: true
37
+
38
+ - type: input
39
+ id: python
40
+ attributes:
41
+ label: Python version
42
+ placeholder: "3.12"
43
+
44
+ - type: input
45
+ id: database
46
+ attributes:
47
+ label: Database / dialect
48
+ placeholder: sqlite / postgres 16
49
+
50
+ - type: textarea
51
+ id: logs
52
+ attributes:
53
+ label: Logs, traceback, or eval report output
54
+ render: text
@@ -0,0 +1,5 @@
1
+ blank_issues_enabled: true
2
+ contact_links:
3
+ - name: Security vulnerability
4
+ url: https://github.com/nickklos10/QueryPilot/security/advisories/new
5
+ about: Please report security issues privately, not as public issues.
@@ -0,0 +1,38 @@
1
+ name: Feature request
2
+ description: Propose an improvement or new capability
3
+ labels: [enhancement]
4
+ body:
5
+ - type: textarea
6
+ id: problem
7
+ attributes:
8
+ label: Problem
9
+ description: What are you trying to do that QueryPilot doesn't support today?
10
+ validations:
11
+ required: true
12
+
13
+ - type: textarea
14
+ id: proposal
15
+ attributes:
16
+ label: Proposed solution
17
+ validations:
18
+ required: true
19
+
20
+ - type: textarea
21
+ id: alternatives
22
+ attributes:
23
+ label: Alternatives considered
24
+
25
+ - type: dropdown
26
+ id: area
27
+ attributes:
28
+ label: Area
29
+ options:
30
+ - Safety engine / validation
31
+ - Eval harness
32
+ - Connectors
33
+ - Access control
34
+ - Audit trail
35
+ - MCP server
36
+ - FastAPI server
37
+ - LLM generation
38
+ - Other
@@ -0,0 +1,20 @@
1
+ ## Summary
2
+
3
+ <!-- What does this PR change and why? One PR per logical change. -->
4
+
5
+ ## Changes
6
+
7
+ -
8
+
9
+ ## Testing
10
+
11
+ - [ ] `pytest` passes locally
12
+ - [ ] New behavior has a unit test
13
+ - [ ] Validator/safety changes include a safety-suite case (`suites/safety.yaml`)
14
+ - [ ] User-facing CLI changes have a CLI test
15
+ - [ ] `CHANGELOG.md` updated under `[Unreleased]`
16
+ - [ ] Eval baseline regenerated in this PR if pass/safety/correctness rates deliberately changed
17
+
18
+ ## Linked issues
19
+
20
+ <!-- Closes #... -->
@@ -0,0 +1,71 @@
1
+ name: eval
2
+
3
+ on:
4
+ pull_request:
5
+ push:
6
+ branches: [main]
7
+
8
+ jobs:
9
+ lint:
10
+ runs-on: ubuntu-latest
11
+ steps:
12
+ - uses: actions/checkout@v4
13
+
14
+ - name: Set up Python
15
+ uses: actions/setup-python@v5
16
+ with:
17
+ python-version: "3.12"
18
+ cache: pip
19
+
20
+ - name: Install ruff
21
+ run: pip install ruff
22
+
23
+ - name: Ruff check
24
+ run: ruff check src tests
25
+
26
+ eval:
27
+ runs-on: ubuntu-latest
28
+ strategy:
29
+ fail-fast: false
30
+ matrix:
31
+ python-version: ["3.11", "3.12", "3.13"]
32
+ steps:
33
+ - uses: actions/checkout@v4
34
+
35
+ - name: Set up Python ${{ matrix.python-version }}
36
+ uses: actions/setup-python@v5
37
+ with:
38
+ python-version: ${{ matrix.python-version }}
39
+ cache: pip
40
+
41
+ - name: Install package
42
+ run: pip install -e ".[dev,eval]"
43
+
44
+ - name: Seed demo fixture
45
+ run: python tests/fixtures/seed_demo.py
46
+
47
+ - name: Run unit tests
48
+ run: pytest
49
+
50
+ - name: Run smoke eval suite
51
+ run: |
52
+ querypilot eval run \
53
+ --suite suites/smoke.yaml \
54
+ --generator demo \
55
+ --report eval-out.json \
56
+ --no-color
57
+
58
+ - name: Check eval report against baseline
59
+ run: |
60
+ querypilot eval check \
61
+ --report eval-out.json \
62
+ --baseline .eval/baseline.json \
63
+ --threshold 0.9 \
64
+ --require-safety 1.0
65
+
66
+ - name: Upload eval report
67
+ if: always()
68
+ uses: actions/upload-artifact@v4
69
+ with:
70
+ name: eval-report-py${{ matrix.python-version }}
71
+ path: eval-out.json
@@ -0,0 +1,46 @@
1
+ name: release
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+
7
+ permissions:
8
+ contents: read
9
+
10
+ jobs:
11
+ build:
12
+ runs-on: ubuntu-latest
13
+ steps:
14
+ - uses: actions/checkout@v4
15
+
16
+ - name: Set up Python
17
+ uses: actions/setup-python@v5
18
+ with:
19
+ python-version: "3.12"
20
+
21
+ - name: Build distributions
22
+ run: |
23
+ pip install build
24
+ python -m build
25
+
26
+ - uses: actions/upload-artifact@v4
27
+ with:
28
+ name: dist
29
+ path: dist/
30
+
31
+ publish:
32
+ needs: build
33
+ runs-on: ubuntu-latest
34
+ environment:
35
+ name: pypi
36
+ url: https://pypi.org/p/querypilot
37
+ permissions:
38
+ id-token: write
39
+ steps:
40
+ - uses: actions/download-artifact@v4
41
+ with:
42
+ name: dist
43
+ path: dist/
44
+
45
+ - name: Publish to PyPI
46
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,7 @@
1
+ .venv/
2
+ .pytest_cache/
3
+ __pycache__/
4
+ *.py[cod]
5
+ *.egg-info/
6
+ dist/
7
+ build/
@@ -0,0 +1,87 @@
1
+ # Changelog
2
+
3
+ All notable changes to QueryPilot are documented here. The format follows
4
+ [Keep a Changelog](https://keepachangelog.com/en/1.1.0/) and the project
5
+ follows [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
6
+
7
+ ## [Unreleased]
8
+
9
+ ### Added
10
+
11
+ - `SECURITY.md` security policy, Contributor Covenant code of conduct, issue
12
+ templates, and a pull-request template.
13
+ - PyPI release workflow (`.github/workflows/release.yml`) using trusted
14
+ publishing, triggered by publishing a GitHub Release.
15
+
16
+ ### Changed
17
+
18
+ - CI now tests Python 3.11, 3.12, and 3.13 and runs `ruff check` as a
19
+ separate lint job.
20
+
21
+ ### Removed
22
+
23
+ - Internal planning documents from `docs/`.
24
+
25
+ ## [0.1.0] - 2026-04-28
26
+
27
+ Initial public release. Foundation and eval-driven harness shipped.
28
+
29
+ ### Added — Safety engine
30
+
31
+ - sqlglot-based SQL validation with single-statement and SELECT-only
32
+ enforcement, blocked-keyword filter, table/column allowlist + blocklist,
33
+ Cartesian-join detection, automatic `LIMIT` injection and max-row capping,
34
+ `SELECT *` policy, query fingerprinting, and risk-level scoring.
35
+ - SQLite and PostgreSQL connectors with per-dialect read-only execution and
36
+ query timeouts.
37
+
38
+ ### Added — Audit & access control
39
+
40
+ - Structured audit trail: `QueryAuditRecord` with audit ID, original SQL,
41
+ rewritten SQL, validation result, applied access policy, row count, and
42
+ execution timing.
43
+ - `InMemoryAuditSink` and `JSONLAuditSink` implementations.
44
+ - Access-control policies: column allowlist + blocklist, row-filter injection
45
+ ANDed into WHERE, post-execution column masking (redact / null / hash).
46
+
47
+ ### Added — Runtimes
48
+
49
+ - FastAPI server runtime (`querypilot serve`) with `/health`, `/schema`,
50
+ `/search-schema`, `/ask`, `/generate-sql`, `/validate-sql`, `/execute-sql`,
51
+ `/evals/run`, and `/audit/recent` endpoints.
52
+ - MCP server runtime (`querypilot mcp`) over stdio and Streamable HTTP with
53
+ `ask_database`, `search_schema`, `validate_sql`, and `execute_sql` tools.
54
+
55
+ ### Added — Generation
56
+
57
+ - `DemoSQLGenerator` (offline, deterministic) plus `OpenAISQLGenerator` and
58
+ `AnthropicSQLGenerator` provider implementations with a validator-driven
59
+ repair loop.
60
+ - Tool-schema producers `as_openai_tools()` and `as_anthropic_tools()` for
61
+ drop-in agent use.
62
+
63
+ ### Added — Eval-driven harness
64
+
65
+ - `BenchmarkCase` / `BenchmarkSuite` Pydantic schema with thresholds,
66
+ comparison config, and tags. YAML and JSON suite loaders with shared-config
67
+ validation across multi-file suite directories.
68
+ - Result-set comparator with column- and row-order normalization,
69
+ abs-difference float tolerance, datetime ISO normalization, NaN handling,
70
+ and structured row diffs.
71
+ - `pipeline.run_case` per-case runner reusing existing `QueryPilot.generate_sql`,
72
+ `validate_sql`, and `execute_sql`; per-stage `time.perf_counter` timings;
73
+ failure classification across 12 categories.
74
+ - Cost trackers for OpenAI and Anthropic (idempotent client wrap with
75
+ restore), `NullCostTracker`, and a `MODEL_PRICING` table.
76
+ - `run_suite` aggregator producing `SuiteReport` with pass / safety /
77
+ correctness / repair rates, p50/p95 latency, token totals, $ estimate, tag
78
+ rollups, failure breakdown, and threshold violations.
79
+ - Stdlib JSON writer and screenshot-quality terminal renderer.
80
+ - `querypilot eval run|replay|check|init` CLI with audit-log → regression-
81
+ suite replay, baseline-vs-current regression detection, and a starter
82
+ scaffold for `suites/` and `.eval/`.
83
+ - Sample GitHub Actions workflow at `.github/workflows/eval.yml` running
84
+ `eval run` + `eval check` on every PR.
85
+
86
+ [Unreleased]: https://github.com/nickklos10/QueryPilot/compare/v0.1.0...HEAD
87
+ [0.1.0]: https://github.com/nickklos10/QueryPilot/releases/tag/v0.1.0