mycorrhizal 0.1.2__py3-none-any.whl → 0.2.0__py3-none-any.whl

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.
Files changed (41) hide show
  1. mycorrhizal/_version.py +1 -1
  2. mycorrhizal/common/__init__.py +15 -3
  3. mycorrhizal/common/cache.py +114 -0
  4. mycorrhizal/common/compilation.py +263 -0
  5. mycorrhizal/common/interface_detection.py +159 -0
  6. mycorrhizal/common/interfaces.py +3 -50
  7. mycorrhizal/common/mermaid.py +124 -0
  8. mycorrhizal/common/wrappers.py +1 -1
  9. mycorrhizal/hypha/core/builder.py +11 -1
  10. mycorrhizal/hypha/core/runtime.py +242 -107
  11. mycorrhizal/mycelium/__init__.py +174 -0
  12. mycorrhizal/mycelium/core.py +619 -0
  13. mycorrhizal/mycelium/exceptions.py +30 -0
  14. mycorrhizal/mycelium/hypha_bridge.py +1143 -0
  15. mycorrhizal/mycelium/instance.py +440 -0
  16. mycorrhizal/mycelium/pn_context.py +276 -0
  17. mycorrhizal/mycelium/runner.py +165 -0
  18. mycorrhizal/mycelium/spores_integration.py +655 -0
  19. mycorrhizal/mycelium/tree_builder.py +102 -0
  20. mycorrhizal/mycelium/tree_spec.py +197 -0
  21. mycorrhizal/rhizomorph/README.md +82 -33
  22. mycorrhizal/rhizomorph/core.py +287 -119
  23. mycorrhizal/septum/TRANSITION_REFERENCE.md +385 -0
  24. mycorrhizal/{enoki → septum}/core.py +326 -100
  25. mycorrhizal/{enoki → septum}/testing_utils.py +7 -7
  26. mycorrhizal/{enoki → septum}/util.py +44 -21
  27. mycorrhizal/spores/__init__.py +3 -3
  28. mycorrhizal/spores/core.py +149 -28
  29. mycorrhizal/spores/dsl/__init__.py +8 -8
  30. mycorrhizal/spores/dsl/hypha.py +3 -15
  31. mycorrhizal/spores/dsl/rhizomorph.py +3 -11
  32. mycorrhizal/spores/dsl/{enoki.py → septum.py} +26 -77
  33. mycorrhizal/spores/encoder/json.py +21 -12
  34. mycorrhizal/spores/extraction.py +14 -11
  35. mycorrhizal/spores/models.py +53 -20
  36. mycorrhizal-0.2.0.dist-info/METADATA +335 -0
  37. mycorrhizal-0.2.0.dist-info/RECORD +54 -0
  38. mycorrhizal-0.1.2.dist-info/METADATA +0 -198
  39. mycorrhizal-0.1.2.dist-info/RECORD +0 -39
  40. /mycorrhizal/{enoki → septum}/__init__.py +0 -0
  41. {mycorrhizal-0.1.2.dist-info → mycorrhizal-0.2.0.dist-info}/WHEEL +0 -0
