marimo-flow 0.4.2__tar.gz → 0.4.4__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {marimo_flow-0.4.2/src/marimo_flow.egg-info → marimo_flow-0.4.4}/PKG-INFO +25 -25
- {marimo_flow-0.4.2 → marimo_flow-0.4.4}/pyproject.toml +31 -31
- {marimo_flow-0.4.2 → marimo_flow-0.4.4}/src/marimo_flow/agents/toolsets/control.py +6 -1
- {marimo_flow-0.4.2 → marimo_flow-0.4.4}/src/marimo_flow/control/heat_rod.py +24 -9
- {marimo_flow-0.4.2 → marimo_flow-0.4.4}/src/marimo_flow/control/mpc.py +39 -6
- {marimo_flow-0.4.2 → marimo_flow-0.4.4/src/marimo_flow.egg-info}/PKG-INFO +25 -25
- marimo_flow-0.4.4/src/marimo_flow.egg-info/requires.txt +39 -0
- marimo_flow-0.4.2/src/marimo_flow.egg-info/requires.txt +0 -39
- {marimo_flow-0.4.2 → marimo_flow-0.4.4}/LICENSE +0 -0
- {marimo_flow-0.4.2 → marimo_flow-0.4.4}/README.md +0 -0
- {marimo_flow-0.4.2 → marimo_flow-0.4.4}/setup.cfg +0 -0
- {marimo_flow-0.4.2 → marimo_flow-0.4.4}/src/marimo_flow/__init__.py +0 -0
- {marimo_flow-0.4.2 → marimo_flow-0.4.4}/src/marimo_flow/agents/__init__.py +0 -0
- {marimo_flow-0.4.2 → marimo_flow-0.4.4}/src/marimo_flow/agents/chat.py +0 -0
- {marimo_flow-0.4.2 → marimo_flow-0.4.4}/src/marimo_flow/agents/deps.py +0 -0
- {marimo_flow-0.4.2 → marimo_flow-0.4.4}/src/marimo_flow/agents/graph.py +0 -0
- {marimo_flow-0.4.2 → marimo_flow-0.4.4}/src/marimo_flow/agents/lead.py +0 -0
- {marimo_flow-0.4.2 → marimo_flow-0.4.4}/src/marimo_flow/agents/mcp.py +0 -0
- {marimo_flow-0.4.2 → marimo_flow-0.4.4}/src/marimo_flow/agents/nodes/__init__.py +0 -0
- {marimo_flow-0.4.2 → marimo_flow-0.4.4}/src/marimo_flow/agents/nodes/mlflow_node.py +0 -0
- {marimo_flow-0.4.2 → marimo_flow-0.4.4}/src/marimo_flow/agents/nodes/model.py +0 -0
- {marimo_flow-0.4.2 → marimo_flow-0.4.4}/src/marimo_flow/agents/nodes/notebook.py +0 -0
- {marimo_flow-0.4.2 → marimo_flow-0.4.4}/src/marimo_flow/agents/nodes/problem.py +0 -0
- {marimo_flow-0.4.2 → marimo_flow-0.4.4}/src/marimo_flow/agents/nodes/route.py +0 -0
- {marimo_flow-0.4.2 → marimo_flow-0.4.4}/src/marimo_flow/agents/nodes/solver.py +0 -0
- {marimo_flow-0.4.2 → marimo_flow-0.4.4}/src/marimo_flow/agents/nodes/training.py +0 -0
- {marimo_flow-0.4.2 → marimo_flow-0.4.4}/src/marimo_flow/agents/nodes/triage.py +0 -0
- {marimo_flow-0.4.2 → marimo_flow-0.4.4}/src/marimo_flow/agents/nodes/validation.py +0 -0
- {marimo_flow-0.4.2 → marimo_flow-0.4.4}/src/marimo_flow/agents/runner.py +0 -0
- {marimo_flow-0.4.2 → marimo_flow-0.4.4}/src/marimo_flow/agents/schemas/__init__.py +0 -0
- {marimo_flow-0.4.2 → marimo_flow-0.4.4}/src/marimo_flow/agents/schemas/artifacts.py +0 -0
- {marimo_flow-0.4.2 → marimo_flow-0.4.4}/src/marimo_flow/agents/schemas/control.py +0 -0
- {marimo_flow-0.4.2 → marimo_flow-0.4.4}/src/marimo_flow/agents/schemas/decisions.py +0 -0
- {marimo_flow-0.4.2 → marimo_flow-0.4.4}/src/marimo_flow/agents/schemas/equation.py +0 -0
- {marimo_flow-0.4.2 → marimo_flow-0.4.4}/src/marimo_flow/agents/schemas/mesh.py +0 -0
- {marimo_flow-0.4.2 → marimo_flow-0.4.4}/src/marimo_flow/agents/schemas/observation.py +0 -0
- {marimo_flow-0.4.2 → marimo_flow-0.4.4}/src/marimo_flow/agents/schemas/optimization.py +0 -0
- {marimo_flow-0.4.2 → marimo_flow-0.4.4}/src/marimo_flow/agents/schemas/preset.py +0 -0
- {marimo_flow-0.4.2 → marimo_flow-0.4.4}/src/marimo_flow/agents/schemas/problem.py +0 -0
- {marimo_flow-0.4.2 → marimo_flow-0.4.4}/src/marimo_flow/agents/schemas/run.py +0 -0
- {marimo_flow-0.4.2 → marimo_flow-0.4.4}/src/marimo_flow/agents/schemas/stochastic.py +0 -0
- {marimo_flow-0.4.2 → marimo_flow-0.4.4}/src/marimo_flow/agents/schemas/task.py +0 -0
- {marimo_flow-0.4.2 → marimo_flow-0.4.4}/src/marimo_flow/agents/server/__init__.py +0 -0
- {marimo_flow-0.4.2 → marimo_flow-0.4.4}/src/marimo_flow/agents/server/a2a.py +0 -0
- {marimo_flow-0.4.2 → marimo_flow-0.4.4}/src/marimo_flow/agents/server/ag_ui.py +0 -0
- {marimo_flow-0.4.2 → marimo_flow-0.4.4}/src/marimo_flow/agents/services/__init__.py +0 -0
- {marimo_flow-0.4.2 → marimo_flow-0.4.4}/src/marimo_flow/agents/services/composer.py +0 -0
- {marimo_flow-0.4.2 → marimo_flow-0.4.4}/src/marimo_flow/agents/services/design.py +0 -0
- {marimo_flow-0.4.2 → marimo_flow-0.4.4}/src/marimo_flow/agents/services/experiment.py +0 -0
- {marimo_flow-0.4.2 → marimo_flow-0.4.4}/src/marimo_flow/agents/services/mesh_domain.py +0 -0
- {marimo_flow-0.4.2 → marimo_flow-0.4.4}/src/marimo_flow/agents/services/orchestrator.py +0 -0
- {marimo_flow-0.4.2 → marimo_flow-0.4.4}/src/marimo_flow/agents/services/preset_catalog.py +0 -0
- {marimo_flow-0.4.2 → marimo_flow-0.4.4}/src/marimo_flow/agents/services/provenance.py +0 -0
- {marimo_flow-0.4.2 → marimo_flow-0.4.4}/src/marimo_flow/agents/skills.py +0 -0
- {marimo_flow-0.4.2 → marimo_flow-0.4.4}/src/marimo_flow/agents/state.py +0 -0
- {marimo_flow-0.4.2 → marimo_flow-0.4.4}/src/marimo_flow/agents/toolsets/__init__.py +0 -0
- {marimo_flow-0.4.2 → marimo_flow-0.4.4}/src/marimo_flow/agents/toolsets/_registry.py +0 -0
- {marimo_flow-0.4.2 → marimo_flow-0.4.4}/src/marimo_flow/agents/toolsets/_specs.py +0 -0
- {marimo_flow-0.4.2 → marimo_flow-0.4.4}/src/marimo_flow/agents/toolsets/curator.py +0 -0
- {marimo_flow-0.4.2 → marimo_flow-0.4.4}/src/marimo_flow/agents/toolsets/data.py +0 -0
- {marimo_flow-0.4.2 → marimo_flow-0.4.4}/src/marimo_flow/agents/toolsets/design.py +0 -0
- {marimo_flow-0.4.2 → marimo_flow-0.4.4}/src/marimo_flow/agents/toolsets/lead.py +0 -0
- {marimo_flow-0.4.2 → marimo_flow-0.4.4}/src/marimo_flow/agents/toolsets/model.py +0 -0
- {marimo_flow-0.4.2 → marimo_flow-0.4.4}/src/marimo_flow/agents/toolsets/problem.py +0 -0
- {marimo_flow-0.4.2 → marimo_flow-0.4.4}/src/marimo_flow/agents/toolsets/skills.py +0 -0
- {marimo_flow-0.4.2 → marimo_flow-0.4.4}/src/marimo_flow/agents/toolsets/solver.py +0 -0
- {marimo_flow-0.4.2 → marimo_flow-0.4.4}/src/marimo_flow/agents/toolsets/training.py +0 -0
- {marimo_flow-0.4.2 → marimo_flow-0.4.4}/src/marimo_flow/agents/toolsets/validation.py +0 -0
- {marimo_flow-0.4.2 → marimo_flow-0.4.4}/src/marimo_flow/cli.py +0 -0
- {marimo_flow-0.4.2 → marimo_flow-0.4.4}/src/marimo_flow/control/__init__.py +0 -0
- {marimo_flow-0.4.2 → marimo_flow-0.4.4}/src/marimo_flow/control/pinn_surrogate.py +0 -0
- {marimo_flow-0.4.2 → marimo_flow-0.4.4}/src/marimo_flow/core/__init__.py +0 -0
- {marimo_flow-0.4.2 → marimo_flow-0.4.4}/src/marimo_flow/core/model_factory.py +0 -0
- {marimo_flow-0.4.2 → marimo_flow-0.4.4}/src/marimo_flow/core/model_manager.py +0 -0
- {marimo_flow-0.4.2 → marimo_flow-0.4.4}/src/marimo_flow/core/problem_manager.py +0 -0
- {marimo_flow-0.4.2 → marimo_flow-0.4.4}/src/marimo_flow/core/solver_manager.py +0 -0
- {marimo_flow-0.4.2 → marimo_flow-0.4.4}/src/marimo_flow/core/training.py +0 -0
- {marimo_flow-0.4.2 → marimo_flow-0.4.4}/src/marimo_flow/core/visualization.py +0 -0
- {marimo_flow-0.4.2 → marimo_flow-0.4.4}/src/marimo_flow/core/viz3d.py +0 -0
- {marimo_flow-0.4.2 → marimo_flow-0.4.4}/src/marimo_flow/core/walrus.py +0 -0
- {marimo_flow-0.4.2 → marimo_flow-0.4.4}/src/marimo_flow.egg-info/SOURCES.txt +0 -0
- {marimo_flow-0.4.2 → marimo_flow-0.4.4}/src/marimo_flow.egg-info/dependency_links.txt +0 -0
- {marimo_flow-0.4.2 → marimo_flow-0.4.4}/src/marimo_flow.egg-info/entry_points.txt +0 -0
- {marimo_flow-0.4.2 → marimo_flow-0.4.4}/src/marimo_flow.egg-info/not-zip-safe +0 -0
- {marimo_flow-0.4.2 → marimo_flow-0.4.4}/src/marimo_flow.egg-info/top_level.txt +0 -0
- {marimo_flow-0.4.2 → marimo_flow-0.4.4}/tests/test_cli.py +0 -0
- {marimo_flow-0.4.2 → marimo_flow-0.4.4}/tests/test_training.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: marimo-flow
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.4
|
|
4
4
|
Summary: Agentic scientific-computing platform: a reactive multi-agent team orchestrating PINA physics-informed neural-network workflows via pydantic-graph, with MLflow tracing/provenance and a marimo chat UI.
|
|
5
5
|
Author-email: Björn Bethge <helloworld@synapticore.io>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -20,44 +20,44 @@ Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
|
20
20
|
Requires-Python: >=3.11
|
|
21
21
|
Description-Content-Type: text/markdown
|
|
22
22
|
License-File: LICENSE
|
|
23
|
-
Requires-Dist: marimo[lsp,mcp,recommended,sql]>=0.
|
|
23
|
+
Requires-Dist: marimo[lsp,mcp,recommended,sql]>=0.25.0
|
|
24
24
|
Requires-Dist: mlflow[genai]>=3.16.1
|
|
25
25
|
Requires-Dist: fastmcp>=4.0.9
|
|
26
|
-
Requires-Dist: optuna>=
|
|
27
|
-
Requires-Dist: pina-mathlab>=0.2.
|
|
28
|
-
Requires-Dist: transformers[accelerate,tiktoken]>=5.
|
|
29
|
-
Requires-Dist: authlib>=1.
|
|
30
|
-
Requires-Dist: pillow>=12.
|
|
31
|
-
Requires-Dist: cryptography>=
|
|
32
|
-
Requires-Dist: langgraph>=1.
|
|
26
|
+
Requires-Dist: optuna>=5.0.0
|
|
27
|
+
Requires-Dist: pina-mathlab>=0.3.2.post2609
|
|
28
|
+
Requires-Dist: transformers[accelerate,tiktoken]>=5.17.0
|
|
29
|
+
Requires-Dist: authlib>=1.8.0
|
|
30
|
+
Requires-Dist: pillow>=12.3.0
|
|
31
|
+
Requires-Dist: cryptography>=50.0.1
|
|
32
|
+
Requires-Dist: langgraph>=1.2.12
|
|
33
33
|
Requires-Dist: werkzeug>=3.1.8
|
|
34
34
|
Requires-Dist: sqlparse>=0.6.0
|
|
35
35
|
Requires-Dist: diskcache>=5.6.3
|
|
36
36
|
Requires-Dist: protobuf>=6.33.6
|
|
37
|
-
Requires-Dist: python-multipart>=0.0.
|
|
38
|
-
Requires-Dist: ujson>=
|
|
39
|
-
Requires-Dist: pyasn1>=0.6.
|
|
40
|
-
Requires-Dist: pyjwt>=2.
|
|
37
|
+
Requires-Dist: python-multipart>=0.0.32
|
|
38
|
+
Requires-Dist: ujson>=6.0.0
|
|
39
|
+
Requires-Dist: pyasn1>=0.6.4
|
|
40
|
+
Requires-Dist: pyjwt>=2.15.0
|
|
41
41
|
Requires-Dist: flask>=3.1.3
|
|
42
|
-
Requires-Dist: gitpython>=3.1.
|
|
43
|
-
Requires-Dist: httpx2>=2.
|
|
44
|
-
Requires-Dist: httpcore2>=2.
|
|
42
|
+
Requires-Dist: gitpython>=3.1.62
|
|
43
|
+
Requires-Dist: httpx2>=2.13.1
|
|
44
|
+
Requires-Dist: httpcore2>=2.13.1
|
|
45
45
|
Requires-Dist: lightning>=2.6.6
|
|
46
46
|
Requires-Dist: aiohttp>=3.14.3
|
|
47
47
|
Requires-Dist: accelerate>=1.15.0
|
|
48
|
-
Requires-Dist: pymdown-extensions>=11.0.
|
|
49
|
-
Requires-Dist: optuna-integration[pytorch-lightning]>=
|
|
50
|
-
Requires-Dist: plotly[express,kaleido]>=
|
|
51
|
-
Requires-Dist: pydantic-ai-slim[ag-ui]>=2.
|
|
48
|
+
Requires-Dist: pymdown-extensions>=11.0.2
|
|
49
|
+
Requires-Dist: optuna-integration[pytorch-lightning]>=5.0.0
|
|
50
|
+
Requires-Dist: plotly[express,kaleido]>=7.1.0
|
|
51
|
+
Requires-Dist: pydantic-ai-slim[ag-ui]>=2.49.0
|
|
52
52
|
Requires-Dist: pyyaml>=6.0.3
|
|
53
|
-
Requires-Dist: python-dotenv>=1.2.
|
|
54
|
-
Requires-Dist: typer>=0.
|
|
53
|
+
Requires-Dist: python-dotenv>=1.2.3
|
|
54
|
+
Requires-Dist: typer>=0.27.2
|
|
55
55
|
Requires-Dist: sympy>=1.14.0
|
|
56
56
|
Requires-Dist: meshio>=5.3.5
|
|
57
|
-
Requires-Dist: fasta2a>=0.
|
|
57
|
+
Requires-Dist: fasta2a>=2.0.1
|
|
58
58
|
Provides-Extra: all
|
|
59
|
-
Requires-Dist: torch>=2.
|
|
60
|
-
Requires-Dist: torch-geometric>=2.
|
|
59
|
+
Requires-Dist: torch>=2.14.0; extra == "all"
|
|
60
|
+
Requires-Dist: torch-geometric>=2.8.0.post1; extra == "all"
|
|
61
61
|
Dynamic: license-file
|
|
62
62
|
|
|
63
63
|
# Marimo Flow 🌊
|
|
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "marimo-flow"
|
|
7
|
-
version = "0.4.
|
|
7
|
+
version = "0.4.4"
|
|
8
8
|
description = "Agentic scientific-computing platform: a reactive multi-agent team orchestrating PINA physics-informed neural-network workflows via pydantic-graph, with MLflow tracing/provenance and a marimo chat UI."
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.11"
|
|
@@ -43,62 +43,62 @@ classifiers = [
|
|
|
43
43
|
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
44
44
|
]
|
|
45
45
|
dependencies = [
|
|
46
|
-
"marimo[lsp,recommended,sql,mcp]>=0.
|
|
46
|
+
"marimo[lsp,recommended,sql,mcp]>=0.25.0",
|
|
47
47
|
# No [mcp] extra: it pins fastmcp<4, which pip resolves to fastmcp 2.x +
|
|
48
48
|
# mcp 2.x (ImportError on McpError). We need the fastmcp client directly.
|
|
49
49
|
"mlflow[genai]>=3.16.1",
|
|
50
50
|
"fastmcp>=4.0.9",
|
|
51
|
-
"optuna>=
|
|
52
|
-
"pina-mathlab>=0.2.
|
|
53
|
-
"transformers[accelerate,tiktoken]>=5.
|
|
51
|
+
"optuna>=5.0.0",
|
|
52
|
+
"pina-mathlab>=0.3.2.post2609",
|
|
53
|
+
"transformers[accelerate,tiktoken]>=5.17.0",
|
|
54
54
|
# security: explicit minimums for vulnerable transitive deps
|
|
55
|
-
"authlib>=1.
|
|
56
|
-
"pillow>=12.
|
|
57
|
-
"cryptography>=
|
|
58
|
-
"langgraph>=1.
|
|
55
|
+
"authlib>=1.8.0",
|
|
56
|
+
"pillow>=12.3.0",
|
|
57
|
+
"cryptography>=50.0.1",
|
|
58
|
+
"langgraph>=1.2.12",
|
|
59
59
|
"werkzeug>=3.1.8",
|
|
60
60
|
"sqlparse>=0.6.0",
|
|
61
61
|
"diskcache>=5.6.3",
|
|
62
62
|
"protobuf>=6.33.6",
|
|
63
|
-
"python-multipart>=0.0.
|
|
64
|
-
"ujson>=
|
|
65
|
-
"pyasn1>=0.6.
|
|
66
|
-
"pyjwt>=2.
|
|
63
|
+
"python-multipart>=0.0.32",
|
|
64
|
+
"ujson>=6.0.0",
|
|
65
|
+
"pyasn1>=0.6.4",
|
|
66
|
+
"pyjwt>=2.15.0",
|
|
67
67
|
"flask>=3.1.3",
|
|
68
|
-
"gitpython>=3.1.
|
|
69
|
-
"httpx2>=2.
|
|
70
|
-
"httpcore2>=2.
|
|
68
|
+
"gitpython>=3.1.62",
|
|
69
|
+
"httpx2>=2.13.1",
|
|
70
|
+
"httpcore2>=2.13.1",
|
|
71
71
|
"lightning>=2.6.6",
|
|
72
72
|
"aiohttp>=3.14.3",
|
|
73
73
|
"accelerate>=1.15.0",
|
|
74
|
-
"pymdown-extensions>=11.0.
|
|
75
|
-
"optuna-integration[pytorch-lightning]>=
|
|
76
|
-
"plotly[express,kaleido]>=
|
|
74
|
+
"pymdown-extensions>=11.0.2",
|
|
75
|
+
"optuna-integration[pytorch-lightning]>=5.0.0",
|
|
76
|
+
"plotly[express,kaleido]>=7.1.0",
|
|
77
77
|
# pydantic-ai 2.x dropped the bundled `a2a` extra; A2A now comes via the
|
|
78
78
|
# standalone `fasta2a` dep below (still the same agent_to_a2a API).
|
|
79
|
-
"pydantic-ai-slim[ag-ui]>=2.
|
|
79
|
+
"pydantic-ai-slim[ag-ui]>=2.49.0",
|
|
80
80
|
"pyyaml>=6.0.3",
|
|
81
|
-
"python-dotenv>=1.2.
|
|
82
|
-
"typer>=0.
|
|
81
|
+
"python-dotenv>=1.2.3",
|
|
82
|
+
"typer>=0.27.2",
|
|
83
83
|
"sympy>=1.14.0",
|
|
84
84
|
"meshio>=5.3.5",
|
|
85
|
-
"fasta2a>=0.
|
|
85
|
+
"fasta2a>=2.0.1",
|
|
86
86
|
]
|
|
87
87
|
|
|
88
88
|
[project.optional-dependencies]
|
|
89
89
|
all = [
|
|
90
|
-
"torch>=2.
|
|
91
|
-
"torch-geometric>=2.
|
|
90
|
+
"torch>=2.14.0",
|
|
91
|
+
"torch-geometric>=2.8.0.post1",
|
|
92
92
|
]
|
|
93
93
|
|
|
94
94
|
[dependency-groups]
|
|
95
95
|
dev = [
|
|
96
|
-
"mypy>=
|
|
97
|
-
"pre-commit>=4.
|
|
98
|
-
"pytest>=9.
|
|
99
|
-
"pytest-asyncio>=1.
|
|
100
|
-
"pytest-cov>=7.
|
|
101
|
-
"ruff>=0.
|
|
96
|
+
"mypy>=2.3.1",
|
|
97
|
+
"pre-commit>=4.6.2",
|
|
98
|
+
"pytest>=9.1.1",
|
|
99
|
+
"pytest-asyncio>=1.4.0",
|
|
100
|
+
"pytest-cov>=7.1.0",
|
|
101
|
+
"ruff>=0.16.9",
|
|
102
102
|
]
|
|
103
103
|
docs = [
|
|
104
104
|
"sphinx>=9.0.4",
|
|
@@ -115,7 +115,11 @@ def closed_loop_simulation(
|
|
|
115
115
|
true_dynamics_registry_key: str,
|
|
116
116
|
n_steps: int = 20,
|
|
117
117
|
) -> dict[str, list[list[float]]]:
|
|
118
|
-
"""Run
|
|
118
|
+
"""Run an offset-free closed-loop rollout.
|
|
119
|
+
|
|
120
|
+
Returns the state and control trajectories plus ``disturbance``, the
|
|
121
|
+
observer's estimate of the surrogate's bias at each step.
|
|
122
|
+
"""
|
|
119
123
|
from marimo_flow.control.mpc import simulate_closed_loop
|
|
120
124
|
|
|
121
125
|
plan_model = ControlPlan.model_validate(plan)
|
|
@@ -135,4 +139,5 @@ def closed_loop_simulation(
|
|
|
135
139
|
return {
|
|
136
140
|
"states": traj["states"].tolist(),
|
|
137
141
|
"controls": traj["controls"].tolist(),
|
|
142
|
+
"disturbance": traj["disturbance"].tolist(),
|
|
138
143
|
}
|
|
@@ -119,8 +119,13 @@ def train_step_surrogate(
|
|
|
119
119
|
epochs: int = 200,
|
|
120
120
|
lr: float = 1e-3,
|
|
121
121
|
batch_size: int = 256,
|
|
122
|
+
seed: int | None = None,
|
|
122
123
|
) -> PredictStepFn:
|
|
123
|
-
"""Fit a small MLP on plant rollouts; return a numpy predict callable.
|
|
124
|
+
"""Fit a small MLP on plant rollouts; return a numpy predict callable.
|
|
125
|
+
|
|
126
|
+
``seed`` makes weight init and batch shuffling reproducible without
|
|
127
|
+
touching torch's global RNG state.
|
|
128
|
+
"""
|
|
124
129
|
if inputs.ndim != 2 or inputs.shape[1] != 2:
|
|
125
130
|
raise ValueError("inputs must have shape (n, 2)")
|
|
126
131
|
if targets.ndim != 2 or targets.shape[1] != 1:
|
|
@@ -139,13 +144,23 @@ def train_step_surrogate(
|
|
|
139
144
|
x_norm = (inputs - x_mean) / x_std
|
|
140
145
|
y_norm = (targets - y_mean) / y_std
|
|
141
146
|
|
|
142
|
-
|
|
143
|
-
|
|
144
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
|
|
147
|
+
generator = torch.Generator()
|
|
148
|
+
if seed is None:
|
|
149
|
+
generator.seed()
|
|
150
|
+
else:
|
|
151
|
+
generator.manual_seed(seed)
|
|
152
|
+
|
|
153
|
+
# nn.Linear initialises from the global RNG; fork it so a seeded run
|
|
154
|
+
# neither depends on nor changes the caller's torch RNG state.
|
|
155
|
+
with torch.random.fork_rng(devices=[]):
|
|
156
|
+
torch.manual_seed(generator.initial_seed())
|
|
157
|
+
layers: list[nn.Module] = []
|
|
158
|
+
in_dim = 2
|
|
159
|
+
for width in hidden:
|
|
160
|
+
layers.extend([nn.Linear(in_dim, width), nn.Tanh()])
|
|
161
|
+
in_dim = width
|
|
162
|
+
layers.append(nn.Linear(in_dim, 1))
|
|
163
|
+
model = nn.Sequential(*layers)
|
|
149
164
|
|
|
150
165
|
x_t = torch.tensor(x_norm, dtype=torch.float32)
|
|
151
166
|
y_t = torch.tensor(y_norm, dtype=torch.float32)
|
|
@@ -154,7 +169,7 @@ def train_step_surrogate(
|
|
|
154
169
|
|
|
155
170
|
n = len(x_t)
|
|
156
171
|
for _ in range(epochs):
|
|
157
|
-
perm = torch.randperm(n)
|
|
172
|
+
perm = torch.randperm(n, generator=generator)
|
|
158
173
|
for start in range(0, n, batch_size):
|
|
159
174
|
idx = perm[start : start + batch_size]
|
|
160
175
|
pred = model(x_t[idx])
|
|
@@ -19,6 +19,13 @@ Returns:
|
|
|
19
19
|
* ``state_trajectory``: shape ``(horizon, n_states)`` — predicted next states.
|
|
20
20
|
"""
|
|
21
21
|
|
|
22
|
+
# Surrogates are usually torch networks evaluated in float32. SLSQP's default
|
|
23
|
+
# finite-difference step (~1.5e-8) is below float32 resolution, so the
|
|
24
|
+
# objective would not change, the gradient would be zero and the solver would
|
|
25
|
+
# stop at the initial guess. sqrt(float32 eps) is the standard forward-
|
|
26
|
+
# difference step for float32-noisy functions.
|
|
27
|
+
_FD_REL_STEP = float(np.sqrt(np.finfo(np.float32).eps))
|
|
28
|
+
|
|
22
29
|
|
|
23
30
|
def run_mpc_step(
|
|
24
31
|
plan: ControlPlan,
|
|
@@ -26,12 +33,15 @@ def run_mpc_step(
|
|
|
26
33
|
surrogate: SurrogateFn,
|
|
27
34
|
*,
|
|
28
35
|
prev_controls: np.ndarray | None = None,
|
|
36
|
+
disturbance: np.ndarray | None = None,
|
|
29
37
|
) -> tuple[np.ndarray, dict[str, float]]:
|
|
30
38
|
"""Solve one MPC horizon; return the chosen control sequence + info.
|
|
31
39
|
|
|
32
40
|
Only the first control column is applied by the caller — the rest
|
|
33
41
|
is the MPC's look-ahead. ``prev_controls`` warm-starts the solver
|
|
34
|
-
with the previous horizon shifted by one step.
|
|
42
|
+
with the previous horizon shifted by one step. ``disturbance`` (shape
|
|
43
|
+
``(n_states,)``) is added to every predicted state — the output
|
|
44
|
+
disturbance estimate of offset-free MPC.
|
|
35
45
|
"""
|
|
36
46
|
h = plan.horizon
|
|
37
47
|
n_ctrl = len(plan.controls)
|
|
@@ -47,12 +57,13 @@ def run_mpc_step(
|
|
|
47
57
|
|
|
48
58
|
targets = np.array([s.target if s.target is not None else 0.0 for s in plan.states])
|
|
49
59
|
weights = np.array([s.weight for s in plan.states])
|
|
60
|
+
offset = np.zeros(n_state) if disturbance is None else disturbance
|
|
50
61
|
|
|
51
62
|
def flat_to_seq(x: np.ndarray) -> np.ndarray:
|
|
52
63
|
return x.reshape(h, n_ctrl)
|
|
53
64
|
|
|
54
65
|
def objective(x: np.ndarray) -> float:
|
|
55
|
-
traj = surrogate(state_now, flat_to_seq(x))
|
|
66
|
+
traj = surrogate(state_now, flat_to_seq(x)) + offset
|
|
56
67
|
err = traj - targets
|
|
57
68
|
return float(np.sum(weights * (err**2)))
|
|
58
69
|
|
|
@@ -64,8 +75,9 @@ def run_mpc_step(
|
|
|
64
75
|
objective,
|
|
65
76
|
x0=x0.flatten(),
|
|
66
77
|
method="SLSQP",
|
|
78
|
+
jac="2-point",
|
|
67
79
|
bounds=bounds,
|
|
68
|
-
options={"maxiter": 50, "ftol": 1e-6},
|
|
80
|
+
options={"maxiter": 50, "ftol": 1e-6, "finite_diff_rel_step": _FD_REL_STEP},
|
|
69
81
|
)
|
|
70
82
|
return flat_to_seq(result.x), {
|
|
71
83
|
"cost": float(result.fun),
|
|
@@ -81,25 +93,46 @@ def simulate_closed_loop(
|
|
|
81
93
|
true_dynamics: SurrogateFn,
|
|
82
94
|
*,
|
|
83
95
|
n_steps: int,
|
|
96
|
+
offset_free: bool = True,
|
|
97
|
+
disturbance_gain: float = 0.3,
|
|
84
98
|
) -> dict[str, np.ndarray]:
|
|
85
99
|
"""Run n_steps of MPC + true-dynamics rollout; return the trajectory.
|
|
86
100
|
|
|
87
101
|
``true_dynamics`` plays the role of the real plant (for sim work).
|
|
88
102
|
In production the caller replaces it with a measurement hook.
|
|
103
|
+
|
|
104
|
+
With ``offset_free`` (default) an integrating output-disturbance
|
|
105
|
+
observer corrects the surrogate: ``d += disturbance_gain * (measured -
|
|
106
|
+
(surrogate + d))``, and every horizon is planned on ``surrogate + d``.
|
|
107
|
+
A surrogate bias then leaves no steady-state error; ``d`` stays zero
|
|
108
|
+
when the surrogate matches the plant. A gain below 1 keeps the estimate
|
|
109
|
+
from chasing input-dependent (e.g. gain) model errors step by step,
|
|
110
|
+
which would make the loop oscillate.
|
|
111
|
+
Returns ``states`` and ``disturbance`` of shape ``(n_steps + 1,
|
|
112
|
+
n_states)`` and ``controls`` of shape ``(n_steps, n_controls)``.
|
|
89
113
|
"""
|
|
90
114
|
n_ctrl = len(plan.controls)
|
|
115
|
+
n_state = len(plan.states)
|
|
91
116
|
state = initial_state.copy()
|
|
92
117
|
applied = np.zeros((n_steps, n_ctrl))
|
|
93
|
-
states = np.zeros((n_steps + 1,
|
|
118
|
+
states = np.zeros((n_steps + 1, n_state))
|
|
119
|
+
disturbances = np.zeros((n_steps + 1, n_state))
|
|
94
120
|
states[0] = state
|
|
95
121
|
prev = None
|
|
122
|
+
d = np.zeros(n_state)
|
|
96
123
|
for k in range(n_steps):
|
|
97
|
-
ctrl_seq, _ = run_mpc_step(
|
|
124
|
+
ctrl_seq, _ = run_mpc_step(
|
|
125
|
+
plan, state, surrogate, prev_controls=prev, disturbance=d
|
|
126
|
+
)
|
|
98
127
|
applied[k] = ctrl_seq[0]
|
|
128
|
+
predicted = surrogate(state, ctrl_seq[:1])[0] + d
|
|
99
129
|
state = true_dynamics(state, ctrl_seq[:1])[0]
|
|
130
|
+
if offset_free:
|
|
131
|
+
d = d + disturbance_gain * (state - predicted)
|
|
100
132
|
states[k + 1] = state
|
|
133
|
+
disturbances[k + 1] = d
|
|
101
134
|
prev = ctrl_seq
|
|
102
|
-
return {"states": states, "controls": applied}
|
|
135
|
+
return {"states": states, "controls": applied, "disturbance": disturbances}
|
|
103
136
|
|
|
104
137
|
|
|
105
138
|
def _warm_start(plan: ControlPlan, prev_controls: np.ndarray | None) -> np.ndarray:
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: marimo-flow
|
|
3
|
-
Version: 0.4.
|
|
3
|
+
Version: 0.4.4
|
|
4
4
|
Summary: Agentic scientific-computing platform: a reactive multi-agent team orchestrating PINA physics-informed neural-network workflows via pydantic-graph, with MLflow tracing/provenance and a marimo chat UI.
|
|
5
5
|
Author-email: Björn Bethge <helloworld@synapticore.io>
|
|
6
6
|
License-Expression: MIT
|
|
@@ -20,44 +20,44 @@ Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
|
20
20
|
Requires-Python: >=3.11
|
|
21
21
|
Description-Content-Type: text/markdown
|
|
22
22
|
License-File: LICENSE
|
|
23
|
-
Requires-Dist: marimo[lsp,mcp,recommended,sql]>=0.
|
|
23
|
+
Requires-Dist: marimo[lsp,mcp,recommended,sql]>=0.25.0
|
|
24
24
|
Requires-Dist: mlflow[genai]>=3.16.1
|
|
25
25
|
Requires-Dist: fastmcp>=4.0.9
|
|
26
|
-
Requires-Dist: optuna>=
|
|
27
|
-
Requires-Dist: pina-mathlab>=0.2.
|
|
28
|
-
Requires-Dist: transformers[accelerate,tiktoken]>=5.
|
|
29
|
-
Requires-Dist: authlib>=1.
|
|
30
|
-
Requires-Dist: pillow>=12.
|
|
31
|
-
Requires-Dist: cryptography>=
|
|
32
|
-
Requires-Dist: langgraph>=1.
|
|
26
|
+
Requires-Dist: optuna>=5.0.0
|
|
27
|
+
Requires-Dist: pina-mathlab>=0.3.2.post2609
|
|
28
|
+
Requires-Dist: transformers[accelerate,tiktoken]>=5.17.0
|
|
29
|
+
Requires-Dist: authlib>=1.8.0
|
|
30
|
+
Requires-Dist: pillow>=12.3.0
|
|
31
|
+
Requires-Dist: cryptography>=50.0.1
|
|
32
|
+
Requires-Dist: langgraph>=1.2.12
|
|
33
33
|
Requires-Dist: werkzeug>=3.1.8
|
|
34
34
|
Requires-Dist: sqlparse>=0.6.0
|
|
35
35
|
Requires-Dist: diskcache>=5.6.3
|
|
36
36
|
Requires-Dist: protobuf>=6.33.6
|
|
37
|
-
Requires-Dist: python-multipart>=0.0.
|
|
38
|
-
Requires-Dist: ujson>=
|
|
39
|
-
Requires-Dist: pyasn1>=0.6.
|
|
40
|
-
Requires-Dist: pyjwt>=2.
|
|
37
|
+
Requires-Dist: python-multipart>=0.0.32
|
|
38
|
+
Requires-Dist: ujson>=6.0.0
|
|
39
|
+
Requires-Dist: pyasn1>=0.6.4
|
|
40
|
+
Requires-Dist: pyjwt>=2.15.0
|
|
41
41
|
Requires-Dist: flask>=3.1.3
|
|
42
|
-
Requires-Dist: gitpython>=3.1.
|
|
43
|
-
Requires-Dist: httpx2>=2.
|
|
44
|
-
Requires-Dist: httpcore2>=2.
|
|
42
|
+
Requires-Dist: gitpython>=3.1.62
|
|
43
|
+
Requires-Dist: httpx2>=2.13.1
|
|
44
|
+
Requires-Dist: httpcore2>=2.13.1
|
|
45
45
|
Requires-Dist: lightning>=2.6.6
|
|
46
46
|
Requires-Dist: aiohttp>=3.14.3
|
|
47
47
|
Requires-Dist: accelerate>=1.15.0
|
|
48
|
-
Requires-Dist: pymdown-extensions>=11.0.
|
|
49
|
-
Requires-Dist: optuna-integration[pytorch-lightning]>=
|
|
50
|
-
Requires-Dist: plotly[express,kaleido]>=
|
|
51
|
-
Requires-Dist: pydantic-ai-slim[ag-ui]>=2.
|
|
48
|
+
Requires-Dist: pymdown-extensions>=11.0.2
|
|
49
|
+
Requires-Dist: optuna-integration[pytorch-lightning]>=5.0.0
|
|
50
|
+
Requires-Dist: plotly[express,kaleido]>=7.1.0
|
|
51
|
+
Requires-Dist: pydantic-ai-slim[ag-ui]>=2.49.0
|
|
52
52
|
Requires-Dist: pyyaml>=6.0.3
|
|
53
|
-
Requires-Dist: python-dotenv>=1.2.
|
|
54
|
-
Requires-Dist: typer>=0.
|
|
53
|
+
Requires-Dist: python-dotenv>=1.2.3
|
|
54
|
+
Requires-Dist: typer>=0.27.2
|
|
55
55
|
Requires-Dist: sympy>=1.14.0
|
|
56
56
|
Requires-Dist: meshio>=5.3.5
|
|
57
|
-
Requires-Dist: fasta2a>=0.
|
|
57
|
+
Requires-Dist: fasta2a>=2.0.1
|
|
58
58
|
Provides-Extra: all
|
|
59
|
-
Requires-Dist: torch>=2.
|
|
60
|
-
Requires-Dist: torch-geometric>=2.
|
|
59
|
+
Requires-Dist: torch>=2.14.0; extra == "all"
|
|
60
|
+
Requires-Dist: torch-geometric>=2.8.0.post1; extra == "all"
|
|
61
61
|
Dynamic: license-file
|
|
62
62
|
|
|
63
63
|
# Marimo Flow 🌊
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
marimo[lsp,mcp,recommended,sql]>=0.25.0
|
|
2
|
+
mlflow[genai]>=3.16.1
|
|
3
|
+
fastmcp>=4.0.9
|
|
4
|
+
optuna>=5.0.0
|
|
5
|
+
pina-mathlab>=0.3.2.post2609
|
|
6
|
+
transformers[accelerate,tiktoken]>=5.17.0
|
|
7
|
+
authlib>=1.8.0
|
|
8
|
+
pillow>=12.3.0
|
|
9
|
+
cryptography>=50.0.1
|
|
10
|
+
langgraph>=1.2.12
|
|
11
|
+
werkzeug>=3.1.8
|
|
12
|
+
sqlparse>=0.6.0
|
|
13
|
+
diskcache>=5.6.3
|
|
14
|
+
protobuf>=6.33.6
|
|
15
|
+
python-multipart>=0.0.32
|
|
16
|
+
ujson>=6.0.0
|
|
17
|
+
pyasn1>=0.6.4
|
|
18
|
+
pyjwt>=2.15.0
|
|
19
|
+
flask>=3.1.3
|
|
20
|
+
gitpython>=3.1.62
|
|
21
|
+
httpx2>=2.13.1
|
|
22
|
+
httpcore2>=2.13.1
|
|
23
|
+
lightning>=2.6.6
|
|
24
|
+
aiohttp>=3.14.3
|
|
25
|
+
accelerate>=1.15.0
|
|
26
|
+
pymdown-extensions>=11.0.2
|
|
27
|
+
optuna-integration[pytorch-lightning]>=5.0.0
|
|
28
|
+
plotly[express,kaleido]>=7.1.0
|
|
29
|
+
pydantic-ai-slim[ag-ui]>=2.49.0
|
|
30
|
+
pyyaml>=6.0.3
|
|
31
|
+
python-dotenv>=1.2.3
|
|
32
|
+
typer>=0.27.2
|
|
33
|
+
sympy>=1.14.0
|
|
34
|
+
meshio>=5.3.5
|
|
35
|
+
fasta2a>=2.0.1
|
|
36
|
+
|
|
37
|
+
[all]
|
|
38
|
+
torch>=2.14.0
|
|
39
|
+
torch-geometric>=2.8.0.post1
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
marimo[lsp,mcp,recommended,sql]>=0.23.1
|
|
2
|
-
mlflow[genai]>=3.16.1
|
|
3
|
-
fastmcp>=4.0.9
|
|
4
|
-
optuna>=4.8.0
|
|
5
|
-
pina-mathlab>=0.2.6
|
|
6
|
-
transformers[accelerate,tiktoken]>=5.5.4
|
|
7
|
-
authlib>=1.6.9
|
|
8
|
-
pillow>=12.2.0
|
|
9
|
-
cryptography>=49.0.0
|
|
10
|
-
langgraph>=1.1.8
|
|
11
|
-
werkzeug>=3.1.8
|
|
12
|
-
sqlparse>=0.6.0
|
|
13
|
-
diskcache>=5.6.3
|
|
14
|
-
protobuf>=6.33.6
|
|
15
|
-
python-multipart>=0.0.27
|
|
16
|
-
ujson>=5.12.0
|
|
17
|
-
pyasn1>=0.6.3
|
|
18
|
-
pyjwt>=2.12.1
|
|
19
|
-
flask>=3.1.3
|
|
20
|
-
gitpython>=3.1.59
|
|
21
|
-
httpx2>=2.12.0
|
|
22
|
-
httpcore2>=2.10.0
|
|
23
|
-
lightning>=2.6.6
|
|
24
|
-
aiohttp>=3.14.3
|
|
25
|
-
accelerate>=1.15.0
|
|
26
|
-
pymdown-extensions>=11.0.1
|
|
27
|
-
optuna-integration[pytorch-lightning]>=4.8.0
|
|
28
|
-
plotly[express,kaleido]>=6.7.0
|
|
29
|
-
pydantic-ai-slim[ag-ui]>=2.10.0
|
|
30
|
-
pyyaml>=6.0.3
|
|
31
|
-
python-dotenv>=1.2.2
|
|
32
|
-
typer>=0.24.1
|
|
33
|
-
sympy>=1.14.0
|
|
34
|
-
meshio>=5.3.5
|
|
35
|
-
fasta2a>=0.6.1
|
|
36
|
-
|
|
37
|
-
[all]
|
|
38
|
-
torch>=2.11.0
|
|
39
|
-
torch-geometric>=2.7.0
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|