Skip to content

feat: Band 3 — Design Quantities and the Simulation MCP Server - #83

Open
tinix84 wants to merge 5 commits into
feat/band2-topology-cache-keyfrom
feat/band3-legible-answers
Open

feat: Band 3 — Design Quantities and the Simulation MCP Server#83
tinix84 wants to merge 5 commits into
feat/band2-topology-cache-keyfrom
feat/band3-legible-answers

Conversation

@tinix84

@tinix84 tinix84 commented Aug 28, 2026

Copy link
Copy Markdown
Owner

Band 3 — the answer is legible

Stacked on #74 (Band 2); merge that first. Specs #75 (Simulation MCP Server, answering #59) and #76 (Design Quantities); tickets #77#82. Decisions: ADR-0011, ADR-0012.

What changes for an engineer

  • Column 5 — read the meaning. pyplecs.quantities turns a Simulation Result into Design Quantities on demand: named waveforms over the last N complete switching periods, per-component stress (time-weighted mean/RMS with exact piecewise-linear integration, peak, min/max, peak-to-peak, max slew rate) and a power balance (efficiency, total loss, per-component loss, unattributed remainder). Roles come from a caller-declared Signal Map; nothing is inferred from names and nothing is written to the Cache Record. Reachable from Python, POST /simulations/{task_id}/quantities, and the simulation_quantities MCP tool — identical payloads.
  • Column 6 — work where they already work. pyplecs-mcp-sim is the Simulation MCP Server: simulation_submit/_status/_wait/_result/_cancel/_list, cache_lookup/_invalidate, models_list, simulation_quantities, over stdio submit/poll with opaque ids. PLECS unreachable → explicit tool error at submission, no task created, every other tool still answers. The docs server pyplecs-mcp is untouched and asserted frozen.
  • LivePlecsAdapter routes whole Simulation Requests to PLECS one model session per model file; the orchestrator's seam accepts any adapter offering simulate_requests.

Commits

  1. style: sort an import block the current ruff flags (pre-push gate).
  2. feat(quantities): Design Quantities + CONTEXT terms + ADR-0011/0012 + README rows.
  3. feat(mcp): Simulation MCP Server core; async-aware, typed ToolCatalogue.
  4. feat: cache/model tools, live PLECS adapter, quantities over REST/MCP.

Evidence

  • Closed-form checks on a non-uniform grid: constant, ramp (A/√3), square (A·D, A·√D), sine (A/√2); lossless fixture → η = 1, unattributed 0; declared resistive drop attributed exactly.
  • Submit→wait→result round trip, cache hit without a second adapter call, failed result as data, unavailable PLECS, cancel, validation, disjoint tool names, entry point registered; live adapter groups by model file against a fake PlecsServer.
  • Gate: ruff, vulture, structure check, 208 passed across the platform-independent set.

Review (two-axis /code-review, since 4f6e56d)

Fixed in commit 5: silent drop of one-legged components from loss attribution (now unattributable_components), PlecsRequestPort protocol instead of a hasattr probe, per-file failure capture in models_list and no recursive flag, middle-man create_simulation_mcp_server removed, TIME_COLUMN, "metric" wording, pyproject line-ending churn, missing non-completed→400 test. Spec text amended on #76 (exact piecewise-linear integration, non-decreasing time axis, interpolated window start, zero-power error). Kept deliberately: README reflow (the 150-line cap), the third time+signals serializer (unifying api/tas.py/simulation_sync.py is #46's concern), priority in the task snapshot.

Still owed / not in this PR

Closes #77, closes #78, closes #79, closes #80, closes #81, closes #82, closes #24, closes #52.

🤖 Generated with Claude Code

tinix84 and others added 4 commits August 28, 2026 19:36
ruff I001 on the current lock's ruff; the pre-push gate requires a clean run.

Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Waveform capture over a deterministic steady-state window (last N complete
periods of the declared switching frequency, start interpolated), per-component
stress (time-weighted mean/RMS with exact piecewise-linear integration, peak,
min/max, peak-to-peak, max slew rate) and a power balance (efficiency, total
loss, per-component loss, unattributed remainder) — all pure functions of one
Simulation Result and a caller-declared Signal Map. Nothing is inferred from
signal names and nothing is written to the Cache Record (ADR-0012).

Also records ADR-0011 (Simulation MCP Server as a second server), adds the
Design Quantity and Signal Map terms to CONTEXT.md, and folds two README lines
to stay under the 150-line cap.

Refs: #78, #81, #52, #76
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…ecycle

`pyplecs-mcp-sim` is a second stdio server (ADR-0011) exposing
simulation_submit / _status / _wait / _result / _cancel / _list as a thin
transport over SimulationOrchestrator. Submission is rejected with an explicit
tool error when PLECS is unavailable and no Simulation Task is created; every
other tool keeps answering. A failed task is a Simulation Result with
success=false, not a tool error. The result payload is the normalized
time + named signals shape the REST sync route already returns.

The ToolCatalogue learns to await coroutine handlers (dispatch_async, used by
the stdio adapter) and to check object/array/number/boolean/enum/range
arguments locally; the docs server's eight tools and sync dispatch are
unchanged and asserted frozen.

Refs: #77, #24, #75
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…s over MCP/REST

- Simulation MCP Server gains cache_lookup / cache_invalidate (the cache's own
  explain_miss names the differing Cache Key id), models_list (offline, via the
  Circuit Model parser) and simulation_quantities.
- LivePlecsAdapter routes whole Simulation Requests to PLECS one model session
  per model file with a real XML-RPC reachability probe; the orchestrator now
  accepts any adapter offering simulate_requests, and pyplecs-mcp-sim is wired
  to it. Live runs against installed PLECS remain owed to the Band 4 map #56.
- POST /simulations/{task_id}/quantities and the MCP tool share one payload
  helper, so REST, MCP and Python return identical Design Quantities computed
  on demand; the Cache Record is untouched (ADR-0012).

Refs: #79, #80, #82, #24, #52
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
- Name components that cannot be attributed a loss (`unattributable_components`)
  instead of folding them silently into the unattributed remainder.
- `PlecsRequestPort` protocol replaces the hasattr probe; LivePlecsAdapter no
  longer carries a raising `simulate_batch`.
- `models_list`: any per-file failure is reported per file; drop the
  unrequested `recursive` flag.
- Drop the `create_simulation_mcp_server` middle man so importing pyplecs.mcp
  no longer imports the live adapter; use TIME_COLUMN; "metric" wording.
- Restore LF on the pyproject script lines; test the non-completed → 400 path.

Refs: #83
Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant