mango-agents 2.1.2__tar.gz → 2.2.0__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.
Files changed (49) hide show
  1. mango_agents-2.2.0/PKG-INFO +392 -0
  2. mango_agents-2.2.0/mango/__init__.py +102 -0
  3. mango_agents-2.2.0/mango/agent/core.py +941 -0
  4. {mango_agents-2.1.2 → mango_agents-2.2.0}/mango/agent/role.py +183 -15
  5. {mango_agents-2.1.2 → mango_agents-2.2.0}/mango/container/core.py +9 -7
  6. {mango_agents-2.1.2 → mango_agents-2.2.0}/mango/container/external_coupling.py +8 -7
  7. {mango_agents-2.1.2 → mango_agents-2.2.0}/mango/container/factory.py +16 -1
  8. {mango_agents-2.1.2 → mango_agents-2.2.0}/mango/container/mp.py +16 -5
  9. {mango_agents-2.1.2 → mango_agents-2.2.0}/mango/container/mqtt.py +47 -28
  10. {mango_agents-2.1.2 → mango_agents-2.2.0}/mango/container/tcp.py +15 -23
  11. {mango_agents-2.1.2 → mango_agents-2.2.0}/mango/express/api.py +217 -0
  12. mango_agents-2.2.0/mango/express/topology.py +672 -0
  13. {mango_agents-2.1.2 → mango_agents-2.2.0}/mango/messages/codecs.py +46 -12
  14. mango_agents-2.2.0/mango/simulation/__init__.py +45 -0
  15. mango_agents-2.2.0/mango/simulation/communication.py +229 -0
  16. mango_agents-2.2.0/mango/simulation/environment.py +342 -0
  17. mango_agents-2.2.0/mango/simulation/visualization.py +347 -0
  18. mango_agents-2.2.0/mango/simulation/world.py +724 -0
  19. {mango_agents-2.1.2 → mango_agents-2.2.0}/mango/util/distributed_clock.py +2 -2
  20. {mango_agents-2.1.2 → mango_agents-2.2.0}/mango/util/scheduling.py +41 -6
  21. mango_agents-2.2.0/mango_agents.egg-info/PKG-INFO +392 -0
  22. {mango_agents-2.1.2 → mango_agents-2.2.0}/mango_agents.egg-info/SOURCES.txt +5 -0
  23. {mango_agents-2.1.2 → mango_agents-2.2.0}/mango_agents.egg-info/requires.txt +1 -0
  24. {mango_agents-2.1.2 → mango_agents-2.2.0}/pyproject.toml +3 -2
  25. mango_agents-2.2.0/readme.md +335 -0
  26. mango_agents-2.1.2/PKG-INFO +0 -230
  27. mango_agents-2.1.2/mango/__init__.py +0 -32
  28. mango_agents-2.1.2/mango/agent/core.py +0 -499
  29. mango_agents-2.1.2/mango/express/topology.py +0 -139
  30. mango_agents-2.1.2/mango_agents.egg-info/PKG-INFO +0 -230
  31. mango_agents-2.1.2/readme.md +0 -175
  32. {mango_agents-2.1.2 → mango_agents-2.2.0}/LICENSE +0 -0
  33. {mango_agents-2.1.2 → mango_agents-2.2.0}/mango/agent/__init__.py +0 -0
  34. {mango_agents-2.1.2 → mango_agents-2.2.0}/mango/container/__init__.py +0 -0
  35. {mango_agents-2.1.2 → mango_agents-2.2.0}/mango/container/protocol.py +0 -0
  36. {mango_agents-2.1.2 → mango_agents-2.2.0}/mango/express/__init__.py +0 -0
  37. {mango_agents-2.1.2 → mango_agents-2.2.0}/mango/messages/__init__.py +0 -0
  38. {mango_agents-2.1.2 → mango_agents-2.2.0}/mango/messages/acl_message_pb2.py +0 -0
  39. {mango_agents-2.1.2 → mango_agents-2.2.0}/mango/messages/fast_json.py +0 -0
  40. {mango_agents-2.1.2 → mango_agents-2.2.0}/mango/messages/mango_message_pb2.py +0 -0
  41. {mango_agents-2.1.2 → mango_agents-2.2.0}/mango/messages/message.py +0 -0
  42. {mango_agents-2.1.2 → mango_agents-2.2.0}/mango/messages/other_proto_msgs_pb2.py +0 -0
  43. {mango_agents-2.1.2 → mango_agents-2.2.0}/mango/util/__init__.py +0 -0
  44. {mango_agents-2.1.2 → mango_agents-2.2.0}/mango/util/clock.py +0 -0
  45. {mango_agents-2.1.2 → mango_agents-2.2.0}/mango/util/multiprocessing.py +0 -0
  46. {mango_agents-2.1.2 → mango_agents-2.2.0}/mango/util/termination_detection.py +0 -0
  47. {mango_agents-2.1.2 → mango_agents-2.2.0}/mango_agents.egg-info/dependency_links.txt +0 -0
  48. {mango_agents-2.1.2 → mango_agents-2.2.0}/mango_agents.egg-info/top_level.txt +0 -0
  49. {mango_agents-2.1.2 → mango_agents-2.2.0}/setup.cfg +0 -0
