mail-swarms 1.3.2__py3-none-any.whl → 1.3.3__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.
mail/api.py CHANGED
@@ -748,6 +748,7 @@ class MAILSwarm:
748
748
  description: str = "",
749
749
  keywords: list[str] = [],
750
750
  enable_db_agent_histories: bool = False,
751
+ print_llm_streams: bool = True,
751
752
  ) -> None:
752
753
  self.name = name
753
754
  self.version = version
@@ -763,6 +764,7 @@ class MAILSwarm:
763
764
  self.task_message_limit = task_message_limit
764
765
  self.description = description
765
766
  self.keywords = keywords
767
+ self.print_llm_streams = print_llm_streams
766
768
  self.adjacency_matrix, self.agent_names = self._build_adjacency_matrix()
767
769
  self.supervisors = [agent for agent in agents if agent.can_complete_tasks]
768
770
  self._agent_cores = {agent.name: agent.to_core() for agent in agents}
@@ -778,6 +780,7 @@ class MAILSwarm:
778
780
  breakpoint_tools=breakpoint_tools,
779
781
  exclude_tools=exclude_tools,
780
782
  enable_db_agent_histories=enable_db_agent_histories,
783
+ print_llm_streams=print_llm_streams,
781
784
  )
782
785
  self._validate()
783
786
 
@@ -1543,6 +1546,7 @@ class MAILSwarmTemplate:
1543
1546
  user_role: Literal["admin", "agent", "user"] = "user",
1544
1547
  base_url: str = "http://localhost:8000",
1545
1548
  registry_file: str | None = None,
1549
+ print_llm_streams: bool = True,
1546
1550
  ) -> MAILSwarm:
