Metadata-Version: 2.4
Name: ol-simulator-interop-services
Version: 0.1.1
Summary: Canonical thermodynamics interop domain models and simulator adapter protocol.
Project-URL: Homepage, https://github.com/OntoLedgy/ol_simulator_interop_services
Project-URL: Source, https://github.com/OntoLedgy/ol_simulator_interop_services
Project-URL: Issues, https://github.com/OntoLedgy/ol_simulator_interop_services/issues
Project-URL: Documentation, https://github.com/OntoLedgy/ol_simulator_interop_services#readme
Author: OntoLedgy
License-Expression: AGPL-3.0-or-later
License-File: LICENSE
License-File: NOTICE
Keywords: cape-open,domain-model,mcp,simulator,thermodynamics
Classifier: Development Status :: 4 - Beta
Classifier: Intended Audience :: Developers
Classifier: Intended Audience :: Science/Research
Classifier: License :: OSI Approved :: GNU Affero General Public License v3 or later (AGPLv3+)
Classifier: Operating System :: OS Independent
Classifier: Programming Language :: Python :: 3
Classifier: Programming Language :: Python :: 3.11
Classifier: Programming Language :: Python :: 3.12
Classifier: Topic :: Scientific/Engineering :: Chemistry
Classifier: Topic :: Software Development :: Libraries
Classifier: Typing :: Typed
Requires-Python: >=3.11
Requires-Dist: pydantic<3.0,>=2.0
Description-Content-Type: text/markdown

<!--
SPDX-FileCopyrightText: 2018-2026 OntoLedgy Ltd.

This file is part of the OntoLedgy Thermodynamics Architecture and is
dual-licensed:

  1. Open source under the GNU Affero General Public License v3.0 or
     later (AGPL-3.0-or-later). See the LICENSE file in the repository
     root for the full licence text and NOTICE for attribution.
  2. Commercial under a separate proprietary licence offered by
     OntoLedgy Ltd. See COMMERCIAL.md for terms and contact details.

SPDX-License-Identifier: AGPL-3.0-or-later
-->

# ol-simulator-interop-services

The canonical domain model and adapter contract layer for the Thermodynamics Agent Service architecture. Defines the types, protocols, and registries that every simulator backend (DWSIM, Rust thermo kernel, HYSYS, UniSim, ...) implements against. Licensed under **AGPL-3.0-or-later**.

This package is **pure Python, backend-agnostic, and cross-platform**. It's the port in a hexagonal (ports-and-adapters) architecture; simulator-specific implementations are the adapters.

---

## Install

```bash
pip install ol-simulator-interop-services
```

Python 3.11+ only. The sole runtime dependency is `pydantic>=2.0,<3.0`.

---

## Role in the architecture

This repository is the **middle layer**:

```
LLM agent / MCP client
        |
        v
+--[ ol_thermodynamics_agent_services ]--+
|   MCP tools, routing, provenance       |
+----------------------------------------+
        |
        v  (in-process Python call)
+--[ ol_simulator_interop_services ]-----+   <-- this repo
|   canonical domain model + protocol    |
+----------------------------------------+
        |
   +----+----+----------+---------+
   v         v          v         v
 [Rust]   [DWSIM]   [HYSYS]   [UniSim]
 kernel   adapter   adapter    adapter
```

Backend-agnostic by design. No simulator's types leak above this boundary — a request arrives as a canonical `FlashProblem`, is dispatched to whichever adapter is registered, and returns a canonical `FlashResult`.

---

## Responsibilities

