diff --git a/CHANGELOG.md b/CHANGELOG.md index 51210bc..cb3fe19 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,37 @@ For auto-generated release notes, see [GitHub Releases](https://github.com/DataV (Empty — next-cycle work lands here.) +## [1.5.0] - 2026-05-13 + +Pyodide / Cloudflare Python Workers consumers can now import +``synth_panel.ensemble`` without dragging ``ThreadPoolExecutor`` into +the load chain. Boardroom (and any other Workers-style consumer that +adopts ``synthesize_panel``) is unblocked: the ensemble surface is +fully threadpool-free at load time, so transitively-bound ``.submit()`` +calls can no longer deadlock the Worker runtime. + +### Changed + +- **Lazy threading imports across the ensemble load chain (sy-2wa).** + ``synth_panel.orchestrator``, ``synth_panel.synthesis``, and + ``synth_panel.perturbation`` no longer bind ``ThreadPoolExecutor`` / + ``as_completed`` / ``threading`` at module top. The imports are + hoisted into the threaded entry points (``run_panel_parallel``, + ``synthesize_panel_mapreduce``, ``generate_panel_variants_parallel``, + ``WorkerRegistry.__init__``) so ``from synth_panel.ensemble import + synthesize_panel`` never touches ``concurrent.futures``. Boardroom's + 22 s ``asyncio.wait_for`` fallback around ``synthesize_panel`` (PR #11) + can now be removed (or kept as defense-in-depth). + +### Added + +- **``tests/test_threadpool_lazy_import.py`` (sy-2wa).** CI test that + asserts ``concurrent.futures`` stays out of ``sys.modules`` after a + fresh ``synth_panel.ensemble`` load, runs the same import against a + poisoned ``concurrent.futures`` (any access raises), and pins the + ``orchestrator`` / ``synthesis`` / ``perturbation`` module namespaces + as ``ThreadPoolExecutor``-free. + ## [1.4.0] - 2026-05-12 OpenRouter cost actuals are now surfaced explicitly alongside the local diff --git a/site/.well-known/mcp/server-card.json b/site/.well-known/mcp/server-card.json index 5c68611..5660000 100644 --- a/site/.well-known/mcp/server-card.json +++ b/site/.well-known/mcp/server-card.json @@ -3,7 +3,7 @@ "name": "io.github.DataViking-Tech/synthpanel", "title": "SynthPanel", "description": "Run synthetic focus groups using AI personas. 12 MCP tools for single prompts, full panel runs, and v3 branching (adaptive) instruments across any LLM provider (Claude, OpenAI, Gemini, xAI).", - "version": "1.4.0", + "version": "1.5.0", "websiteUrl": "https://synthpanel.dev", "repository": { "url": "https://github.com/DataViking-Tech/SynthPanel", @@ -11,7 +11,7 @@ }, "serverInfo": { "name": "synthpanel", - "version": "1.4.0" + "version": "1.5.0" }, "capabilities": { "tools": { "listChanged": false }, @@ -23,7 +23,7 @@ "registryType": "pypi", "registryBaseUrl": "https://pypi.org", "identifier": "synthpanel", - "version": "1.4.0", + "version": "1.5.0", "runtimeHint": "uvx", "runtimeArguments": [ { "type": "positional", "value": "synthpanel[mcp]" }, diff --git a/site/index.html b/site/index.html index 08722d0..803143c 100644 --- a/site/index.html +++ b/site/index.html @@ -45,8 +45,8 @@ "applicationCategory": "DeveloperApplication", "applicationSubCategory": "Research Tool", "operatingSystem": "Cross-platform", - "softwareVersion": "1.4.0", - "dateModified": "2026-05-12", + "softwareVersion": "1.5.0", + "dateModified": "2026-05-13", "license": "https://opensource.org/licenses/MIT", "codeRepository": "https://github.com/DataViking-Tech/SynthPanel", "downloadUrl": "https://pypi.org/project/synthpanel/", @@ -140,7 +140,7 @@ class="mb-4 inline-flex items-center gap-2 rounded-full border border-emerald-400/30 bg-emerald-400/5 px-3 py-1 text-xs font-medium text-emerald-300" > - v1.4.0 — public beta + v1.5.0 — public beta