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.
- querypilot-0.1.0/.eval/baseline.json +340 -0
- querypilot-0.1.0/.github/ISSUE_TEMPLATE/bug_report.yml +54 -0
- querypilot-0.1.0/.github/ISSUE_TEMPLATE/config.yml +5 -0
- querypilot-0.1.0/.github/ISSUE_TEMPLATE/feature_request.yml +38 -0
- querypilot-0.1.0/.github/PULL_REQUEST_TEMPLATE.md +20 -0
- querypilot-0.1.0/.github/workflows/eval.yml +71 -0
- querypilot-0.1.0/.github/workflows/release.yml +46 -0
- querypilot-0.1.0/.gitignore +7 -0
- querypilot-0.1.0/CHANGELOG.md +87 -0
- querypilot-0.1.0/CODE_OF_CONDUCT.md +134 -0
- querypilot-0.1.0/CONTRIBUTING.md +67 -0
- querypilot-0.1.0/LICENSE +21 -0
- querypilot-0.1.0/PKG-INFO +601 -0
- querypilot-0.1.0/README.md +548 -0
- querypilot-0.1.0/SECURITY.md +39 -0
- querypilot-0.1.0/pyproject.toml +92 -0
- querypilot-0.1.0/src/querypilot/__init__.py +36 -0
- querypilot-0.1.0/src/querypilot/access/__init__.py +3 -0
- querypilot-0.1.0/src/querypilot/access/policy.py +32 -0
- querypilot-0.1.0/src/querypilot/adapters/__init__.py +1 -0
- querypilot-0.1.0/src/querypilot/adapters/anthropic.py +49 -0
- querypilot-0.1.0/src/querypilot/adapters/openai.py +53 -0
- querypilot-0.1.0/src/querypilot/audit/__init__.py +10 -0
- querypilot-0.1.0/src/querypilot/audit/sinks.py +46 -0
- querypilot-0.1.0/src/querypilot/audit/types.py +53 -0
- querypilot-0.1.0/src/querypilot/cli.py +401 -0
- querypilot-0.1.0/src/querypilot/connectors/__init__.py +5 -0
- querypilot-0.1.0/src/querypilot/connectors/base.py +24 -0
- querypilot-0.1.0/src/querypilot/connectors/postgres.py +48 -0
- querypilot-0.1.0/src/querypilot/connectors/sqlite.py +49 -0
- querypilot-0.1.0/src/querypilot/core/__init__.py +1 -0
- querypilot-0.1.0/src/querypilot/core/client.py +286 -0
- querypilot-0.1.0/src/querypilot/core/config.py +29 -0
- querypilot-0.1.0/src/querypilot/core/safety_defaults.py +12 -0
- querypilot-0.1.0/src/querypilot/core/types.py +89 -0
- querypilot-0.1.0/src/querypilot/evals/__init__.py +81 -0
- querypilot-0.1.0/src/querypilot/evals/check.py +222 -0
- querypilot-0.1.0/src/querypilot/evals/compare.py +286 -0
- querypilot-0.1.0/src/querypilot/evals/cost.py +202 -0
- querypilot-0.1.0/src/querypilot/evals/factory.py +83 -0
- querypilot-0.1.0/src/querypilot/evals/init.py +104 -0
- querypilot-0.1.0/src/querypilot/evals/loader.py +179 -0
- querypilot-0.1.0/src/querypilot/evals/pipeline.py +484 -0
- querypilot-0.1.0/src/querypilot/evals/replay.py +217 -0
- querypilot-0.1.0/src/querypilot/evals/report.py +246 -0
- querypilot-0.1.0/src/querypilot/evals/suite.py +91 -0
- querypilot-0.1.0/src/querypilot/evals/suite_runner.py +361 -0
- querypilot-0.1.0/src/querypilot/execution/__init__.py +1 -0
- querypilot-0.1.0/src/querypilot/execution/formatter.py +11 -0
- querypilot-0.1.0/src/querypilot/execution/runner.py +13 -0
- querypilot-0.1.0/src/querypilot/generation/__init__.py +9 -0
- querypilot-0.1.0/src/querypilot/generation/llm.py +180 -0
- querypilot-0.1.0/src/querypilot/generation/prompt_builder.py +49 -0
- querypilot-0.1.0/src/querypilot/generation/sql_generator.py +82 -0
- querypilot-0.1.0/src/querypilot/mcp/__init__.py +3 -0
- querypilot-0.1.0/src/querypilot/mcp/server.py +51 -0
- querypilot-0.1.0/src/querypilot/py.typed +0 -0
- querypilot-0.1.0/src/querypilot/schema/__init__.py +3 -0
- querypilot-0.1.0/src/querypilot/schema/introspector.py +8 -0
- querypilot-0.1.0/src/querypilot/schema/search.py +33 -0
- querypilot-0.1.0/src/querypilot/server/__init__.py +3 -0
- querypilot-0.1.0/src/querypilot/server/app.py +157 -0
- querypilot-0.1.0/src/querypilot/validation/__init__.py +3 -0
- querypilot-0.1.0/src/querypilot/validation/policies.py +3 -0
- querypilot-0.1.0/src/querypilot/validation/validator.py +592 -0
- querypilot-0.1.0/suites/safety.yaml +55 -0
- querypilot-0.1.0/suites/smoke.yaml +45 -0
- querypilot-0.1.0/tests/conftest.py +42 -0
- querypilot-0.1.0/tests/evals/__init__.py +0 -0
- querypilot-0.1.0/tests/evals/test_check.py +338 -0
- querypilot-0.1.0/tests/evals/test_cli.py +550 -0
- querypilot-0.1.0/tests/evals/test_compare.py +449 -0
- querypilot-0.1.0/tests/evals/test_cost.py +314 -0
- querypilot-0.1.0/tests/evals/test_factory.py +140 -0
- querypilot-0.1.0/tests/evals/test_loader.py +464 -0
- querypilot-0.1.0/tests/evals/test_pipeline.py +341 -0
- querypilot-0.1.0/tests/evals/test_replay.py +414 -0
- querypilot-0.1.0/tests/evals/test_report.py +269 -0
- querypilot-0.1.0/tests/evals/test_suite_runner.py +298 -0
- querypilot-0.1.0/tests/fixtures/demo.db +0 -0
- querypilot-0.1.0/tests/fixtures/seed_demo.py +160 -0
- querypilot-0.1.0/tests/test_access_policy.py +187 -0
- querypilot-0.1.0/tests/test_adapters.py +42 -0
- querypilot-0.1.0/tests/test_audit.py +62 -0
- querypilot-0.1.0/tests/test_llm_generation.py +142 -0
- querypilot-0.1.0/tests/test_mcp_runtime.py +74 -0
- querypilot-0.1.0/tests/test_postgres_connector.py +74 -0
- querypilot-0.1.0/tests/test_querypilot_flow.py +38 -0
- querypilot-0.1.0/tests/test_server_runtime.py +129 -0
- querypilot-0.1.0/tests/test_sqlite_connector.py +41 -0
- 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,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,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
|