- **Canonical domain model** — architectural type commitments that all layers depend on (table below).
- **`SimulatorAdapter` protocol** — the Python [`Protocol`](https://docs.python.org/3/library/typing.html#typing.Protocol) every simulator adapter must implement. Canonical methods: `flash`, `get_properties`, `phase_envelope`, `list_property_packages`, `list_components`, `introspect_property_package`.
- **Component registry** — CAS-keyed canonical component identity with per-backend alias tables (`InMemoryComponentRegistry`).
- **Parameter-source registry** — tracking of each backend's parameter databank and its revision (`InMemoryParameterSourceRegistry`).
- **Property-package registry** — model + parameter-source + revision triples (`InMemoryPropertyPackageRegistry`).
- **Error ontology** — uniform exception types across all backends (`AdapterCapabilityError`, `ComponentNotFoundError`, etc.).

---

## Canonical domain model

| Type | Purpose |
|---|---|
| `CanonicalComponent` | Identity by CAS number + canonicalised molecular formula. |
| `CanonicalComponentRef` | Lightweight reference to a registered `CanonicalComponent`. |
| `Composition` | Ordered list of `(CanonicalComponentRef, MoleFraction)`; normalisation invariant enforced at construction. |
| `PropertyPackageSpec` | Triple of `(model_id, parameter_source_id, revision)`. |
| `PropertyPackageDescriptor` | Registered package: spec + display name + supported flash-calculation types. |
| `StreamCondition` | Sum type — `TemperaturePressureCondition`, `PressureEnthalpyCondition`, `PressureEntropyCondition`, etc. |
| `FlashProblem` | Immutable `(Composition, StreamCondition, PropertyPackageSpec)` value object. |
| `FlashResult` | Ordered list of `Phase`, convergence metadata, provenance. |
| `Phase` | Stable identity derived from composition + phase kind + density. |
| `PropertyBundle` | Collection of `PropertyValue`s keyed by canonical property ID. |
| `Provenance` | `(backend_id, property_package_spec, wall_time_seconds, ...)` attached to every result. |

`CanonicalComponent` and `PropertyPackageSpec` follow the BIE identity pattern: canonical identity surfaces above, per-backend projections and parameter-source governance below.

---

## Communication boundaries

| Boundary | Transport | Rationale |
|---|---|---|
| Agent service → this service | In-process Python call | Same process; no network boundary needed. |
| This service → adapters | Python protocol (in-process) | Adapters are Python classes loaded at startup. |
| Adapter → backend engine | Adapter-local (pythonnet, HTTP, PyO3, ...) | Each adapter chooses its own transport. |

---

## Development

### Setup

```bash
git clone https://github.com/OntoLedgy/ol_simulator_interop_services.git
cd ol_simulator_interop_services
uv sync
```

### Tests + lint + types

```bash
uv run pytest          # 22 tests
uv run ruff check .
uv run mypy
```

CI (see `.github/workflows/ci.yml`) runs all three on push/PR to `main` across Python 3.11 and 3.12.

### Release

Releases publish to PyPI via OIDC trusted publishing — no token secrets in this repo. To cut a release:

1. Bump `project.version` in `pyproject.toml` (committed).
2. Tag `vX.Y.Z` matching that version.
3. Push the tag. The `release.yml` workflow builds sdist + wheel, publishes to PyPI, and creates a GitHub Release with both artifacts.

---

## Related repositories

| Repository | Layer | Role |
|---|---|---|
| [`ol_thermodynamics_agent_services`](https://github.com/OntoLedgy/ol_thermodynamics_agent_services) | Agent (top) | MCP tool schemas, backend routing, provenance |
| [`ol_dwsim_interop_services`](https://github.com/OntoLedgy/ol_dwsim_interop_services) | Adapter | DWSIM `SimulatorAdapter` implementation |
| `ol_thermodynamics_kernel` *(planned)* | Adapter | Native Rust thermo kernel via PyO3 |

---

## License

Dual-licensed:

1. **Open source** — **AGPL-3.0-or-later**. See [LICENSE](LICENSE) for the full text and [NOTICE](NOTICE) for attribution.
2. **Commercial** — a separate proprietary license is available from OntoLedgy Ltd. for embedding, proprietary `SimulatorAdapter` implementations, or other use cases that don't fit AGPL terms. See [COMMERCIAL.md](COMMERCIAL.md).

Copyright (c) 2018-2026 OntoLedgy Ltd.

Although this package is a library rather than a networked service, downstream services that consume it (e.g. `ol-dwsim-mcp-server`) are network-reachable, and AGPL §13 obligations propagate when those services are hosted. Using this package under the AGPL option means accepting the same AGPL terms across the dependency chain.