1547
1551
  """
1548
1552
  Instantiate a MAILSwarm from a MAILSwarmTemplate.
@@ -1638,6 +1642,7 @@ class MAILSwarmTemplate:
1638
1642
  description=self.description,
1639
1643
  keywords=self.keywords,
1640
1644
  enable_db_agent_histories=self.enable_db_agent_histories,
1645
+ print_llm_streams=print_llm_streams,
1641
1646
  )
1642
1647
 
1643
1648
  def get_subswarm(
mail/cli.py CHANGED
@@ -68,10 +68,18 @@ def _run_server_with_args(args: argparse.Namespace) -> None:
68
68
  if args.swarm_registry is not None:
69
69
  swarm_overrides["registry_file"] = args.swarm_registry
70
70
 
71
+ settings_overrides: dict[str, object] = {}
72
+ if args.print_llm_streams is not None:
73
+ settings_overrides["print_llm_streams"] = args.print_llm_streams
74
+
71
75
  if swarm_overrides:
72
76
  server_overrides["swarm"] = base_config.swarm.model_copy(
73
77
  update=swarm_overrides
74
78
  )
79
+ if settings_overrides:
80
+ server_overrides["settings"] = base_config.settings.model_copy(
81
+ update=settings_overrides
82
+ )
75
83
 
76
84
  effective_config = (
77
85
  base_config.model_copy(update=server_overrides)
@@ -345,6 +353,12 @@ def main() -> None:
345
353
  required=False,
346
354
  help="registry file of the swarm",
347
355
  )
356
+ server_parser.add_argument(
357
+ "--print-llm-streams",
358
+ type=_str_to_bool,
359
+ required=False,
360
+ help="whether to print LLM reasoning/response streams to the console (true/false)",
361
+ )
348
362
 
349
363
  # command `client`
350
364
  client_parser = subparsers.add_parser("client", help="run the MAIL client")
mail/config/server.py CHANGED
@@ -68,6 +68,7 @@ def _load_defaults_from_toml() -> tuple[dict[str, Any], dict[str, Any], dict[str
68
68
  }
69
69
  settings_defaults: dict[str, Any] = {
70
70
  "task_message_limit": 15,
71
+ "print_llm_streams": True,
71
72
  }
72
73
 
73
74
  if tomllib is None:
@@ -118,6 +119,9 @@ def _load_defaults_from_toml() -> tuple[dict[str, Any], dict[str, Any], dict[str
118
119
  "task_message_limit": settings_section.get(
119
120
  "task_message_limit", settings_defaults["task_message_limit"]
120
121
  ),
122
+ "print_llm_streams": settings_section.get(
123
+ "print_llm_streams", settings_defaults["print_llm_streams"]
124
+ ),
121
125
  }
122
126
 
123
127
  logger.info(
@@ -153,6 +157,9 @@ class SettingsConfig(BaseModel):
153
157
  task_message_limit: int = Field(
154
158
  default_factory=lambda: _settings_defaults()["task_message_limit"]
155
159
  )
160
+ print_llm_streams: bool = Field(
161
+ default_factory=lambda: _settings_defaults()["print_llm_streams"]
162
+ )
156
163
 
157
164
 
158
165
  class ServerConfig(BaseModel):
mail/core/runtime.py CHANGED
@@ -94,6 +94,7 @@ class MAILRuntime:
94
94
  breakpoint_tools: list[str] | None = None,
95
95
  exclude_tools: list[str] | None = None,
96
96
  enable_db_agent_histories: bool = False,
97
+ print_llm_streams: bool = True,
97
98
  ):
98
99
  # Use a priority queue with a deterministic tiebreaker to avoid comparing dicts
99
100
  # Structure: (priority, seq, message)
@@ -142,6 +143,7 @@ class MAILRuntime:
142
143
  self.manual_return_events: dict[str, asyncio.Event] = defaultdict(asyncio.Event)
143
144
  self.manual_return_messages: dict[str, MAILMessage | None] = defaultdict(None)
144
145
  self.exclude_tools = list(exclude_tools or [])
146
+ self.print_llm_streams = print_llm_streams
145
147
  self.response_messages: dict[str, MAILMessage] = {}
146
148
  self.last_breakpoint_caller: dict[str, str] = {}
147
149
  self.last_breakpoint_tool_calls: dict[str, list[AgentToolCall]] = {}
@@ -151,6 +153,42 @@ class MAILRuntime:
151
153
  self.outstanding_requests: dict[str, dict[str, int]] = defaultdict(
152
154
  lambda: defaultdict(int)
153
155
  )
156
+ self._apply_llm_stream_settings()
157
+
158
+ def _apply_llm_stream_settings(self) -> None:
159
+ """
160
+ Best-effort propagation of LLM stream print settings to agent functions.
161
+ """
162
+ seen: set[int] = set()
163
+ for agent in self.agents.values():
164
+ self._set_llm_stream_setting(agent.function, seen)
165
+
166
+ def _set_llm_stream_setting(
167
+ self, fn: Any, seen: set[int], value: bool | None = None
168
+ ) -> None:
169
+ """
170
+ Recursively apply print_llm_streams to known agent function wrappers.
171
+ """
172
+ if fn is None:
173
+ return
174
+ fn_id = id(fn)
175
+ if fn_id in seen:
176
+ return
177
+ seen.add(fn_id)
178
+ stream_value = self.print_llm_streams if value is None else value
179
+
180
+ if hasattr(fn, "print_llm_streams"):
181
+ try:
182
+ setattr(fn, "print_llm_streams", stream_value)
183
+ except Exception: # pragma: no cover - defensive
184
+ logger.debug(
185
+ f"{self._log_prelude()} unable to update print_llm_streams on {fn}"
186
+ )
187
+
188
+ for attr in ("supervisor_fn", "action_agent_fn", "_mail_agent"):
189
+ inner = getattr(fn, attr, None)
190
+ if inner is not None:
191
+ self._set_llm_stream_setting(inner, seen, stream_value)
154
192
 
155
193
  def _log_prelude(self) -> str:
156
194
  """
mail/factories/action.py CHANGED
@@ -43,6 +43,7 @@ def action_agent_factory(
43
43
  memory: bool = True,
44
44
  use_proxy: bool = True,
45
45
  _debug_include_mail_tools: bool = True,
46
+ print_llm_streams: bool = True,
46
47
  ) -> AgentFunction:
