Commit 952ee90
authored
feat(py/tools): add conform CLI with multi-runtime support (#4593)
## Summary
Refactors the parallel conformance runner into a dedicated private package (`conform`) with a clean module architecture and `asyncio.Queue` worker pool for parallel execution.
<img width="1364" height="776" alt="Screenshot 2026-02-11 at 2 33 49 PM" src="https://github.com/user-attachments/assets/12beabb3-ad99-4cd0-808b-ff3d167dd548" />
<img width="1081" height="473" alt="Screenshot 2026-02-11 at 2 34 28 PM" src="https://github.com/user-attachments/assets/37b3dd6d-031f-4113-9cfc-70edfcc5ece1" />
### Subcommands
| Command | Purpose |
|---------|---------|
| `conform check-model [PLUGIN...] [--all] [-j N] [-v] [--runtime NAME]` | Run model conformance tests in parallel |
| `conform check-plugin` | Lint-time check that plugins have conformance files |
| `conform list` | Show plugins and env-var readiness |
### Key changes
- **Module architecture** — `types.py` contains shared types (Status, PluginResult, Runtime Protocol) to eliminate circular imports
- **Runtime Protocol** — abstracts runtime differences (Python, JS, Go) behind a Protocol; configurable via `[tool.conform.runtimes.*]` in pyproject.toml
- **asyncio.Queue worker pool** — natural backpressure instead of semaphore; N workers pull from the queue
- **Error log** — Rich Panels showing last 15 lines per failure (full with `-v`)
- **CLI polish** — yellow section headers, cyan args via rich-argparse; bare `conform` shows help + env-var table
- **MkDocs eng docs** — Material theme (blue), covers architecture, usage, config, multi-runtime
- **py/bin/conform** — wrapper script for convenience
- **Blocking I/O audit** — all async paths verified safe
- **Releasekit fixes** — added `conform` to `internal_tools` group (fixes ungrouped_packages and publish_classifier_consistency warnings); added Changelog URL to genkit `pyproject.toml`
### Conformance test results
Running `genkit dev:test-model` directly for `google-genai` with credentials:
| Model | Tests | Result |
|-------|-------|--------|
| `gemini-2.5-flash` | Tool Request, Structured Output, Multiturn, System Role, Image Base64, Image URL, Video YouTube | **7/7 ✅** |
| `gemini-2.5-pro` | All 7 tests | 0/7 ❌ (aborted — race condition) |
| `gemini-3-pro-preview` | All 10 tests | 0/10 ❌ (aborted — race condition) |
| `imagen-4.0-generate-001` | Image Output | 0/1 ❌ (aborted — race condition) |
| `gemini-2.5-flash-preview-tts` | TTS | 0/1 ❌ (aborted — race condition) |
**Summary: 7 passed, 19 failed** — All 7 `gemini-2.5-flash` tests pass. The 19 failures are all "aborted" due to a **genkit CLI race condition**: `genkit dev:test-model` dispatches test requests for models before the Python reflection server has finished registering their actions, causing 404s on `/api/runAction`. The last model in the sequence (`gemini-2.5-flash`) passes because the server is fully ready by then.
### Known upstream issues (not addressed in this PR)
1. **`_base_async.py` graceful shutdown** — The `dev_runner` raises `RuntimeError: User coroutine finished without a result.` when SIGTERM cancels a conformance entry point. This is a core framework bug that needs a separate PR. It doesn't affect test correctness but produces noisy tracebacks on shutdown.
2. **Genkit CLI action discovery race** — `genkit dev:test-model` starts testing models before the Python runtime has registered all actions with the reflection server. Models tested early get 404s and are marked "aborted". This is a timing issue in the Node.js CLI, not the Python SDK.
### Lint status
`bin/lint` passes with 0 errors.1 parent 4f5a910 commit 952ee90
File tree
63 files changed
+3210
-183
lines changed- py
- bin
- engdoc
- tests/conform
- amazon-bedrock
- anthropic
- cloudflare-workers-ai
- cohere
- compat-oai
- deepseek
- google-genai
- huggingface
- microsoft-foundry
- mistral
- ollama
- vertex-ai
- xai
- tools/conform
- docs
- src/conform
Some content is hidden
Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.
63 files changed
+3210
-183
lines changed| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
34 | 34 | | |
35 | 35 | | |
36 | 36 | | |
| 37 | + | |
37 | 38 | | |
38 | 39 | | |
39 | 40 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
38 | 38 | | |
39 | 39 | | |
40 | 40 | | |
| 41 | + | |
| 42 | + | |
41 | 43 | | |
42 | 44 | | |
43 | 45 | | |
| |||
59 | 61 | | |
60 | 62 | | |
61 | 63 | | |
62 | | - | |
| 64 | + | |
63 | 65 | | |
64 | 66 | | |
65 | 67 | | |
| |||
675 | 677 | | |
676 | 678 | | |
677 | 679 | | |
| 680 | + | |
| 681 | + | |
| 682 | + | |
| 683 | + | |
| 684 | + | |
| 685 | + | |
| 686 | + | |
| 687 | + | |
| 688 | + | |
| 689 | + | |
| 690 | + | |
| 691 | + | |
678 | 692 | | |
679 | 693 | | |
680 | 694 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
| 1 | + | |
| 2 | + | |
| 3 | + | |
| 4 | + | |
| 5 | + | |
| 6 | + | |
| 7 | + | |
| 8 | + | |
| 9 | + | |
| 10 | + | |
| 11 | + | |
| 12 | + | |
| 13 | + | |
| 14 | + | |
| 15 | + | |
| 16 | + | |
| 17 | + | |
| 18 | + | |
| 19 | + | |
| 20 | + | |
| 21 | + | |
| 22 | + | |
| 23 | + | |
| 24 | + | |
| 25 | + | |
| 26 | + | |
| 27 | + | |
| 28 | + | |
| 29 | + | |
| 30 | + | |
| 31 | + | |
This file was deleted.
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
187 | 187 | | |
188 | 188 | | |
189 | 189 | | |
| 190 | + | |
| 191 | + | |
| 192 | + | |
| 193 | + | |
| 194 | + | |
| 195 | + | |
| 196 | + | |
| 197 | + | |
| 198 | + | |
| 199 | + | |
| 200 | + | |
| 201 | + | |
| 202 | + | |
| 203 | + | |
| 204 | + | |
| 205 | + | |
| 206 | + | |
| 207 | + | |
190 | 208 | | |
191 | 209 | | |
192 | 210 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
136 | 136 | | |
137 | 137 | | |
138 | 138 | | |
139 | | - | |
| 139 | + | |
140 | 140 | | |
141 | | - | |
| 141 | + | |
| 142 | + | |
| 143 | + | |
| 144 | + | |
| 145 | + | |
| 146 | + | |
| 147 | + | |
| 148 | + | |
| 149 | + | |
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
42 | 42 | | |
43 | 43 | | |
44 | 44 | | |
| 45 | + | |
| 46 | + | |
45 | 47 | | |
46 | 48 | | |
47 | 49 | | |
| |||
233 | 235 | | |
234 | 236 | | |
235 | 237 | | |
| 238 | + | |
| 239 | + | |
236 | 240 | | |
237 | 241 | | |
238 | 242 | | |
239 | | - | |
| 243 | + | |
240 | 244 | | |
241 | 245 | | |
242 | 246 | | |
| |||
453 | 457 | | |
454 | 458 | | |
455 | 459 | | |
| 460 | + | |
456 | 461 | | |
457 | 462 | | |
458 | 463 | | |
| |||
499 | 504 | | |
500 | 505 | | |
501 | 506 | | |
| 507 | + | |
502 | 508 | | |
503 | 509 | | |
504 | 510 | | |
| |||
547 | 553 | | |
548 | 554 | | |
549 | 555 | | |
| 556 | + | |
550 | 557 | | |
551 | 558 | | |
552 | 559 | | |
| |||
563 | 570 | | |
564 | 571 | | |
565 | 572 | | |
| 573 | + | |
566 | 574 | | |
567 | 575 | | |
568 | 576 | | |
| |||
| Original file line number | Diff line number | Diff line change | |
|---|---|---|---|
| |||
47 | 47 | | |
48 | 48 | | |
49 | 49 | | |
50 | | - | |
| 50 | + | |
51 | 51 | | |
52 | 52 | | |
53 | 53 | | |
| |||
0 commit comments