@@ -0,0 +1,392 @@
1
+ Metadata-Version: 2.4
2
+ Name: mango-agents
3
+ Version: 2.2.0
4
+ Summary: Modular Python Agent Framework
5
+ Author-email: mango Team <mango@offis.de>
6
+ License: MIT License
7
+
8
+ Copyright (c) 2020 OFFIS e.V.
9
+
10
+ Permission is hereby granted, free of charge, to any person obtaining a copy
11
+ of this software and associated documentation files (the "Software"), to deal
12
+ in the Software without restriction, including without limitation the rights
13
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
14
+ copies of the Software, and to permit persons to whom the Software is
15
+ furnished to do so, subject to the following conditions:
16
+
17
+ The above copyright notice and this permission notice shall be included in all
18
+ copies or substantial portions of the Software.
19
+
20
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
21
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
22
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
23
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
24
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
25
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
26
+ SOFTWARE.
27
+
28
+ Project-URL: Homepage, https://mango-agents.readthedocs.io
29
+ Project-URL: Repository, https://github.com/OFFIS-DAI/mango
30
+ Project-URL: Issues, https://github.com/OFFIS-DAI/mango/issues
31
+ Classifier: License :: OSI Approved :: MIT License
32
+ Classifier: Programming Language :: Python
33
+ Classifier: Programming Language :: Python :: 3
34
+ Classifier: Programming Language :: Python :: 3.10
35
+ Classifier: Programming Language :: Python :: 3.11
36
+ Classifier: Programming Language :: Python :: 3.12
37
+ Classifier: Programming Language :: Python :: 3.13
38
+ Classifier: Programming Language :: Python :: Implementation :: CPython
39
+ Classifier: Programming Language :: Python :: Implementation :: PyPy
40
+ Requires-Python: >=3.10
41
+ Description-Content-Type: text/markdown
42
+ License-File: LICENSE
43
+ Requires-Dist: paho-mqtt>=2.1.0
44
+ Requires-Dist: python-dateutil>=2.9.0
45
+ Requires-Dist: dill>=0.3.8
46
+ Requires-Dist: protobuf==5.27.2
47
+ Requires-Dist: networkx>=3.4.1
48
+ Provides-Extra: fastjson
49
+ Requires-Dist: msgspec>=0.18.6; extra == "fastjson"
50
+ Provides-Extra: test
51
+ Requires-Dist: pytest; extra == "test"
52
+ Requires-Dist: pytest-cov; extra == "test"
53
+ Requires-Dist: pytest-asyncio; extra == "test"
54
+ Requires-Dist: pre-commit; extra == "test"
55
+ Requires-Dist: matplotlib; extra == "test"
56
+ Dynamic: license-file
57
+
58
+ <p align="center">
59
+ <img src="docs/source/_static/Logo_mango_ohne_sub.svg#gh-light-mode-only" alt="mango" width="320"/>
60
+ <img src="docs/source/_static/Logo_mango_ohne_sub_white.svg#gh-dark-mode-only" alt="mango" width="320"/>
61
+ </p>
62
+
63
+ <p align="center">
64
+ <b>Modular Python Agent Framework</b><br>
65
+ <i>A lightweight, asyncio-based library for research and development of multi-agent systems</i>
66
+ </p>
67
+
68
+ <p align="center">
69
+ <a href="https://pypi.org/project/mango-agents/">PyPI</a> |
70
+ <a href="https://mango-agents.readthedocs.io">Read the Docs</a> |
71
+ <a href="https://github.com/OFFIS-DAI/mango">GitHub</a> |
72
+ <a href="mailto:mango@offis.de">mango@offis.de</a>
73
+ </p>
74
+
75
+ <p align="center">
76
+ <a href="https://pypi.org/project/mango-agents/"><img src="https://img.shields.io/pypi/v/mango-agents?color=blue&label=PyPI" alt="PyPI"></a>
77
+ <a href="https://mango-agents.readthedocs.io"><img src="https://img.shields.io/badge/docs-readthedocs-informational" alt="Docs"></a>
78
+ <a href="https://github.com/OFFIS-DAI/mango/actions/workflows/test-mango.yml"><img src="https://github.com/OFFIS-DAI/mango/actions/workflows/test-mango.yml/badge.svg" alt="Tests"></a>
79
+ <a href="https://codecov.io/gh/OFFIS-DAI/mango"><img src="https://codecov.io/gh/OFFIS-DAI/mango/graph/badge.svg?token=6KVKBICGYG" alt="Coverage"></a>
80
+ <a href="https://github.com/OFFIS-DAI/mango/blob/development/LICENSE"><img src="https://img.shields.io/badge/license-MIT-green.svg" alt="License"></a>
81
+ <img src="https://img.shields.io/badge/lifecycle-maturing-blue.svg" alt="Lifecycle">
82
+ </p>
83
+
84
+ ---
85
+
86
+ **mango** (**m**odul**a**r pytho**n** a**g**ent framew**o**rk) is a Python library for building and simulating multi-agent systems (MAS) on top of `asyncio`. It targets researchers and engineers who need reproducible agent behaviour, structured agent architectures, and controlled experimental conditions — without sacrificing usability for prototyping.
87
+
88
+ ---
89
+
90
+ ## Features
91
+
92
+ | Feature | Description |
93
+ |---|---|
94
+ | **Container-based messaging** | Agents are co-located in containers that short-circuit local message exchange without serialisation overhead |
95
+ | **FIPA ACL message format** | Standardised message envelope with built-in JSON and protobuf codecs |
96
+ | **Role decomposition** | Complex agent behaviour is factored into loosely coupled, independently testable role objects |
97
+ | **TCP and MQTT transport** | Agents communicate across process and machine boundaries via TCP sockets or an external MQTT broker |
98
+ | **Discrete-event simulation** | A clock-driven `SimulationWorld` provides deterministic, reproducible runs with configurable communication delay and loss, spatial environments, and structured data recording |
99
+
100
+ ---
101
+
102
+ ## Installation
103
+
104
+ ```bash
105
+ pip install mango-agents
106
+ ```
107
+
108
+ Requires Python 3.10 or later.
109
+
110
+ ---
111
+
112
+ ## Quick Start
113
+
114
+ Every agent is a subclass of `Agent`. Incoming messages are handled by `handle_message`; two lifecycle hooks signal when the agent has joined its container (`on_register`) and when all containers are active and external messaging is safe (`on_ready`).
115
+
116
+ The following complete script creates two agents, starts them in a shared container, sends a message from one to the other, and shuts everything down cleanly:
117
+
118
+ ```python
119
+ import asyncio
120
+ from mango import Agent, create_tcp_container, activate
121
+
122
+
123
+ class ReportingAgent(Agent):
124
+ def on_ready(self):
125
+ print(f"{self.aid}: ready")
126
+
127
+ def handle_message(self, content, meta):
128
+ print(f"{self.aid}: received '{content}' from {meta['sender_id']}")
129
+
130
+
131
+ async def main():
132
+ # All agents on a single host share one container.
133
+ container = create_tcp_container(addr=("127.0.0.1", 5555))
134
+
135
+ sender = container.register(ReportingAgent())
136
+ receiver = container.register(ReportingAgent())
137
+
138
+ async with activate(container):
139
+ await sender.send_message("Hello!", receiver.addr)
140
+ await asyncio.sleep(0.1) # allow time for message processing
141
+
142
+
143
+ asyncio.run(main())
144
+ # agent0: ready
145
+ # agent1: ready
146
+ # agent1: received 'Hello!' from agent0
147
+ ```
148
+
149
+ `activate` starts the container and guarantees a clean shutdown when its block exits, even if an exception is raised.
150
+
151
+ ### Proactive behavior
152
+
153
+ Agents are not limited to reacting to messages. `schedule_periodic_task` registers a coroutine that is called repeatedly at a fixed interval — useful for polling, broadcasting, or any time-driven behavior:
154
+
155
+ ```python
156
+ class SensorAgent(Agent):
157
+ def __init__(self, target_addr):
158
+ super().__init__()
159
+ self.target_addr = target_addr
160
+
161
+ def on_ready(self):
162
+ # Broadcast a reading every 5 seconds of (simulated) time.
163
+ self.schedule_periodic_task(self._broadcast, delay=5.0)
164
+
165
+ async def _broadcast(self):
166
+ await self.send_message("temperature: 22.5 C", self.target_addr)
167
+ ```
168
+
169
+ ---
170
+
171
+ ## Simulation
172
+
173
+ Running agents over a real network introduces timing variability that makes experiments hard to reproduce. The `SimulationWorld` eliminates this by replacing the network layer with a controlled, clock-driven execution model: time advances only when the simulation explicitly steps forward, there are no open sockets, and every run with the same inputs produces the same outputs.
174
+
175
+ ```
176
+ ┌──────────────────────────────────────────────────────┐
177
+ │ SimulationWorld │
178
+ │ │
179
+ │ ExternalClock ──► step_simulation() │
180
+ │ | │
181
+ │ ┌─────────────────┼─────────────────┐ │
182
+ │ v v v │
183
+ │ on_step() message delivery environment │
184
+ │ (all agents) (delay / loss model) .step() │
185
+ └──────────────────────────────────────────────────────┘
186
+ ```
187
+
188
+ Each step proceeds in order:
189
+
190
+ 1. All agents receive `on_step(env, clock, step_size_s)`.
191
+ 2. The environment behavior advances by `step_size_s`.
192
+ 3. The internal clock is set to the new time, waking any sleeping scheduled tasks.
193
+ 4. A convergence loop delivers all messages whose simulated arrival time has passed and waits for agents to settle between deliveries.
194
+
195
+ ### Complete example
196
+
197
+ The following self-contained script runs two agents for 60 simulated seconds and records how many readings the monitor received over time:
198
+
199
+ ```python
200
+ import asyncio
201
+ from mango import Agent, create_world, discrete_step_until, record_agent
202
+
203
+
204
+ class SensorAgent(Agent):
205
+ """Periodically sends a reading to a monitor agent."""
206
+
207
+ def __init__(self):
208
+ super().__init__()
209
+ self.monitor_addr = None # set after both agents are registered
210
+ self.readings_sent = 0
211
+
212
+ def on_ready(self):
213
+ self.schedule_periodic_task(self._broadcast, delay=10.0)
214
+
215
+ async def _broadcast(self):
216
+ await self.send_message(f"reading {self.readings_sent}", self.monitor_addr)
217
+ self.readings_sent += 1
218
+
219
+
220
+ class MonitorAgent(Agent):
221
+ """Counts incoming readings."""
222
+
223
+ def __init__(self):
224
+ super().__init__()
225
+ self.received = 0
226
+
227
+ def handle_message(self, content, meta):
228
+ self.received += 1
229
+ print(f" t={self.current_timestamp:.0f} s monitor received: {content}")
230
+
231
+
232
+ async def run():
233
+ world = create_world(start_time=0.0)
234
+ sensor = world.register(SensorAgent())
235
+ monitor = world.register(MonitorAgent())
236
+
237
+ # Set the target address before on_ready is called (inside async with).
238
+ sensor.monitor_addr = monitor.addr
239
+
240
+ # Record the running count of received messages after every step.
241
+ record_agent(world, "received", lambda a: a.received,
242
+ filter_fn=lambda a: isinstance(a, MonitorAgent))
243
+
244
+ async with world:
245
+ await discrete_step_until(world, max_advance_time_s=60.0)
246
+
247
+ print(f"\nTotal readings received: {monitor.received}")
248
+ # world.data_agent_collections["received"].timeseries holds the full time series.
249
+
250
+
251
+ asyncio.run(run())
252
+ # t=10 s monitor received: reading 0
253
+ # t=20 s monitor received: reading 1
254
+ # t=30 s monitor received: reading 2
255
+ # t=40 s monitor received: reading 3
256
+ # t=50 s monitor received: reading 4
257
+ # t=60 s monitor received: reading 5
258
+ #
259
+ # Total readings received: 6
260
+ ```
261
+
262
+ `discrete_step_until` automatically determines each step size as the time until the next scheduled event — a message arrival or a task wakeup — and stops when no further events remain within the time budget.
263
+
264
+ For experiment designs that require fixed, uniform time increments, call `step_simulation` directly:
265
+
266
+ ```python
267
+ from mango import step_simulation
268
+
269
+ async with world:
270
+ for _ in range(10):
271
+ result = await step_simulation(world, step_size_s=1.0)
272
+ print(f"t = {world.clock.time:.1f} s messages delivered: {result.messages_delivered}")
273
+ ```
274
+
275
+ ### Communication modelling
276
+
277
+ By default, messages are delivered instantly with no loss. `SimpleCommunicationSimulation` adds configurable one-way latency and independent packet loss, with optional per-link overrides:
278
+
279
+ ```python
280
+ from mango import create_world, SimpleCommunicationSimulation
281
+
282
+ world = create_world(
283
+ start_time=0.0,
284
+ communication_sim=SimpleCommunicationSimulation(
285
+ default_delay_s=0.1, # baseline one-way latency
286
+ loss_percent=0.01, # independent loss probability per message
287
+ delay_s_directed_edge_dict={
288
+ ("agent0", "agent1"): 0.5, # directed per-link override
289
+ },
290
+ ),
291
+ )
292
+ ```
293
+
294
+ For delays drawn from a distribution at runtime, use `DelayProviderCommunicationSimulation`:
295
+
296
+ ```python
297
+ import random
298
+ from mango import create_world, DelayProviderCommunicationSimulation
299
+
300
+ world = create_world(
301
+ start_time=0.0,
302
+ communication_sim=DelayProviderCommunicationSimulation(
303
+ default_delay_s_provider=lambda: random.gauss(0.1, 0.01),
304
+ ),
305
+ )
306
+ ```
307
+
308
+ Custom communication models are implemented by subclassing `CommunicationSimulation` and overriding `calculate_communication`.
309
+
310
+ ### Spatial environments
311
+
312
+ Agents can be embedded in a continuous 2-D area. Agents without a pre-assigned position are placed uniformly at random within the area during initialisation, and their positions can be recorded as a time series:
313
+
314
+ ```python
315
+ from mango import (
316
+ create_world, Area2D, DefaultEnvironment,
317
+ record_position, position_history, discrete_step_until,
318
+ )
319
+
320
+ env = DefaultEnvironment(space=Area2D(width=100.0, height=100.0))
321
+ world = create_world(start_time=0.0, environment=env)
322
+
323
+ # ... register agents ...
324
+ record_position(world)
325
+
326
+ async with world:
327
+ await discrete_step_until(world, max_advance_time_s=10.0)
328
+
329
+ history = position_history(world)
330
+ # history.timeseries["agent0"] -> [Position2D(x=..., y=...), ...]
331
+ # history.time -> [0.0, 5.0, 10.0, ...]
332
+ ```
333
+
334
+ Custom spaces and environment behaviors are implemented by subclassing `Space` and `Behavior` respectively.
335
+
336
+ ### Data recording
337
+
338
+ `record_world` and `record_agent` capture any scalar as a time series after every simulation step, without modifying agent code. Results are plain Python lists compatible with numpy, pandas, and matplotlib:
339
+
340
+ ```python
341
+ from mango import create_world, record_world, record_agent
342
+
343
+ world = create_world(start_time=0.0)
344
+ # ... register agents ...
345
+
346
+ # World-level: total messages delivered so far
347
+ record_world(world, "msg_count", lambda: len(world.recorded_messages))
348
+
349
+ # Per-agent: an arbitrary attribute
350
+ record_agent(world, "energy_kwh", lambda a: a.energy_kwh)
351
+
352
+ async with world:
353
+ await discrete_step_until(world, max_advance_time_s=3600.0)
354
+
355
+ world.data_collections["msg_count"].timeseries # list of scalars
356
+ world.data_agent_collections["energy_kwh"].timeseries # dict[aid -> list]
357
+ world.data_agent_collections["energy_kwh"].time # shared time axis
358
+ ```
359
+
360
+ All exchanged messages are also logged automatically in `world.recorded_messages` as `MessageTransaction` objects, each carrying sender, receiver, send time, and arrival time.
361
+
362
+ ### Agent hooks for simulation
363
+
364
+ Any `Agent` or `Role` subclass may override these methods to participate in the simulation lifecycle:
365
+
366
+ ```python
367
+ class MyAgent(Agent):
368
+ def on_step(self, env, clock, step_size_s: float):
369
+ """Invoked at the start of every simulation step, before the clock advances."""
370
+
371
+ def on_global_event(self, event):
372
+ """Invoked when the environment broadcasts an event to all agents."""
373
+
374
+ def on_agent_event(self, event):
375
+ """Invoked when the environment targets this specific agent."""
376
+ ```
377
+
378
+ ---
379
+
380
+ ## Documentation & Support
381
+
382
+ | Resource | Link |
383
+ |---|---|
384
+ | Full documentation | [mango-agents.readthedocs.io](https://mango-agents.readthedocs.io) |
385
+ | Issue tracker | [github.com/OFFIS-DAI/mango/issues](https://github.com/OFFIS-DAI/mango/issues) |
386
+ | Contact | [mango@offis.de](mailto:mango@offis.de) |
387
+
388
+ ---
389
+
390
+ ## License
391
+
392
+ Distributed under the [MIT License](https://github.com/OFFIS-DAI/mango/blob/development/LICENSE).
@@ -0,0 +1,102 @@
1
+ from .messages.message import create_acl, Performatives
2
+ from .agent.core import (
3
+ Agent,
4
+ AgentAddress,
5
+ AgentDescription,
6
+ ForwardingRule,
7
+ State,
8
+ TopologyNeighbor,
9
+ TopologyService,
10
+ )
11
+ from .agent.role import (
12
+ MessagePreprocessor,
13
+ Role,
14
+ RoleAgent,
15
+ RoleContext,
16
+ WaitingMessagePreprocessor,
17
+ )
18
+ from .container.factory import (
19
+ create_tcp as create_tcp_container,
20
+ create_mqtt as create_mqtt_container,
21
+ create_external_coupling as create_ec_container,
22
+ )
23
+ from .express.api import (
24
+ activate,
25
+ run_with_mqtt,
26
+ run_with_tcp,
27
+ run_with_simulation,
28
+ behavior_in,
29
+ agent_composed_of,
30
+ PrintingAgent,
31
+ sender_addr,
32
+ addr,
33
+ )
34
+ from .util.distributed_clock import DistributedClockAgent, DistributedClockManager
35
+ from .util.clock import ExternalClock, AsyncioClock
36
+ from .messages.codecs import (
37
+ json_serializable,
38
+ JSON,
39
+ PROTOBUF,
40
+ SerializationError,
41
+ )
42
+ from .express.topology import (
43
+ AgentNode,
44
+ Topology,
45
+ assign_agents,
46
+ auto_assign,
47
+ broadcast_to_neighbors,
48
+ complete_topology,
49
+ connect_topologies,
50
+ create_topology,
51
+ custom_topology,
52
+ cycle_topology,
53
+ graph_topology,
54
+ mark_as_connector,
55
+ modify_topology,
56
+ per_node,
57
+ star_topology,
58
+ topology_characteristic,
59
+ topology_connection_types,
60
+ topology_connectors,
61
+ topology_neighbors,
62
+ topology_node_id,
63
+ topology_to_aid_graph,
64
+ )
65
+ from .simulation import (
66
+ CommunicationSimulation,
67
+ CommunicationSimulationResult,
68
+ DelayProviderCommunicationSimulation,
69
+ MessagePackage,
70
+ PackageResult,
71
+ SimpleCommunicationSimulation,
72
+ create_distribution_based_com_sim,
73
+ Area2D,
74
+ Behavior,
75
+ DefaultEnvironment,
76
+ Environment,
77
+ NoSpace,
78
+ Position,
79
+ Position2D,
80
+ Space,
81
+ distance,
82
+ AgentsRecording,
83
+ DISCRETE_EVENT,
84
+ MessageTransaction,
85
+ SimulationResult,
86
+ SimulationWorld,
87
+ WorldRecording,
88
+ collect_agent_data,
89
+ collect_data,
90
+ create_world,
91
+ discrete_step_until,
92
+ position_history,
93
+ record_agent,
94
+ record_agent_having,
95
+ record_position,
96
+ record_world,
97
+ step_simulation,
98
+ plot_agents,
99
+ plot_recordings,
100
+ plot_world,
101
+ show_communication_data,
102
+ )