47
48
  warnings.warn(
48
49
  "`mail.factories.action:action_agent_factory` is deprecated and will be removed in a future version. "
@@ -69,6 +70,7 @@ def action_agent_factory(
69
70
  memory=memory,
70
71
  use_proxy=use_proxy,
71
72
  _debug_include_mail_tools=_debug_include_mail_tools,
73
+ print_llm_streams=print_llm_streams,
72
74
  )
73
75
 
74
76
  async def run(
@@ -80,6 +82,8 @@ def action_agent_factory(
80
82
  """
81
83
  return await litellm_action_agent(messages, tool_choice)
82
84
 
85
+ run._mail_agent = litellm_action_agent # type: ignore[attr-defined]
86
+
83
87
  return run
84
88
 
85
89
 
@@ -159,6 +163,7 @@ class LiteLLMActionAgentFunction(ActionAgentFunction):
159
163
  use_proxy: bool = True,
160
164
  _debug_include_mail_tools: bool = True,
161
165
  stream_tokens: bool = False,
166
+ print_llm_streams: bool = True,
162
167
  default_tool_choice: str | dict[str, str] | None = None,
163
168
  ) -> None:
164
169
  super().__init__(
@@ -181,6 +186,7 @@ class LiteLLMActionAgentFunction(ActionAgentFunction):
181
186
  self.use_proxy = use_proxy
182
187
  self._debug_include_mail_tools = _debug_include_mail_tools
183
188
  self.stream_tokens = stream_tokens
189
+ self.print_llm_streams = print_llm_streams
184
190
  self.default_tool_choice = default_tool_choice
185
191
  self.action_agent_fn = LiteLLMAgentFunction(
186
192
  llm=self.llm,
@@ -201,6 +207,7 @@ class LiteLLMActionAgentFunction(ActionAgentFunction):
201
207
  exclude_tools=self.exclude_tools,
202
208
  _debug_include_mail_tools=self._debug_include_mail_tools,
203
209
  stream_tokens=self.stream_tokens,
210
+ print_llm_streams=self.print_llm_streams,
204
211
  )
205
212
 
206
213
  def __call__(
mail/factories/base.py CHANGED
@@ -57,6 +57,7 @@ def base_agent_factory(
57
57
  memory: bool = True,
58
58
  use_proxy: bool = True,
59
59
  stream_tokens: bool = False,
60
+ print_llm_streams: bool = True,
60
61
  _debug_include_mail_tools: bool = True,
61
62
  default_tool_choice: str | dict[str, str] | None = None,
62
63
  ) -> AgentFunction:
@@ -85,6 +86,7 @@ def base_agent_factory(
85
86
  memory=memory,
86
87
  use_proxy=use_proxy,
87
88
  stream_tokens=stream_tokens,
89
+ print_llm_streams=print_llm_streams,
88
90
  _debug_include_mail_tools=_debug_include_mail_tools,
89
91
  default_tool_choice=default_tool_choice,
90
92
  )
@@ -102,6 +104,8 @@ def base_agent_factory(
102
104
  tool_choice=tool_choice,
103
105
  )
104
106
 
107
+ run._mail_agent = litellm_agent # type: ignore[attr-defined]
108
+
105
109
  return run
106
110
 
107
111
 
@@ -168,6 +172,7 @@ class LiteLLMAgentFunction(MAILAgentFunction):
168
172
  memory: bool = True,
169
173
  use_proxy: bool = True,
170
174
  stream_tokens: bool = False,
175
+ print_llm_streams: bool = True,
171
176
  _debug_include_mail_tools: bool = True,
172
177
  default_tool_choice: str | dict[str, str] | None = None,
173
178
  ) -> None:
@@ -219,6 +224,7 @@ class LiteLLMAgentFunction(MAILAgentFunction):
219
224
  self.memory = memory
220
225
  self.use_proxy = use_proxy
221
226
  self.stream_tokens = stream_tokens
227
+ self.print_llm_streams = print_llm_streams
222
228
  self._debug_include_mail_tools = _debug_include_mail_tools
223
229
  self.default_tool_choice = default_tool_choice
224
230
 
@@ -903,32 +909,37 @@ class LiteLLMAgentFunction(MAILAgentFunction):
903
909
 
904
910
  if block_type == "thinking":
905
911
  if not is_reasoning:
906
- rich.print(
907
- f"\n\n[bold green]{'=' * 21} REASONING {'=' * 21}[/bold green]\n\n"
908
- )
912
+ if self.print_llm_streams:
913
+ rich.print(
914
+ f"\n\n[bold green]{'=' * 21} REASONING {'=' * 21}[/bold green]\n\n"
915
+ )
909
916
  is_reasoning = True
910
917
 
911
918
  elif block_type == "redacted_thinking":
912
919
  # Redacted thinking blocks contain encrypted content
913
920
  if not is_reasoning:
914
- rich.print(
915
- f"\n\n[bold green]{'=' * 21} REASONING {'=' * 21}[/bold green]\n\n"
916
- )
921
+ if self.print_llm_streams:
922
+ rich.print(
923
+ f"\n\n[bold green]{'=' * 21} REASONING {'=' * 21}[/bold green]\n\n"
924
+ )
917
925
  is_reasoning = True
918
- rich.print("[redacted thinking]", flush=True)
926
+ if self.print_llm_streams:
927
+ rich.print("[redacted thinking]", flush=True)
919
928
 
920
929
  elif block_type == "server_tool_use":
921
930
  if not is_searching:
922
- rich.print(
923
- f"\n\n[bold yellow]{'=' * 21} WEB SEARCH {'=' * 21}[/bold yellow]\n\n"
924
- )
931
+ if self.print_llm_streams:
932
+ rich.print(
933
+ f"\n\n[bold yellow]{'=' * 21} WEB SEARCH {'=' * 21}[/bold yellow]\n\n"
934
+ )
925
935
  is_searching = True
926
936
 
927
937
  elif block_type == "text":
928
938
  if not is_response:
929
- rich.print(
930
- f"\n\n[bold blue]{'=' * 21} RESPONSE {'=' * 21}[/bold blue]\n\n"
931
- )
939
+ if self.print_llm_streams:
940
+ rich.print(
941
+ f"\n\n[bold blue]{'=' * 21} RESPONSE {'=' * 21}[/bold blue]\n\n"
942
+ )
932
943
  is_response = True
933
944
 
934
945
  elif event_type == "content_block_delta":
@@ -938,10 +949,12 @@ class LiteLLMAgentFunction(MAILAgentFunction):
938
949
 
939
950
  if delta_type == "thinking_delta":
940
951
  assert isinstance(delta, ThinkingDelta)
941
- print(delta.thinking, end="", flush=True)
952
+ if self.print_llm_streams:
953
+ print(delta.thinking, end="", flush=True)
942
954
  elif delta_type == "text_delta":
943
955
  assert isinstance(delta, TextDelta)
944
- print(delta.text, end="", flush=True)
956
+ if self.print_llm_streams:
957
+ print(delta.text, end="", flush=True)
945
958
 
946
959
  # Get the final message with full content
947
960
  final_message = await stream.get_final_message()
@@ -1128,18 +1141,22 @@ class LiteLLMAgentFunction(MAILAgentFunction):
1128
1141
  delta = chunk.choices[0].delta
1129
1142
  if getattr(delta, "reasoning_content", None) is not None:
1130
1143
  if not is_reasoning:
1131
- rich.print(
1132
- f"\n\n[bold green]{'=' * 21} REASONING {'=' * 21}[/bold green]\n\n"
1133
- )
1144
+ if self.print_llm_streams:
1145
+ rich.print(
1146
+ f"\n\n[bold green]{'=' * 21} REASONING {'=' * 21}[/bold green]\n\n"
1147
+ )
1134
1148
  is_reasoning = True
1135
- rich.print(delta.reasoning_content, end="", flush=True)
1149
+ if self.print_llm_streams:
1150
+ rich.print(delta.reasoning_content, end="", flush=True)
1136
1151
  elif getattr(delta, "content", None) is not None:
1137
1152
  if not is_response:
1138
- rich.print(
1139
- f"\n\n[bold blue]{'=' * 21} RESPONSE {'=' * 21}[/bold blue]\n\n"
1140
- )
1153
+ if self.print_llm_streams:
1154
+ rich.print(
1155
+ f"\n\n[bold blue]{'=' * 21} RESPONSE {'=' * 21}[/bold blue]\n\n"
1156
+ )
1141
1157
  is_response = True
1142
- rich.print(delta.content, end="", flush=True)
1158
+ if self.print_llm_streams:
1159
+ rich.print(delta.content, end="", flush=True)
1143
1160
  chunks.append(chunk)
1144
1161
 
1145
1162
  final_completion = litellm.stream_chunk_builder(chunks, messages=messages)
@@ -1468,17 +1485,20 @@ class LiteLLMAgentFunction(MAILAgentFunction):
1468
1485
  async for event in stream:
1469
1486
  match event.type:
1470
1487
  case "response.created":
1471
- rich.print(
1472
- f"\n\n[bold green]{'=' * 21} REASONING {'=' * 21}[/bold green]\n\n"
1473
- )
1488
+ if self.print_llm_streams:
1489
+ rich.print(
1490
+ f"\n\n[bold green]{'=' * 21} REASONING {'=' * 21}[/bold green]\n\n"
1491
+ )
1474
1492
  case "response.reasoning_summary_text.delta":
1475
1493
  # Stream reasoning text and accumulate for mapping
1476
- rich.print(event.delta, end="", flush=True)
1494
+ if self.print_llm_streams:
1495
+ rich.print(event.delta, end="", flush=True)
1477
1496
  current_reasoning_text.append(event.delta)
1478
1497
 
1479
1498
  case "response.reasoning_summary_part.done":
1480
1499
  # Reasoning part complete - finalize the block
1481
- rich.print("\n\n")
1500
+ if self.print_llm_streams:
1501
+ rich.print("\n\n")
1482
1502
  if current_reasoning_text:
1483
1503
  pending_reasoning_parts.append("".join(current_reasoning_text))
1484
1504
  current_reasoning_text = []
@@ -1512,12 +1532,14 @@ class LiteLLMAgentFunction(MAILAgentFunction):
1512
1532
  pending_reasoning_parts = []
1513
1533
 
1514
1534
  if item_type == "message":
1515
- rich.print(
1516
- f"\n\n[bold blue]{'=' * 21} RESPONSE {'=' * 21}[/bold blue]\n\n"
1517
- )
1535
+ if self.print_llm_streams:
1536
+ rich.print(
1537
+ f"\n\n[bold blue]{'=' * 21} RESPONSE {'=' * 21}[/bold blue]\n\n"
1538
+ )
1518
1539
 
1519
1540
  case "response.output_text.delta":
1520
- rich.print(event.delta, end="", flush=True)
1541
+ if self.print_llm_streams:
1542
+ rich.print(event.delta, end="", flush=True)
1521
1543
 
1522
1544
  case "response.completed":
1523
1545
  # Defensive: flush any remaining reasoning text
@@ -46,6 +46,7 @@ def supervisor_factory(
46
46
  memory: bool = True,
47
47
  use_proxy: bool = True,
48
48
  stream_tokens: bool = False,
49
+ print_llm_streams: bool = True,
49
50
  default_tool_choice: str | dict[str, str] | None = None,
50
51
  ) -> AgentFunction:
51
52
  """
@@ -76,6 +77,7 @@ def supervisor_factory(
76
77
  tool_format=tool_format,
77
78
  exclude_tools=exclude_tools,
78
79
  stream_tokens=stream_tokens,
80
+ print_llm_streams=print_llm_streams,
79
81
  default_tool_choice=default_tool_choice,
80
82
  )
81
83
 
@@ -88,6 +90,8 @@ def supervisor_factory(
88
90
  """
89
91
  return await litellm_supervisor(messages, tool_choice)
90
92
 
93
+ run._mail_agent = litellm_supervisor # type: ignore[attr-defined]
94
+
91
95
  return run
92
96
 
93
97
 
@@ -183,6 +187,7 @@ class LiteLLMSupervisorFunction(SupervisorFunction):
183
187
  use_proxy: bool = True,
184
188
  _debug_include_mail_tools: bool = True,
185
189
  stream_tokens: bool = False,
190
+ print_llm_streams: bool = True,
186
191
  default_tool_choice: str | dict[str, str] | None = None,
187
192
  ) -> None:
188
193
  super().__init__(
@@ -205,6 +210,7 @@ class LiteLLMSupervisorFunction(SupervisorFunction):
205
210
  self.use_proxy = use_proxy
206
211
  self._debug_include_mail_tools = _debug_include_mail_tools
207
212
  self.stream_tokens = stream_tokens
213
+ self.print_llm_streams = print_llm_streams
208
214
  self.default_tool_choice = default_tool_choice
209
215
  self.supervisor_fn = LiteLLMAgentFunction(
210
216
  name=self.name,
@@ -224,6 +230,7 @@ class LiteLLMSupervisorFunction(SupervisorFunction):
224
230
  use_proxy=self.use_proxy,
225
231
  _debug_include_mail_tools=self._debug_include_mail_tools,
226
232
  stream_tokens=self.stream_tokens,
233
+ print_llm_streams=self.print_llm_streams,
227
234
  default_tool_choice=self.default_tool_choice,
228
235
  )
229
236
 
mail/server.py CHANGED
@@ -98,6 +98,7 @@ async def _server_startup(app: FastAPI) -> None:
98
98
 
99
99
  # set defaults
100
100
  app.state.debug = cfg.debug
101
+ app.state.settings = cfg.settings
101
102
 
102
103
  # swarm stuff
103
104
  app.state.persistent_swarm = ps
@@ -333,6 +334,7 @@ async def get_or_create_mail_instance(
333
334
  user_role=role,
334
335
  base_url=app.state.local_base_url,
335
336
  registry_file=app.state.swarm_registry.persistence_file,
337
+ print_llm_streams=app.state.settings.print_llm_streams,
336
338
  )
337
339
  mail_instances[id] = mail_instance
338
340
 
@@ -1553,6 +1555,7 @@ def run_server_with_template(
1553
1555
  port: int = 8000,
1554
1556
  host: str = "0.0.0.0",
1555
1557
  task_message_limit: int | None = None,
1558
+ print_llm_streams: bool = True,
1556
1559
  ) -> None:
1557
1560
  """Run MAIL server with a pre-configured swarm template.
1558
1561
 
@@ -1579,7 +1582,10 @@ def run_server_with_template(
1579
1582
  ),
1580
1583
  settings=SettingsConfig(
1581
1584
  # Use large sentinel for "unlimited" - avoids changing type throughout codebase
1582
- task_message_limit=task_message_limit if task_message_limit is not None else 999999,
1585
+ task_message_limit=task_message_limit
1586
+ if task_message_limit is not None
1587
+ else 999999,
1588
+ print_llm_streams=print_llm_streams,
1583
1589
  ),
1584
1590
  )
1585
1591
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: mail-swarms
3
- Version: 1.3.2
3
+ Version: 1.3.3
4
4
  Summary: Multi-Agent Interface Layer reference implementation
5
5
  License-Expression: Apache-2.0
6
6
  License-File: LICENSE
@@ -121,7 +121,7 @@ The runtime processes MAIL messages **asynchronously**, tracks per-task state, a
121
121
  ### Installation
122
122
  ```bash
123
123
  # Clone and enter the repository
124
- git clone https://github.com/charonlabs/mail --branch v1.3.1
124
+ git clone https://github.com/charonlabs/mail --branch v1.3.3
125
125
  cd mail
126
126
 
127
127
  # Install dependencies (preferred)
@@ -150,7 +150,7 @@ export ANTHROPIC_API_KEY=sk-your-anthropic-key
150
150
  export DATABASE_URL=postgresql://...
151
151
  ```
152
152
 
153
- Defaults for host, port, swarm metadata, and client behaviour are loaded from [`mail.toml`](mail.toml). The `[server.settings]` table exposes `task_message_limit`, which bounds how many messages the runtime will process per task when `run_continuous` is active (default `15`). Override the file or point `MAIL_CONFIG_PATH` at an alternate TOML to adjust these values per environment. Use `mail server --swarm-name/--swarm-source/--swarm-registry` (or edit `mail.toml`) to change swarm identity; `mail server` exports `SWARM_NAME`, `SWARM_SOURCE`, `SWARM_REGISTRY_FILE`, and `BASE_URL` for downstream tools but does not read them as config overrides.
153
+ Defaults for host, port, swarm metadata, and client behaviour are loaded from [`mail.toml`](mail.toml). The `[server.settings]` table exposes `task_message_limit`, which bounds how many messages the runtime will process per task when `run_continuous` is active (default `15`), and `print_llm_streams` (default `true`), which controls whether runtime-managed agents print LLM reasoning/response stream chunks to server stdout. Set `print_llm_streams=false` (or pass `mail server --print-llm-streams false`) for quieter server logs; task/event SSE streaming is unaffected. Override the file or point `MAIL_CONFIG_PATH` at an alternate TOML to adjust these values per environment. Use CLI flags such as `--swarm-name`, `--swarm-source`, `--swarm-registry`, and `--print-llm-streams true|false` (or edit `mail.toml`) to override these at launch; `mail server` exports `SWARM_NAME`, `SWARM_SOURCE`, `SWARM_REGISTRY_FILE`, and `BASE_URL` for downstream tools but does not read them as config overrides.
154
154
 
155
155
  MAIL will create the parent directory for `SWARM_REGISTRY_FILE` on startup if it is missing, so you can rely on the default `registries/` path without committing the folder.
156
156
 
@@ -1,18 +1,18 @@
1
1
  mail/__init__.py,sha256=Rj44tvgXvcEjx_-l2aBilzCmrCdzLPXMREP-KNj0uZk,600
2
- mail/api.py,sha256=CoF8EZphMl9cs56WanH51jERE1bgx93vRccrzK0f7a8,73976
3
- mail/cli.py,sha256=LvU2_OR37R7-iMullRziK8GBx_SMfNPrkek_-kqsEP8,12670
2
+ mail/api.py,sha256=_H5eng3Rbcocmy7dA36UWejET5xakF0AhGqEZriMTm8,74205
3
+ mail/cli.py,sha256=dvNYsrv8_tU_YXkwAo27sPyPmnGTKYz5tTBqE3vvsDE,13221
4
4
  mail/client.py,sha256=igbcjGlz2Z-9LvGHf_qyACfVdeMVLnFuMXaMn740daY,56909
5
- mail/server.py,sha256=NFANKkk0L19BKrxk1UkXaaWs7XQjOQWiN5F9cg9Ezh0,55966
5
+ mail/server.py,sha256=xc5OUUsLTTBTXxZMNqnWPIEASY9CFDz0ArR--razDY4,56185
6
6
  mail/summarizer.py,sha256=clG4d1mcSHmGagvKva_P3trw46sd2XJPJ7lJ_o-e0qM,7468
7
7
  mail/url_scheme.py,sha256=RRqXuIzmQAq_depvn1-bht9yEnTgxPy8R2s_8FbDF9M,1229
8
8
  mail/config/__init__.py,sha256=bP2yX8fTyRm5Iv362uiQBf18rsh9H7coNoPtbpZJAeU,153
9
9
  mail/config/client.py,sha256=aFuCqqvGnZQsDDqAi6aaWIjU8o3OPc41PkDAqYtnPZs,2581
10
- mail/config/server.py,sha256=u1bJzu1IBA9kpuztY1oWObpUxPrVXh8e9NmogWubhok,5829
10
+ mail/config/server.py,sha256=w5P_Cf9WbG4nzoMPQC4hGhq8yeRURgedCbycgHf9tMo,6151
11
11
  mail/core/__init__.py,sha256=v85xchqjsprvsOUUyf3lxdD0_89Il3TEQE2sMyJyk0I,1833
12
12
  mail/core/actions.py,sha256=ZwXfceB-6aNrCEjcwOreUTxku2nTuh22_pemqY-cDWE,2249
13
13
  mail/core/agents.py,sha256=hiCugGB8t3XicdiPmNWBd9Yfn1FqBJoAYNWao9Joy74,2084
14
14
  mail/core/message.py,sha256=q70d0b5GB8YHMTCMrdvWhyTRDlazfydbc-5sktBqeUY,10812
15
- mail/core/runtime.py,sha256=rCsU8SUZwMXZ9yOAlMkB8B0nm6ONd8sR740zerdjBGw,154773
15
+ mail/core/runtime.py,sha256=7w_XtYf1zt38x7YppZmfnOZYR-mOzfvSE8YivYy-L-M,156171
16
16
  mail/core/tasks.py,sha256=CUtc8SQIoAuvBhqSl6uPPCI-bVWbG538EOH6optDzyw,10048
17
17
  mail/core/tools.py,sha256=DMrUme5gBgoMbR2Tv3aE_pTAumHNAKRTqW2ganPI1uc,42993
18
18
  mail/db/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
@@ -95,9 +95,9 @@ mail/examples/weather_dummy/agent.py,sha256=ehoMg_0fXZcRYJ9VfsSwpKwxyG4mSvjBlyHU
95
95
  mail/examples/weather_dummy/prompts.py,sha256=sCAeGktBbSf_RGWkC1CKHLlLidura86hyOE7tF5UPRY,1586
96
96
  mail/examples/weather_dummy/types.py,sha256=rWNU2Fz_1LJdm54iyzBgy3H_Mx6IzIsdpA_ofTO56OM,164
97
97
  mail/factories/__init__.py,sha256=qcUcc_ZHQzpk4pgdydZxhmv3HQLumoazGOjm5tEn6Zg,569
98
- mail/factories/action.py,sha256=35AACPNWYcht6dyC9W5fmWTpajTXJpXweSmF34E99oY,7298
99
- mail/factories/base.py,sha256=UgWiDnxu52uS1mU2GXIAXhEBODYI5V_QI_fr1Fc6BSs,61476
100
- mail/factories/supervisor.py,sha256=smo67Gf09c-LCtK_ueq9LuLRxu6bKqzpBEjjoY6-hWY,7935
98
+ mail/factories/action.py,sha256=5gB6vsW8XY07jAUV-n8WQA6dBcCeQPPtNhALk5zfnJs,7598
99
+ mail/factories/base.py,sha256=lzUk9f-oj0sVYpmz7dtU02LVosfD229kAkVPDWs-nPM,62663
100
+ mail/factories/supervisor.py,sha256=OuteeG97jfpStyLKaapwPzhqWqCg6IFuj1AAZZOX57w,8233
101
101
  mail/net/__init__.py,sha256=s6obszeuL0nMHsfR9zROMKi1aRDAwtf1XXB5z6jqtJE,133
102
102
  mail/net/registry.py,sha256=rP-_E53JC9iyt83SzDKlRHHR6pSmBm38sjx9XiCxnwQ,27894
103
103
  mail/net/router.py,sha256=gc2wB_hgWL8WJmZryZQPT0tslbO9Dtct7IpFCa2RKGE,28729
@@ -128,10 +128,10 @@ mail/utils/serialize.py,sha256=S-nqIwodDXZrsgHDrBg2ndur4fMnmFXKRf8kKl_Z0yc,9753
128
128
  mail/utils/store.py,sha256=VJ9GoHjFWcWeDWoOwS7Ujh-8rHqxvMQtGJDg2XA1ekI,1495
129
129
  mail/utils/string_builder.py,sha256=eAlGUzfKqxgfsAIJfpSoFlZ2hqP2PvSVnNE5FxjprII,4516
130
130
  mail/utils/version.py,sha256=nROAkYcqiff1U-58EPkCaGQ-OrSogu1IRnq7cPrU1EA,605
131
- mail_swarms-1.3.2.dist-info/METADATA,sha256=vAISDuYbLzBvGkZwNuElciZVIvMyMt2n1q3aSPQXUDw,13751
132
- mail_swarms-1.3.2.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
133
- mail_swarms-1.3.2.dist-info/entry_points.txt,sha256=vgOgm2rAG5-LvkCG6vHYyrL6RNkoOvTLM0zLHAXUEgY,39
134
- mail_swarms-1.3.2.dist-info/licenses/LICENSE,sha256=9g90ibSFxcR9tnPkhYkH7-Bpa9oXBfiHD-spD1_KtZ4,10259
135
- mail_swarms-1.3.2.dist-info/licenses/NOTICE,sha256=yp2jlUSYD9Yn-jrK_hyiE3wJzzQe2xbS92a2dLceU7A,327
136
- mail_swarms-1.3.2.dist-info/licenses/THIRD_PARTY_NOTICES.md,sha256=YNG-XYwsk_h0Suf1SxL7L_rRcyG6C-HpKrsGXw3nbF8,596162
137
- mail_swarms-1.3.2.dist-info/RECORD,,
131
+ mail_swarms-1.3.3.dist-info/METADATA,sha256=zZAvUEIaJSmlVquixWw1geKNVrGW7MS2KXSfpXGNqeU,14098
132
+ mail_swarms-1.3.3.dist-info/WHEEL,sha256=WLgqFyCfm_KASv4WHyYy0P3pM_m7J5L9k2skdKLirC8,87
133
+ mail_swarms-1.3.3.dist-info/entry_points.txt,sha256=vgOgm2rAG5-LvkCG6vHYyrL6RNkoOvTLM0zLHAXUEgY,39
134
+ mail_swarms-1.3.3.dist-info/licenses/LICENSE,sha256=9g90ibSFxcR9tnPkhYkH7-Bpa9oXBfiHD-spD1_KtZ4,10259
135
+ mail_swarms-1.3.3.dist-info/licenses/NOTICE,sha256=yp2jlUSYD9Yn-jrK_hyiE3wJzzQe2xbS92a2dLceU7A,327
136
+ mail_swarms-1.3.3.dist-info/licenses/THIRD_PARTY_NOTICES.md,sha256=WwhEdrdgrU_iVVVo4h9NeFhDqHcQlxC8ejDIYysP5hc,596162
137
+ mail_swarms-1.3.3.dist-info/RECORD,,
@@ -5124,14 +5124,14 @@ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
5124
5124
  SOFTWARE.
5125
5125
  ```
5126
5126
 
5127
- ## `mail-swarms==1.3.2`
5127
+ ## `mail-swarms==1.3.3`
5128
5128
  Multi-Agent Interface Layer reference implementation
5129
5129
  ### License field:
5130
5130
  Apache-2.0
5131
5131
  ### Classifiers:
5132
5132
  License :: OSI Approved :: Apache Software License
5133
5133
 
5134
- ### License Text (`mail_swarms-1.3.2.dist-info/licenses/LICENSE`)
5134
+ ### License Text (`mail_swarms-1.3.3.dist-info/licenses/LICENSE`)
5135
5135
 
5136
5136
  ```text
5137
5137
  Apache License
@@ -5337,7 +5337,7 @@ See the License for the specific language governing permissions and
5337
5337
  limitations under the License.
5338
5338
  ```
5339
5339
 
5340
- ### License Text (`mail_swarms-1.3.2.dist-info/licenses/NOTICE`)
5340
+ ### License Text (`mail_swarms-1.3.3.dist-info/licenses/NOTICE`)
5341
5341
 
5342
5342
  ```text
5343
5343
  MAIL Project