May 11, 2026
Custom PyBaMM model + Li-S support, ECM capacity co-optimization, default project for the Python SDK, structured validation issues
Custom PyBaMM models with Lithium-Sulfur chemistry
The/models/upload-custom endpoint now accepts a chemistry field (defaulting
to lithium_ion), and Li-S models get a chemistry-aware initial-state shim
plus tighter IDAKLU tolerances when they run. The manage-projects SDK skill
documents the full upload workflow — pybamm.Serialise().save_custom_model(filename=...)
→ multipart upload → client.model.get(id) returns is_custom_model: true —
including the EventType-not-JSON-serializable gotcha that hits anyone trying
to json.dumps the dict from serialise_custom_model() directly.ECM fit: capacity co-optimization and per-segment initial SoC
Several interlocking improvements to the project-scoped ECM fit. Supplying anocv_soc_curve (and optional bounds_capacity) lets you co-optimize cell
capacity Q jointly with the RC beta knots in the outer least-squares loop
instead of pinning Q to a single seed; on a 25 °C rate-test trace the fitted
capacity now lands within 0.9 % of the coulomb-counting truth across all knot
schedules. initial_soc accepts a list (one entry per measurement) so
multi-measurement fits reset SoC at each segment boundary instead of
integrating coulombs across the gaps; if you omit it, the new auto-seed
routine refines each segment’s soc0 by root-finding
V[s] = OCV(soc0) − I[s]·R0(soc0). num_knots, num_knots_r0,
knot_schedule, and clamp_max_ratio are now first-class parameters on
/fit-from-measurements and /fit-from-file. The boundary clamp default also
loosened from max_ratio=1.0 to 10.0, which was collapsing R0 and triggering
pybamm IDAKLU CONV_FAIL on rate-test forward sims.Default project for the Python SDK
TheIonworks client now resolves a default project_id at construction time
from a project_id= argument or the new IONWORKS_PROJECT_ID environment
variable, so callers no longer have to thread project_id through every call.
The previous PROJECT_ID env var still works but emits a DeprecationWarning.
All client.study.* methods take project_id as an optional keyword
(after the resource ID) defaulting to the client value, and pipelines and
optimizations auto-inject it into payloads.Structured measurement-validation issues
MeasurementValidationError.errors is now list[ValidationIssue] — a frozen
dataclass carrying a stable IssueCode (StrEnum), severity, human-readable
message, and JSON-native payload. Downstream code can branch on check
identity via e.has_code(IssueCode.CURRENT_SIGN_REVERSED) instead of grepping
the message string. ionworksdata’s auto-fix path now keys off the new codes;
IssueCode and ValidationIssue are re-exported from the top-level
ionworks package.Studio
Studio
Improvements
organization_idis nowNOT NULLon ~15 tables, all RLS policies have been rewritten to read it directly (replacing thehas_permission_via_*function chain), and composite(project_id, organization_id)foreign keys prevent org drift on project-scoped tables.- Simulation boards CRUD moved to a proper backend API at
/projects/{project_id}/studies/{study_id}/simulation_boardswithorganization_idresolved server-side, fixing a blank Visualization tab on stage where direct Supabase inserts were silently rejected by the stricter RLS. - Optimization Performance Detail and Performance Summary tabs now surface
buried
validation_warning/validation_not_supportedissues as top-level alerts above the tabs, with info “no data” alerts inside the tabs for the rare empty-but-valid case. - Defensive UX in the Visualization tab: the Data/Visualization toggle stays visible even when no board is available, with a warning alert prompting the switch back to Data instead of trapping the user on a blank page.
- The single simulation result page no longer flashes “Simulation not found” before the data loads on a fresh navigation.
Pipeline
Pipeline
Improvements
ionworks-schemagainedConstraint,Penalty,CMAESOptions,PSOOptions,DEOptions,LatinHypercube, andUniformschema classes that pipeline already had, plusField(description=...)enrichment on ~40 pilot-touched classes across objectives, data fits, parameter estimators, regularizers, and distribution samplers. A new Sphinx docs skeleton auto-generates a reference page per submodule and cross-links each schema class to the matchingionworkspipelinepage via intersphinx.
EmptySolutionAttributeError(raised when SUNDIALS gives up at IC for a bad parameter combination) now routes to the existing fit-failure penalty path instead of crashing the whole datafit. Cloud fits stay alive and the offending sample just gets a huge cost.
Python API
Python API
Improvements
- New
client.urls.measurement(measurement_id, project_id)helper returns the web app deep link for a measurement, so callers don’t have to hand-build URLs againstfrontend/src/routes/paths.ts.
Skills
Skills
Improvements
manage-projectsdocuments the/models/upload-custommultipart workflow and the Model / ParameterizedModel disambiguation.upload-dataand other validation-aware skills updated to reference the newIssueCode/ValidationIssueAPI and thee.has_code(...)pattern instead of substring-matching error strings.