@@ -0,0 +1,335 @@
1
+ Metadata-Version: 2.4
2
+ Name: mycorrhizal
3
+ Version: 0.2.0
4
+ Summary: Utilities and DSLs for modelling and implementing safe, performant, structured systems
5
+ Author-email: Jeff Ciesielski <jeffciesielski@gmail.com>
6
+ Requires-Python: >=3.10
7
+ Requires-Dist: pydantic>=2.11.7
8
+ Requires-Dist: typeguard==4.4.4
9
+ Provides-Extra: docs
10
+ Requires-Dist: mkdocs-literate-nav>=0.6.0; extra == 'docs'
11
+ Requires-Dist: mkdocs-material>=9.5.0; extra == 'docs'
12
+ Requires-Dist: mkdocs-section-index>=0.3.0; extra == 'docs'
13
+ Requires-Dist: mkdocs-table-reader-plugin>=2.0.0; extra == 'docs'
14
+ Requires-Dist: mkdocs>=1.6.0; extra == 'docs'
15
+ Requires-Dist: mkdocstrings[python]>=0.25.0; extra == 'docs'
16
+ Description-Content-Type: text/markdown
17
+
18
+ # Mycorrhizal
19
+
20
+ [![Tests](https://github.com/Jeff-Ciesielski/mycorrhizal/actions/workflows/test.yml/badge.svg)](https://github.com/Jeff-Ciesielski/mycorrhizal/actions/workflows/test.yml)
21
+ [![codecov](https://codecov.io/gh/Jeff-Ciesielski/mycorrhizal/branch/main/graph/badge.svg)](https://codecov.io/gh/Jeff-Ciesielski/mycorrhizal)
22
+ [![Documentation Status](https://readthedocs.org/projects/mycorrhizal/badge/?version=latest)](https://mycorrhizal.readthedocs.io/en/latest/?badge=latest)
23
+ [![Python Version](https://img.shields.io/pypi/pyversions/mycorrhizal)](https://pypi.org/project/mycorrhizal/)
24
+ [![License: MIT](https://img.shields.io/badge/License-MIT-yellow.svg)](https://opensource.org/licenses/MIT)
25
+
26
+ A Python library for building safe, structured, concurrent, event-driven systems.
27
+
28
+ ## Overview
29
+
30
+ Mycorrhizal provides four domain-specific languages (DSLs) for modeling and implementing different aspects of complex systems:
31
+
32
+ * **Hypha** - Colored Petri nets for workflow modeling and orchestration
33
+ * **Rhizomorph** - Behavior trees for decision-making and control logic
34
+ * **Septum** - Finite state machines for stateful components
35
+ * **Spores** - Event and object logging for observability and process mining
36
+
37
+ Each DSL can be used independently or combined to build sophisticated systems. All modules share common infrastructure for state management (blackboards) and time abstraction, enabling seamless composition.
38
+
39
+ ## Installation
40
+
41
+ ```bash
42
+ pip install mycorrhizal
43
+ ```
44
+
45
+ Requires Python 3.10 or later.
46
+
47
+ ## Quick Start
48
+
49
+ ### Behavior Tree (Rhizomorph)
50
+
51
+ Define behavior trees using a decorator-based DSL:
52
+
53
+ ```python
54
+ from mycorrhizal.rhizomorph.core import bt, Runner, Status
55
+
56
+ @bt.tree
57
+ def ThreatResponse():
58
+ @bt.action
59
+ async def assess_threat(bb) -> Status:
60
+ # Analyze threat level
61
+ return Status.SUCCESS if bb.threat_level > 5 else Status.FAILURE
62
+
63
+ @bt.action
64
+ async def engage_countermeasures(bb) -> Status:
65
+ # Respond to threat
66
+ return Status.SUCCESS
67
+
68
+ @bt.root
69
+ @bt.sequence
70
+ def root():
71
+ yield assess_threat
72
+ yield engage_countermeasures
73
+
74
+ # Run the behavior tree
75
+ runner = Runner(ThreatResponse, bb=blackboard)
76
+ await runner.tick_until_complete()
77
+ ```
78
+
79
+ ### Petri Net (Hypha)
80
+
81
+ Model workflows with colored Petri nets:
82
+
83
+ ```python
84
+ from mycorrhizal.hypha.core import pn, Runner, PlaceType
85
+
86
+ @pn.net
87
+ def ProcessingNet(builder):
88
+ # Define places
89
+ pending = builder.place("pending", type=PlaceType.QUEUE)
90
+ processed = builder.place("processed", type=PlaceType.QUEUE)
91
+
92
+ # Define transitions
93
+ @builder.transition()
94
+ async def process(consumed, bb, timebase):
95
+ for token in consumed:
96
+ result = await handle(token)
97
+ yield {processed: result}
98
+
99
+ # Wire the net
100
+ builder.arc(pending, process).arc(processed)
101
+
102
+ # Run the Petri net
103
+ runner = Runner(ProcessingNet, bb=blackboard)
104
+ await runner.start(timebase)
105
+ ```
106
+
107
+ ### Finite State Machine (Septum)
108
+
109
+ Build stateful components with FSMs:
110
+
111
+ ```python
112
+ from mycorrhizal.septum.core import septum, StateMachine, LabeledTransition
113
+
114
+ @septum.state()
115
+ def IdleState():
116
+ @septum.on_state
117
+ async def on_state(ctx):
118
+ if ctx.msg == "start":
119
+ return Events.START
120
+ return None
121
+
122
+ @septum.transitions
123
+ def transitions():
124
+ return [
125
+ LabeledTransition(Events.START, ProcessingState),
126
+ ]
127
+
128
+ # Create and run the FSM
129
+ fsm = StateMachine(initial_state=IdleState, common_data={})
130
+ await fsm.initialize()
131
+ fsm.send_message("start")
132
+ await fsm.tick()
133
+ ```
134
+
135
+ ## Key Features
136
+
137
+ ### Shared Infrastructure
138
+
139
+ All DSLs use common building blocks:
140
+
141
+ * **Blackboards** - Typed shared state using Pydantic models
142
+ * **Interfaces** - Decorator-based access control for blackboard fields
143
+ * **Timebase** - Abstract time for simulation and testing
144
+
145
+ ### Composition
146
+
147
+ Combine DSLs to model complex systems:
148
+
149
+ * Embed behavior trees in Petri net transitions
150
+ * Run state machines within behavior tree actions
151
+ * Use Petri nets to orchestrate FSM-based components
152
+
153
+ ### Observability
154
+
155
+ The Spores module provides OCEL-compliant logging:
156
+
157
+ * Automatic event extraction from DSL execution
158
+ * Object lifecycle tracking
159
+ * Transport layer for custom backends
160
+
161
+ ## Examples
162
+
163
+ The repository contains comprehensive examples:
164
+
165
+ * `examples/hypha/` - Petri net patterns
166
+ * `examples/rhizomorph/` - Behavior tree patterns
167
+ * `examples/septum/` - State machine patterns
168
+ * `examples/spores/` - Event logging integration
169
+ * `examples/interfaces/` - Type-safe blackboard access
170
+
171
+ Run examples with:
172
+
173
+ ```bash
174
+ uv run python examples/hypha/minimal_hypha_demo.py
175
+ ```
176
+
177
+ See [examples/README.md](https://github.com/Jeff-Ciesielski/mycorrhizal/tree/main/examples/) for a complete guide.
178
+
179
+ ## Visualization
180
+
181
+ All three DSLs support Mermaid diagram export for documentation and debugging. You can generate diagrams programmatically:
182
+
183
+ ```python
184
+ # Behavior Tree
185
+ diagram = MyTree.to_mermaid()
186
+
187
+ # Petri Net
188
+ diagram = MyNet.to_mermaid()
189
+
190
+ # Finite State Machine
191
+ from mycorrhizal.septum.util import to_mermaid
192
+ diagram = to_mermaid(fsm)
193
+ ```
194
+
195
+ ### Example Diagrams
196
+
197
+ **Behavior Tree (Rhizomorph)** - A threat response system with decorators:
198
+
199
+ ```mermaid
200
+ flowchart TD
201
+ N1["Selector<br/>root"]
202
+ N1 --> N2
203
+ N2["Subtree<br/>Engage"]
204
+ N2 --> N3
205
+ N3["Sequence<br/>engage_threat"]
206
+ N3 --> N4
207
+ N4((CONDITION<br/>threat_detected))
208
+ N3 --> N5
209
+ N5["Decor<br/>Failer(Gate(cond=battery_ok)(Timeout(0.12s)(engage)))"]
210
+ N5 --> N6
211
+ N6["Decor<br/>Gate(cond=battery_ok)(Timeout(0.12s)(engage))"]
212
+ N6 --> N7
213
+ N7["Decor<br/>Timeout(0.12s)(engage)"]
214
+ N7 --> N8
215
+ N8((ACTION<br/>engage))
216
+ N1 --> N9
217
+ N9["Sequence<br/>patrol"]
218
+ N9 --> N10
219
+ N10((CONDITION<br/>has_waypoints))
220
+ N9 --> N11
221
+ N11((ACTION<br/>go_to_next))
222
+ N9 --> N12
223
+ N12["Decor<br/>Succeeder(Retry(3)(Timeout(1.0s)(scan_area)))"]
224
+ N12 --> N13
225
+ N13["Decor<br/>Retry(3)(Timeout(1.0s)(scan_area))"]
226
+ N13 --> N14
227
+ N14["Decor<br/>Timeout(1.0s)(scan_area)"]
228
+ N14 --> N15
229
+ N15((ACTION<br/>scan_area))
230
+ N1 --> N16
231
+ N16["Decor<br/>Failer(RateLimit(0.200000s)(telemetry_push))"]
232
+ N16 --> N17
233
+ N17["Decor<br/>RateLimit(0.200000s)(telemetry_push)"]
234
+ N17 --> N18
235
+ N18((ACTION<br/>telemetry_push))
236
+ ```
237
+
238
+ **Petri Net (Hypha)** - A task processing system with error handling:
239
+
240
+ ```mermaid
241
+ graph TD
242
+ subgraph TaskProcessingSystem.TaskGen
243
+ TaskProcessingSystem.TaskGen.source(("[INPUT]</br>TaskProcessingSystem.TaskGen.source"))
244
+ end
245
+ subgraph TaskProcessingSystem.TaskProc
246
+ TaskProcessingSystem.TaskProc.input(("TaskProcessingSystem.TaskProc.input"))
247
+ TaskProcessingSystem.TaskProc.processing(("TaskProcessingSystem.TaskProc.processing"))
248
+ TaskProcessingSystem.TaskProc.completed(("TaskProcessingSystem.TaskProc.completed"))
249
+ TaskProcessingSystem.TaskProc.failed(("TaskProcessingSystem.TaskProc.failed"))
250
+ TaskProcessingSystem.TaskProc.take_to_processing[TaskProcessingSystem.TaskProc.take_to_processing]
251
+ TaskProcessingSystem.TaskProc.do_processing[TaskProcessingSystem.TaskProc.do_processing]
252
+ TaskProcessingSystem.TaskProc.input --> TaskProcessingSystem.TaskProc.take_to_processing
253
+ TaskProcessingSystem.TaskProc.take_to_processing --> TaskProcessingSystem.TaskProc.processing
254
+ TaskProcessingSystem.TaskProc.processing --> TaskProcessingSystem.TaskProc.do_processing
255
+ TaskProcessingSystem.TaskProc.do_processing --> TaskProcessingSystem.TaskProc.completed
256
+ TaskProcessingSystem.TaskProc.do_processing --> TaskProcessingSystem.TaskProc.failed
257
+ end
258
+ subgraph TaskProcessingSystem.Notify
259
+ TaskProcessingSystem.Notify.input(("TaskProcessingSystem.Notify.input"))
260
+ TaskProcessingSystem.Notify.email_sink(("[OUTPUT]</br>TaskProcessingSystem.Notify.email_sink"))
261
+ TaskProcessingSystem.Notify.sms_sink(("[OUTPUT]</br>TaskProcessingSystem.Notify.sms_sink"))
262
+ TaskProcessingSystem.Notify.log_sink(("[OUTPUT]</br>TaskProcessingSystem.Notify.log_sink"))
263
+ TaskProcessingSystem.Notify.NotificationFork[TaskProcessingSystem.Notify.NotificationFork]
264
+ TaskProcessingSystem.Notify.input --> TaskProcessingSystem.Notify.NotificationFork
265
+ TaskProcessingSystem.Notify.NotificationFork --> TaskProcessingSystem.Notify.email_sink
266
+ TaskProcessingSystem.Notify.NotificationFork --> TaskProcessingSystem.Notify.sms_sink
267
+ TaskProcessingSystem.Notify.NotificationFork --> TaskProcessingSystem.Notify.log_sink
268
+ end
269
+ subgraph TaskProcessingSystem.ErrorHandle
270
+ TaskProcessingSystem.ErrorHandle.input(("TaskProcessingSystem.ErrorHandle.input"))
271
+ TaskProcessingSystem.ErrorHandle.error_log(("[OUTPUT]</br>TaskProcessingSystem.ErrorHandle.error_log"))
272
+ TaskProcessingSystem.ErrorHandle.ErrorForward[TaskProcessingSystem.ErrorHandle.ErrorForward]
273
+ TaskProcessingSystem.ErrorHandle.input --> TaskProcessingSystem.ErrorHandle.ErrorForward
274
+ TaskProcessingSystem.ErrorHandle.ErrorForward --> TaskProcessingSystem.ErrorHandle.error_log
275
+ end
276
+ TaskProcessingSystem.completion_tracker(("[OUTPUT]</br>TaskProcessingSystem.completion_tracker"))
277
+ TaskProcessingSystem.forward_source_to_input[TaskProcessingSystem.forward_source_to_input]
278
+ TaskProcessingSystem.CompletionFork[TaskProcessingSystem.CompletionFork]
279
+ TaskProcessingSystem.FailureFork[TaskProcessingSystem.FailureFork]
280
+ TaskProcessingSystem.TaskGen.source --> TaskProcessingSystem.forward_source_to_input
281
+ TaskProcessingSystem.forward_source_to_input --> TaskProcessingSystem.TaskProc.input
282
+ TaskProcessingSystem.TaskProc.completed --> TaskProcessingSystem.CompletionFork
283
+ TaskProcessingSystem.CompletionFork --> TaskProcessingSystem.Notify.input
284
+ TaskProcessingSystem.CompletionFork --> TaskProcessingSystem.completion_tracker
285
+ TaskProcessingSystem.TaskProc.failed --> TaskProcessingSystem.FailureFork
286
+ TaskProcessingSystem.FailureFork --> TaskProcessingSystem.ErrorHandle.input
287
+ TaskProcessingSystem.FailureFork --> TaskProcessingSystem.completion_tracker
288
+ ```
289
+
290
+ **Finite State Machine (Septum)** - A simple idle/processing/done workflow:
291
+
292
+ ```mermaid
293
+ flowchart TD
294
+ start((start)) --> S1
295
+ S1[IdleState]
296
+ S1 -->|"START"| S2
297
+ S1 -->|"QUIT"| S3
298
+ S2[ProcessingState]
299
+ S2 -->|"DONE"| S1
300
+ S3[DoneState (**terminal**)]
301
+ ```
302
+
303
+ ## Documentation
304
+
305
+ Full documentation is available at [https://mycorrhizal.readthedocs.io](https://mycorrhizal.readthedocs.io)
306
+
307
+ ## Development
308
+
309
+ ```bash
310
+ # Install dependencies
311
+ uv pip install -e ".[dev]"
312
+
313
+ # Run tests
314
+ pytest
315
+
316
+ # Run with coverage
317
+ pytest --cov=src/mycorrhizal --cov-report=html
318
+ ```
319
+
320
+ ## Project Status
321
+
322
+ This is a 0.1.0 release. The core APIs are stable and well-tested, but some features are still in development:
323
+
324
+ * Current: Four DSLs with decorator-based syntax
325
+ * Current: Comprehensive examples and tests
326
+ * Planned: Cross-DSL interoperability layer
327
+ * Planned: Enhanced composition patterns
328
+
329
+ ## License
330
+
331
+ MIT
332
+
333
+ ## Author
334
+
335
+ Jeff Ciesielski
@@ -0,0 +1,54 @@
1
+ mycorrhizal/__init__.py,sha256=ajz1GSNU9xYVrFEDSz6Xwg7amWQ_yvW75tQa1ZvRIWc,3
2
+ mycorrhizal/_version.py,sha256=XQVhijSHeIVMVzY2S4fY9BKxV2XHSTr9VVHsYltGPvQ,18
3
+ mycorrhizal/common/__init__.py,sha256=OwPFyCFW6H6E6EkQIjQfl-h67qfo36geu0ndfXqYEn4,1705
4
+ mycorrhizal/common/cache.py,sha256=D-L9aVG3eXemXKVmhiRONFB0KWobzRHACknMkHgZ3ug,3477
5
+ mycorrhizal/common/compilation.py,sha256=f98aE0Dq6ztgm6SjxYbWKGjhOZ2i9SWLT7bc2Yvvwos,8922
6
+ mycorrhizal/common/interface_builder.py,sha256=rBJzduqZ6EjD9MNGO669BcjkM9mYvsnMG0F1kd1wWaQ,6895
7
+ mycorrhizal/common/interface_detection.py,sha256=VKUGdL0wkWaSpyMoUqkic16vFsPQFpIL9OCFM68CAHI,4622
8
+ mycorrhizal/common/interfaces.py,sha256=nXS_j1QYmPxel_avjT1Mlb0C1ZpNUOicMN1yQ0e_r6Y,10714
9
+ mycorrhizal/common/mermaid.py,sha256=qEv-0_ChQLZcGYYHLYnkgFYzl3w2G0YDT9JnvOHDFR4,3483
10
+ mycorrhizal/common/timebase.py,sha256=h8OymApwr_EvpRsfRJb6E5YosHg3jfqToOGAfMlL-Qw,2229
11
+ mycorrhizal/common/wrappers.py,sha256=z5ezZuRycH8k8ODOR_B57SrvckTA_TfFLRvyGI63tkQ,17809
12
+ mycorrhizal/hypha/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
+ mycorrhizal/hypha/util.py,sha256=tpvjWXTdGhtVUycQElcQg4usOy-tSEqwE9KEni8R30s,906
14
+ mycorrhizal/hypha/core/__init__.py,sha256=o6BE3fhRKjVfyIWwtNTO64kPt0udlZGyXr-ZuN_ZzF8,2518
15
+ mycorrhizal/hypha/core/builder.py,sha256=aZ6xvktGVteDBVFf2Uva7-7vsBbpAP3maBfiL6xiJl0,17205
16
+ mycorrhizal/hypha/core/runtime.py,sha256=BTguGT2ku2U70r-5IYVPP3ubrG1QC5_opQ0hbF5162k,40830
17
+ mycorrhizal/hypha/core/specs.py,sha256=uWvW9x7-bSoSENIUJkYMIkJ3KxsgE9mB9PyRLPrOEjk,8429
18
+ mycorrhizal/mycelium/__init__.py,sha256=MFgh6eZVjE1zSwgDqD2GXneZv-7MWtRoky5Qtmydqdw,4231
19
+ mycorrhizal/mycelium/core.py,sha256=ly3GtHKHHwqoODk3tFWMKoUT3VYPsQHBYyDNSKCmGMY,19583
20
+ mycorrhizal/mycelium/exceptions.py,sha256=6QVwHEDQWZAYNMgrNhIZ3vhD-wBAaSIt4vKfEJQ2rMI,750
21
+ mycorrhizal/mycelium/hypha_bridge.py,sha256=c1CCAMAo-nBX6iEYZDPPc__SSaaOVnPl77fdoHiX-9A,48325
22
+ mycorrhizal/mycelium/instance.py,sha256=qrjoeDyi71FtVMrDj4bjkb-WwfxNihzO6hAPd4g9sag,16526
23
+ mycorrhizal/mycelium/pn_context.py,sha256=z_wRZAN3DeaZWZP9DdlfbZbreU-Sf0xqKV0qakewMXk,8680
24
+ mycorrhizal/mycelium/runner.py,sha256=afEzk1rjQuPG7FPRP5lf0Uxvr-wUmQTd8A8z8-dV4DY,4402
25
+ mycorrhizal/mycelium/spores_integration.py,sha256=SbFQLF5bBJCr0OOgSbH7rOa7zsDtoKsuU_VJV4ywtR4,20032
26
+ mycorrhizal/mycelium/tree_builder.py,sha256=WOxCZgAPmGmFb_t0FghCNgAVdVLEqdbtWN5KmiBkgx8,3400
27
+ mycorrhizal/mycelium/tree_spec.py,sha256=0RyZBOJROxWrYdqtNeawWv1vB5ZgwzGR-lWFN8b2-Ro,6919
28
+ mycorrhizal/rhizomorph/README.md,sha256=UrCYyaMUtqa9U2ejMyg9om-1QhFm3S6sFS9Cjp_4jUs,9367
29
+ mycorrhizal/rhizomorph/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
30
+ mycorrhizal/rhizomorph/core.py,sha256=S9UWecUWzLqAAdAg1WhjROZYegwoc61btzXArPKCeWg,67411
31
+ mycorrhizal/rhizomorph/util.py,sha256=dUgKAWX5RNtzFK01mGkz10tJyeTMCqyyfnZ8Mi97LkY,1280
32
+ mycorrhizal/septum/TRANSITION_REFERENCE.md,sha256=4mxDeTbeuqIDJCebXlwxT537Tgk2XLpinssam6I6lNw,10987
33
+ mycorrhizal/septum/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
34
+ mycorrhizal/septum/core.py,sha256=vGGvhP0TDidu5MGJgxiioQXsE3t-G9uvQKJeEud_18o,64043
35
+ mycorrhizal/septum/testing_utils.py,sha256=ONk9hOm7oc8qSgbOcsWaZvlfP_iOUS7uoo3aS7Pfuis,17314
36
+ mycorrhizal/septum/util.py,sha256=J4D0uBzNkVWDBwrOMhG9x5Y4lkjP8pEDkuc2d4UX7eI,9344
37
+ mycorrhizal/spores/__init__.py,sha256=iePLLnGdKVHKrzoy9gQFARcQG0jmDIUavkJwLv9Mx6w,4766
38
+ mycorrhizal/spores/cache.py,sha256=0FuWHKudgyC7vlrlcJ_kmRKr7OAJuC2gxRURReMlqF4,6119
39
+ mycorrhizal/spores/core.py,sha256=fBklI4pQUd78o8qJ6_MXFmDZN612CDqr3dfS0yAmc_U,45109
40
+ mycorrhizal/spores/extraction.py,sha256=pCc_bm-MUx7SYGM9xI_m4cOL3X5VjGIr3FQ66fkUW5k,15063
41
+ mycorrhizal/spores/models.py,sha256=nwjSSbSvBMuuE0__nDt2loDRJhJWQBu0Y3jRg4p3wfU,9724
42
+ mycorrhizal/spores/dsl/__init__.py,sha256=DDrLqJ4CjtRsepmzsxkdxu_ugYYpAwaxawau-0t4Bm0,1163
43
+ mycorrhizal/spores/dsl/hypha.py,sha256=L565_yW93xIo7KcqjgZnYldBObiOS7ix1Wq1W6W-ULc,11695
44
+ mycorrhizal/spores/dsl/rhizomorph.py,sha256=JXaZmRyiKVOz2I1uf-96u7Zl9h4YlJCaAtaXYUWnKxc,9737
45
+ mycorrhizal/spores/dsl/septum.py,sha256=bG6HPTAWAAoSbps-2hs0oGsyTOEq1pPCIsgDvmfUI6Q,14206
46
+ mycorrhizal/spores/encoder/__init__.py,sha256=hpp1W4xwQUG1N1zdrea0coBPtMf-WYSE77Q780TinP8,204
47
+ mycorrhizal/spores/encoder/base.py,sha256=xFKk-f5_W_HNrOgNXyquUwhcrcz28LmeT5Y5enDVrwU,870
48
+ mycorrhizal/spores/encoder/json.py,sha256=OPezVz-5-to-NmZ_QuVGMPSLn_24GbdG6Y3F4_RXx40,5064
49
+ mycorrhizal/spores/transport/__init__.py,sha256=Tw6glCXsPK2pzsLPbb9vKOCvvT9vh-ql-xUaulKBAw0,407
50
+ mycorrhizal/spores/transport/base.py,sha256=OsyWx1J8Ig7Y7idUoI9oS-LkONwQAxAP47jL_5OVRjA,1668
51
+ mycorrhizal/spores/transport/file.py,sha256=xcMPxAGiv5q-GfcNKsF_3a-2-yxlDkhHusZli1Fsqa0,3833
52
+ mycorrhizal-0.2.0.dist-info/METADATA,sha256=KCGylTow8Ue3YeSB--pjQ1QtCdFzcD6hwKzosN-JWqk,11607
53
+ mycorrhizal-0.2.0.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
54
+ mycorrhizal-0.2.0.dist-info/RECORD,,
@@ -1,198 +0,0 @@
1
- Metadata-Version: 2.4
2
- Name: mycorrhizal
3
- Version: 0.1.2
4
- Summary: Utilities and DSLs for modelling and implementing safe, performant, structured systems
5
- Author-email: Jeff Ciesielski <jeffciesielski@gmail.com>
6
- Requires-Python: >=3.10
7
- Requires-Dist: pydantic>=2.11.7
8
- Requires-Dist: typeguard==4.4.4
9
- Description-Content-Type: text/markdown
10
-
11
- # Mycorrhizal
12
-
13
- A Python library for building safe, structured, concurrent, event-driven systems.
14
-
15
- ## Overview
16
-
17
- Mycorrhizal provides four domain-specific languages (DSLs) for modeling and implementing different aspects of complex systems:
18
-
19
- * **Hypha** - Colored Petri nets for workflow modeling and orchestration
20
- * **Rhizomorph** - Behavior trees for decision-making and control logic
21
- * **Enoki** - Finite state machines for stateful components
22
- * **Spores** - Event and object logging for observability and process mining
23
-
24
- Each DSL can be used independently or combined to build sophisticated systems. All modules share common infrastructure for state management (blackboards) and time abstraction, enabling seamless composition.
25
-
26
- ## Installation
27
-
28
- ```bash
29
- pip install mycorrhizal
30
- ```
31
-
32
- Requires Python 3.10 or later.
33
-
34
- ## Quick Start
35
-
36
- ### Behavior Tree (Rhizomorph)
37
-
38
- Define behavior trees using a decorator-based DSL:
39
-
40
- ```python
41
- from mycorrhizal.rhizomorph.core import bt, Runner, Status
42
-
43
- @bt.tree
44
- def ThreatResponse():
45
- @bt.action
46
- async def assess_threat(bb) -> Status:
47
- # Analyze threat level
48
- return Status.SUCCESS if bb.threat_level > 5 else Status.FAILURE
49
-
50
- @bt.action
51
- async def engage_countermeasures(bb) -> Status:
52
- # Respond to threat
53
- return Status.SUCCESS
54
-
55
- @bt.root
56
- @bt.sequence
57
- def root():
58
- yield assess_threat
59
- yield engage_countermeasures
60
-
61
- # Run the behavior tree
62
- runner = Runner(ThreatResponse, bb=blackboard)
63
- await runner.tick_until_complete()
64
- ```
65
-
66
- ### Petri Net (Hypha)
67
-
68
- Model workflows with colored Petri nets:
69
-
70
- ```python
71
- from mycorrhizal.hypha.core import pn, Runner, PlaceType
72
-
73
- @pn.net
74
- def ProcessingNet(builder):
75
- # Define places
76
- pending = builder.place("pending", type=PlaceType.QUEUE)
77
- processed = builder.place("processed", type=PlaceType.QUEUE)
78
-
79
- # Define transitions
80
- @builder.transition()
81
- async def process(consumed, bb, timebase):
82
- for token in consumed:
83
- result = await handle(token)
84
- yield {processed: result}
85
-
86
- # Wire the net
87
- builder.arc(pending, process).arc(processed)
88
-
89
- # Run the Petri net
90
- runner = Runner(ProcessingNet, bb=blackboard)
91
- await runner.start(timebase)
92
- ```
93
-
94
- ### Finite State Machine (Enoki)
95
-
96
- Build stateful components with FSMs:
97
-
98
- ```python
99
- from mycorrhizal.enoki.core import enoki, StateMachine, LabeledTransition
100
-
101
- @enoki.state()
102
- def IdleState():
103
- @enoki.on_state
104
- async def on_state(ctx):
105
- if ctx.msg == "start":
106
- return Events.START
107
- return None
108
-
109
- @enoki.transitions
110
- def transitions():
111
- return [
112
- LabeledTransition(Events.START, ProcessingState),
113
- ]
114
-
115
- # Create and run the FSM
116
- fsm = StateMachine(initial_state=IdleState, common_data={})
117
- await fsm.initialize()
118
- fsm.send_message("start")
119
- await fsm.tick()
120
- ```
121
-
122
- ## Key Features
123
-
124
- ### Shared Infrastructure
125
-
126
- All DSLs use common building blocks:
127
-
128
- * **Blackboards** - Typed shared state using Pydantic models
129
- * **Interfaces** - Decorator-based access control for blackboard fields
130
- * **Timebase** - Abstract time for simulation and testing
131
-
132
- ### Composition
133
-
134
- Combine DSLs to model complex systems:
135
-
136
- * Embed behavior trees in Petri net transitions
137
- * Run state machines within behavior tree actions
138
- * Use Petri nets to orchestrate FSM-based components
139
-
140
- ### Observability
141
-
142
- The Spores module provides OCEL-compliant logging:
143
-
144
- * Automatic event extraction from DSL execution
145
- * Object lifecycle tracking
146
- * Transport layer for custom backends
147
-
148
- ## Examples
149
-
150
- The repository contains comprehensive examples:
151
-
152
- * `examples/hypha/` - Petri net patterns
153
- * `examples/rhizomorph/` - Behavior tree patterns
154
- * `examples/enoki/` - State machine patterns
155
- * `examples/spores/` - Event logging integration
156
- * `examples/interfaces/` - Type-safe blackboard access
157
-
158
- Run examples with:
159
-
160
- ```bash
161
- uv run python examples/hypha/minimal_hypha_demo.py
162
- ```
163
-
164
- See [examples/README.md](examples/README.md) for a complete guide.
165
-
166
- ## Documentation
167
-
168
- Full API documentation is available at [docs link here].
169
-
170
- ## Development
171
-
172
- ```bash
173
- # Install dependencies
174
- uv pip install -e ".[dev]"
175
-
176
- # Run tests
177
- pytest
178
-
179
- # Run with coverage
180
- pytest --cov=src/mycorrhizal --cov-report=html
181
- ```
182
-
183
- ## Project Status
184
-
185
- This is a 0.1.0 release. The core APIs are stable and well-tested, but some features are still in development:
186
-
187
- * Current: Four DSLs with decorator-based syntax
188
- * Current: Comprehensive examples and tests
189
- * Planned: Cross-DSL interoperability layer
190
- * Planned: Enhanced composition patterns
191
-
192
- ## License
193
-
194
- MIT
195
-
196
- ## Author
197
-
198
- Jeff Ciesielski
@@ -1,39 +0,0 @@
1
- mycorrhizal/__init__.py,sha256=ajz1GSNU9xYVrFEDSz6Xwg7amWQ_yvW75tQa1ZvRIWc,3
2
- mycorrhizal/_version.py,sha256=08TK2sYzQF2Wqm6gpxZEgWYYF9ZjbInObIzS2R2yxiE,18
3
- mycorrhizal/common/__init__.py,sha256=vAL2NZFFVcoGoPlIREKRG0mrgx1prVTGTlWBopJ76Sw,1450
4
- mycorrhizal/common/interface_builder.py,sha256=rBJzduqZ6EjD9MNGO669BcjkM9mYvsnMG0F1kd1wWaQ,6895
5
- mycorrhizal/common/interfaces.py,sha256=fWw6bm2ejFmKUnl2pSTiSEwTP0Id8Kowg827_Mqir-s,12261
6
- mycorrhizal/common/timebase.py,sha256=h8OymApwr_EvpRsfRJb6E5YosHg3jfqToOGAfMlL-Qw,2229
7
- mycorrhizal/common/wrappers.py,sha256=hdj_1OgWe9RNqGlEkcklQ2j0FFn-AE9h5A55udYTr4o,17794
8
- mycorrhizal/enoki/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
9
- mycorrhizal/enoki/core.py,sha256=17oV8AGTI5aY299nAm3Jtc5iarImT2WPbMIwYE5LRsA,53697
10
- mycorrhizal/enoki/testing_utils.py,sha256=S19p0nZ0UTfQm-hPHFAWqN9LAdfjL9uQKMFx_gaices,17307
11
- mycorrhizal/enoki/util.py,sha256=oJ9vmHrbUdX99Rkh7bBeUHFzM5sS3yrtXOTQDA1524I,8434
12
- mycorrhizal/hypha/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
13
- mycorrhizal/hypha/util.py,sha256=tpvjWXTdGhtVUycQElcQg4usOy-tSEqwE9KEni8R30s,906
14
- mycorrhizal/hypha/core/__init__.py,sha256=o6BE3fhRKjVfyIWwtNTO64kPt0udlZGyXr-ZuN_ZzF8,2518
15
- mycorrhizal/hypha/core/builder.py,sha256=GyjDWG3ZTO_0OIhJNrty4-SaJ9RGsNIzHyOQBCNKDfc,16912
16
- mycorrhizal/hypha/core/runtime.py,sha256=K7EDxPTYu9lyHoolBGrrOTws7f1xmbnU2SBVVLnoD3g,34848
17
- mycorrhizal/hypha/core/specs.py,sha256=uWvW9x7-bSoSENIUJkYMIkJ3KxsgE9mB9PyRLPrOEjk,8429
18
- mycorrhizal/rhizomorph/README.md,sha256=g-G8d00VgMOPriggsNveH7HqLhnJ9HlvoIzrwmUEy_M,8134
19
- mycorrhizal/rhizomorph/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
20
- mycorrhizal/rhizomorph/core.py,sha256=FrV7S6coulaeqhYfHmNE9x6tmlGFBYcqO04zOdpwNNs,60816
21
- mycorrhizal/rhizomorph/util.py,sha256=dUgKAWX5RNtzFK01mGkz10tJyeTMCqyyfnZ8Mi97LkY,1280
22
- mycorrhizal/spores/__init__.py,sha256=VI0y_723Fo1la-nJGJweBWc8PKvpd_VmmT9EBtVrEog,4763
23
- mycorrhizal/spores/cache.py,sha256=0FuWHKudgyC7vlrlcJ_kmRKr7OAJuC2gxRURReMlqF4,6119
24
- mycorrhizal/spores/core.py,sha256=KGv3X6w6pz5RiUD__7MMrYUXvDwGUfWFU_eCvDcQSUg,38624
25
- mycorrhizal/spores/extraction.py,sha256=YnUGABcVgZVSDCXyOQewWG62NAkdievJrXPIA_eJkxg,14918
26
- mycorrhizal/spores/models.py,sha256=Gm_7jwPNgWhYCK5XDIUiN0DfDp4kJEkSbqxpwPdlsJE,8712
27
- mycorrhizal/spores/dsl/__init__.py,sha256=bkxHTkaPrDWUlU1pjYlGJOM-772M5_k7R4aZ8HaxMNM,1153
28
- mycorrhizal/spores/dsl/enoki.py,sha256=eVYNBp3ESZ7lK91vE8H5JWkXX14pOtf6cdAWSLiqAsE,15506
29
- mycorrhizal/spores/dsl/hypha.py,sha256=vcJimWbZT2MmGhj8Lbn3izF1PO9HVJe1YQi5P3EiZ6o,11959
30
- mycorrhizal/spores/dsl/rhizomorph.py,sha256=ChG2fRQD9DR90dLKLYSQR72asC-7eLccvBwZtz8C8kw,9898
31
- mycorrhizal/spores/encoder/__init__.py,sha256=hpp1W4xwQUG1N1zdrea0coBPtMf-WYSE77Q780TinP8,204
32
- mycorrhizal/spores/encoder/base.py,sha256=xFKk-f5_W_HNrOgNXyquUwhcrcz28LmeT5Y5enDVrwU,870
33
- mycorrhizal/spores/encoder/json.py,sha256=dyQSTXfG0VQPSNt9ed8VEgMwxFUPnLtV6u_bSRuEnNY,4747
34
- mycorrhizal/spores/transport/__init__.py,sha256=Tw6glCXsPK2pzsLPbb9vKOCvvT9vh-ql-xUaulKBAw0,407
35
- mycorrhizal/spores/transport/base.py,sha256=OsyWx1J8Ig7Y7idUoI9oS-LkONwQAxAP47jL_5OVRjA,1668
36
- mycorrhizal/spores/transport/file.py,sha256=xcMPxAGiv5q-GfcNKsF_3a-2-yxlDkhHusZli1Fsqa0,3833
37
- mycorrhizal-0.1.2.dist-info/METADATA,sha256=c_xR3AeCwrC8jhbnimBcfu_7jmFItM8UdgAR2Wi8RYQ,4895
38
- mycorrhizal-0.1.2.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
39
- mycorrhizal-0.1.2.dist-info/RECORD,,
File without changes