mail-swarms 1.3.2__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 (137) hide show
  1. mail/__init__.py +35 -0
  2. mail/api.py +1964 -0
  3. mail/cli.py +432 -0
  4. mail/client.py +1657 -0
  5. mail/config/__init__.py +8 -0
  6. mail/config/client.py +87 -0
  7. mail/config/server.py +165 -0
  8. mail/core/__init__.py +72 -0
  9. mail/core/actions.py +69 -0
  10. mail/core/agents.py +73 -0
  11. mail/core/message.py +366 -0
  12. mail/core/runtime.py +3537 -0
  13. mail/core/tasks.py +311 -0
  14. mail/core/tools.py +1206 -0
  15. mail/db/__init__.py +0 -0
  16. mail/db/init.py +182 -0
  17. mail/db/types.py +65 -0
  18. mail/db/utils.py +523 -0
  19. mail/examples/__init__.py +27 -0
  20. mail/examples/analyst_dummy/__init__.py +15 -0
  21. mail/examples/analyst_dummy/agent.py +136 -0
  22. mail/examples/analyst_dummy/prompts.py +44 -0
  23. mail/examples/consultant_dummy/__init__.py +15 -0
  24. mail/examples/consultant_dummy/agent.py +136 -0
  25. mail/examples/consultant_dummy/prompts.py +42 -0
  26. mail/examples/data_analysis/__init__.py +40 -0
  27. mail/examples/data_analysis/analyst/__init__.py +9 -0
  28. mail/examples/data_analysis/analyst/agent.py +67 -0
  29. mail/examples/data_analysis/analyst/prompts.py +53 -0
  30. mail/examples/data_analysis/processor/__init__.py +13 -0
  31. mail/examples/data_analysis/processor/actions.py +293 -0
  32. mail/examples/data_analysis/processor/agent.py +67 -0
  33. mail/examples/data_analysis/processor/prompts.py +48 -0
  34. mail/examples/data_analysis/reporter/__init__.py +10 -0
  35. mail/examples/data_analysis/reporter/actions.py +187 -0
  36. mail/examples/data_analysis/reporter/agent.py +67 -0
  37. mail/examples/data_analysis/reporter/prompts.py +49 -0
  38. mail/examples/data_analysis/statistics/__init__.py +18 -0
  39. mail/examples/data_analysis/statistics/actions.py +343 -0
  40. mail/examples/data_analysis/statistics/agent.py +67 -0
  41. mail/examples/data_analysis/statistics/prompts.py +60 -0
  42. mail/examples/mafia/__init__.py +0 -0
  43. mail/examples/mafia/game.py +1537 -0
  44. mail/examples/mafia/narrator_tools.py +396 -0
  45. mail/examples/mafia/personas.py +240 -0
  46. mail/examples/mafia/prompts.py +489 -0
  47. mail/examples/mafia/roles.py +147 -0
  48. mail/examples/mafia/spec.md +350 -0
  49. mail/examples/math_dummy/__init__.py +23 -0
  50. mail/examples/math_dummy/actions.py +252 -0
  51. mail/examples/math_dummy/agent.py +136 -0
  52. mail/examples/math_dummy/prompts.py +46 -0
  53. mail/examples/math_dummy/types.py +5 -0
  54. mail/examples/research/__init__.py +39 -0
  55. mail/examples/research/researcher/__init__.py +9 -0
  56. mail/examples/research/researcher/agent.py +67 -0
  57. mail/examples/research/researcher/prompts.py +54 -0
  58. mail/examples/research/searcher/__init__.py +10 -0
  59. mail/examples/research/searcher/actions.py +324 -0
  60. mail/examples/research/searcher/agent.py +67 -0
  61. mail/examples/research/searcher/prompts.py +53 -0
  62. mail/examples/research/summarizer/__init__.py +18 -0
  63. mail/examples/research/summarizer/actions.py +255 -0
  64. mail/examples/research/summarizer/agent.py +67 -0
  65. mail/examples/research/summarizer/prompts.py +55 -0
  66. mail/examples/research/verifier/__init__.py +10 -0
  67. mail/examples/research/verifier/actions.py +337 -0
  68. mail/examples/research/verifier/agent.py +67 -0
  69. mail/examples/research/verifier/prompts.py +52 -0
  70. mail/examples/supervisor/__init__.py +11 -0
  71. mail/examples/supervisor/agent.py +4 -0
  72. mail/examples/supervisor/prompts.py +93 -0
  73. mail/examples/support/__init__.py +33 -0
  74. mail/examples/support/classifier/__init__.py +10 -0
  75. mail/examples/support/classifier/actions.py +307 -0
  76. mail/examples/support/classifier/agent.py +68 -0
  77. mail/examples/support/classifier/prompts.py +56 -0
  78. mail/examples/support/coordinator/__init__.py +9 -0
  79. mail/examples/support/coordinator/agent.py +67 -0
  80. mail/examples/support/coordinator/prompts.py +48 -0
  81. mail/examples/support/faq/__init__.py +10 -0
  82. mail/examples/support/faq/actions.py +182 -0
  83. mail/examples/support/faq/agent.py +67 -0
  84. mail/examples/support/faq/prompts.py +42 -0
  85. mail/examples/support/sentiment/__init__.py +15 -0
  86. mail/examples/support/sentiment/actions.py +341 -0
  87. mail/examples/support/sentiment/agent.py +67 -0
  88. mail/examples/support/sentiment/prompts.py +54 -0
  89. mail/examples/weather_dummy/__init__.py +23 -0
  90. mail/examples/weather_dummy/actions.py +75 -0
  91. mail/examples/weather_dummy/agent.py +136 -0
  92. mail/examples/weather_dummy/prompts.py +35 -0
  93. mail/examples/weather_dummy/types.py +5 -0
  94. mail/factories/__init__.py +27 -0
  95. mail/factories/action.py +223 -0
  96. mail/factories/base.py +1531 -0
  97. mail/factories/supervisor.py +241 -0
  98. mail/net/__init__.py +7 -0
  99. mail/net/registry.py +712 -0
  100. mail/net/router.py +728 -0
  101. mail/net/server_utils.py +114 -0
  102. mail/net/types.py +247 -0
  103. mail/server.py +1605 -0
  104. mail/stdlib/__init__.py +0 -0
  105. mail/stdlib/anthropic/__init__.py +0 -0
  106. mail/stdlib/fs/__init__.py +15 -0
  107. mail/stdlib/fs/actions.py +209 -0
  108. mail/stdlib/http/__init__.py +19 -0
  109. mail/stdlib/http/actions.py +333 -0
  110. mail/stdlib/interswarm/__init__.py +11 -0
  111. mail/stdlib/interswarm/actions.py +208 -0
  112. mail/stdlib/mcp/__init__.py +19 -0
  113. mail/stdlib/mcp/actions.py +294 -0
  114. mail/stdlib/openai/__init__.py +13 -0
  115. mail/stdlib/openai/agents.py +451 -0
  116. mail/summarizer.py +234 -0
  117. mail/swarms_json/__init__.py +27 -0
  118. mail/swarms_json/types.py +87 -0
  119. mail/swarms_json/utils.py +255 -0
  120. mail/url_scheme.py +51 -0
  121. mail/utils/__init__.py +53 -0
  122. mail/utils/auth.py +194 -0
  123. mail/utils/context.py +17 -0
  124. mail/utils/logger.py +73 -0
  125. mail/utils/openai.py +212 -0
  126. mail/utils/parsing.py +89 -0
  127. mail/utils/serialize.py +292 -0
  128. mail/utils/store.py +49 -0
  129. mail/utils/string_builder.py +119 -0
  130. mail/utils/version.py +20 -0
  131. mail_swarms-1.3.2.dist-info/METADATA +237 -0
  132. mail_swarms-1.3.2.dist-info/RECORD +137 -0
  133. mail_swarms-1.3.2.dist-info/WHEEL +4 -0
  134. mail_swarms-1.3.2.dist-info/entry_points.txt +2 -0
  135. mail_swarms-1.3.2.dist-info/licenses/LICENSE +202 -0
  136. mail_swarms-1.3.2.dist-info/licenses/NOTICE +10 -0
  137. mail_swarms-1.3.2.dist-info/licenses/THIRD_PARTY_NOTICES.md +12334 -0
mail/utils/store.py ADDED
@@ -0,0 +1,49 @@
1
+ # SPDX-License-Identifier: Apache-2.0
2
+ # Copyright (c) Jacob Hahn
3
+
4
+ import contextlib
5
+ import os
6
+
7
+ try:
8
+ from langgraph.store.postgres.aio import ( # type: ignore
9
+ AsyncPostgresStore,
10
+ PostgresIndexConfig,
11
+ )
12
+
13
+ POSTGRES_AVAILABLE = True
14
+ except ImportError:
15
+ POSTGRES_AVAILABLE = False
16
+ # Fallback to in-memory store
17
+ from langgraph.store.memory import InMemoryStore
18
+
19
+
20
+ @contextlib.asynccontextmanager
21
+ async def get_langmem_store():
22
+ """Async context manager for memory store operations."""
23
+ if POSTGRES_AVAILABLE:
24
+ # Get and prepare connection string
25
+ conn_string = os.getenv("DATABASE_URL", "none")
26
+ if conn_string == "none":
27
+ raise ValueError("DATABASE_URL is not set")
28
+
29
+ # Replace asyncpg with regular postgres driver and add schema
30
+ conn_string = conn_string.replace("postgresql+asyncpg://", "postgresql://")
31
+ conn_string = conn_string + "?options=-csearch_path%3Dlangmem,public"
32
+
33
+ index_config = PostgresIndexConfig(
34
+ dims=1536,
35
+ embed="openai:text-embedding-3-small",
36
+ )
37
+
38
+ async with AsyncPostgresStore.from_conn_string(
39
+ conn_string, index=index_config
40
+ ) as store:
41
+ yield store
42
+ else:
43
+ # Fallback to in-memory store
44
+ store = InMemoryStore()
45
+ try:
46
+ yield store
47
+ finally:
48
+ # InMemoryStore doesn't need explicit cleanup, but we keep the context manager pattern
49
+ pass
@@ -0,0 +1,119 @@
1
+ # SPDX-License-Identifier: Apache-2.0
2
+ # Copyright (c) 2025 Addison Kline
3
+
4
+ from pathlib import Path
5
+
6
+ from mail.core.tools import get_tool_help
7
+
8
+ SPEC_PATH = Path(__file__).resolve().parents[3] / "spec" / "SPEC.md"
9
+
10
+
11
+ def build_mail_help_string(
12
+ name: str,
13
+ swarm: str,
14
+ get_summary: bool = True,
15
+ get_identity: bool = False,
16
+ get_tool_help: list[str] | None = None,
17
+ get_full_protocol: bool = False,
18
+ ) -> str:
19
+ """
20
+ Build the string used by the MAIL `help` tool.
21
+ """
22
+ string = ""
23
+ if get_summary:
24
+ string += _get_summary()
25
+ if get_identity:
26
+ string += _get_identity(name, swarm)
27
+ if get_tool_help:
28
+ string += _get_tool_help(get_tool_help)
29
+ if get_full_protocol:
30
+ string += _get_full_protocol()
31
+
32
+ return string.strip()
33
+
34
+
35
+ def _get_summary() -> str:
36
+ """
37
+ Get a summary of MAIL.
38
+ This is included in the `help` tool's output by default.
39
+ """
40
+ return _create_section("summary", SUMMARY_STRING)
41
+
42
+
43
+ def _get_identity(name: str, swarm: str) -> str:
44
+ """
45
+ Get the identity of the agent.
46
+ """
47
+ return _create_section(
48
+ "your identity", IDENTITY_STRING.format(name=name, swarm=swarm)
49
+ )
50
+
51
+
52
+ def _get_tool_help(tool_help: list[str] | None = None) -> str:
53
+ """
54
+ Get the help for the given tools.
55
+ """
56
+ tool_help = tool_help or []
57
+ return _create_section("tool help", f"\n{get_tool_help(tool_help)}")
58
+
59
+
60
+ def _get_full_protocol() -> str:
61
+ """
62
+ Get the full MAIL protocol specification.
63
+ """
64
+ if SPEC_PATH.is_file():
65
+ content = SPEC_PATH.read_text(encoding="utf-8")
66
+ else:
67
+ content = "The MAIL protocol specification could not be located on disk."
68
+ return _create_section("full MAIL protocol specification", content)
69
+
70
+
71
+ def _create_section(title: str, content: str, capitalize: bool = True) -> str:
72
+ """
73
+ Create a section of the `help` tool's output in a pseudo-Markdown format.
74
+ """
75
+ return f"===== {title.upper() if capitalize else title} =====\n\n{content}\n\n"
76
+
77
+
78
+ SUMMARY_STRING = """
79
+ You are an agent that is part of a swarm following the MAIL (Multi-Agent Interface Layer) protocol.
80
+ MAIL defines a set of tools that allow you to communicate with other agents in an email-like syntax.
81
+ You may be given 'actions' (third-party tools) that you can use to perform tasks that are outside the scope of MAIL.
82
+ These tool calls are processed by an asynchronous message queue in the runtime that operates until a user-specified task is complete.
83
+
84
+ # MAIL Tools
85
+ MAIL defines a suite of core tools that mirror the functionality of email.
86
+ Examples include `send_request`, `send_broadcast`, and `await_message`.
87
+ These tool calls are processed by the runtime and their functions are executed.
88
+ Note that the tool call responses for message-sending calls (`send_request`, `send_response`, `send_interrupt`, `send_broadcast`) are indicators of whether or not the operation was successful.
89
+ A message response is NOT part of the tool call response--if one exists, it will be served to you in a subsequent prompt.
90
+
91
+ # Actions
92
+ You may have access to actions, which are third-party tools that you can use to perform tasks that are outside the scope of MAIL.
93
+ These actions are functionally identical to MAIL tools and are called in the same way.
94
+ Examples of possible actions include `web_search`, `code_interpreter`, and `file_manager`.
95
+ The result of an action call will be part of the tool call response; you will be reprompted by the runtime with an '::action_complete_broadcast::'.
96
+
97
+ # User Tasks
98
+ A MAIL swarm works by having a user specify a task for the swarm to complete.
99
+ Said task is defined by a message from the user to an entrypoint agent in the swarm.
100
+ The swarm will then run until `task_complete` is called by an agent capable of doing so.
101
+ Note that a user may resume a task after it has been completed--this enables multi-turn conversations between the user and the swarm.
102
+ Resumed tasks operate the same way as new tasks; they will run until `task_complete` is called.
103
+
104
+ # Tips
105
+ - To view your identity (agent name, swarm, etc.), call the `help` tool with `get_identity=True`.
106
+ - To view the full MAIL protocol specification, call the `help` tool with `get_full_protocol=True`.
107
+
108
+ # Notes
109
+ This summary message is included in the `help` tool's output by default.
110
+ You can disable it by calling the `help` tool with `get_summary=False`.
111
+ """
112
+
113
+
114
+ IDENTITY_STRING = """
115
+ **Name**: {name}
116
+ **Swarm**: {swarm}
117
+ **Local Address**: {name} (same as name)
118
+ **Interswarm Address**: {name}@{swarm}
119
+ """
mail/utils/version.py ADDED
@@ -0,0 +1,20 @@
1
+ # SPDX-License-Identifier: Apache-2.0
2
+ # Copyright (c) 2025 Addison Kline
3
+
4
+ from toml import load as load_toml
5
+
6
+
7
+ def get_version() -> str:
8
+ """
9
+ Get the current version of the MAIL reference implementation.
10
+ """
11
+ return load_toml("pyproject.toml")["project"]["version"]
12
+
13
+
14
+ def get_protocol_version() -> str:
15
+ """
16
+ Get the current protocol version of the MAIL reference implementation.
17
+ If the ref-impl version is `x.y.z`, the protocol version is `x.y`.
18
+ """
19
+ version = load_toml("pyproject.toml")["project"]["version"]
20
+ return f"{version.split('.')[0]}.{version.split('.')[1]}"
@@ -0,0 +1,237 @@
1
+ Metadata-Version: 2.4
2
+ Name: mail-swarms
3
+ Version: 1.3.2
4
+ Summary: Multi-Agent Interface Layer reference implementation
5
+ License-Expression: Apache-2.0
6
+ License-File: LICENSE
7
+ License-File: NOTICE
8
+ License-File: THIRD_PARTY_NOTICES.md
9
+ Classifier: License :: OSI Approved :: Apache Software License
10
+ Requires-Python: >=3.12
11
+ Requires-Dist: aiohttp>=3.9.0
12
+ Requires-Dist: asyncpg>=0.31.0
13
+ Requires-Dist: dict2xml>=1.7.7
14
+ Requires-Dist: fastapi>=0.104.1
15
+ Requires-Dist: fastmcp>=2.12.5
16
+ Requires-Dist: langchain-core>=0.3.72
17
+ Requires-Dist: langchain>=0.3.27
18
+ Requires-Dist: langgraph>=0.6.3
19
+ Requires-Dist: langmem>=0.0.29
20
+ Requires-Dist: litellm>=1.76.2
21
+ Requires-Dist: numpydoc>=1.9.0
22
+ Requires-Dist: openai>=1.106.1
23
+ Requires-Dist: pydantic>=2.11.7
24
+ Requires-Dist: pyjwt>=2.10.1
25
+ Requires-Dist: rich>=13.0.0
26
+ Requires-Dist: sse-starlette>=3.0.2
27
+ Requires-Dist: toml>=0.10.2
28
+ Requires-Dist: types-toml>=0.10.8.20240310
29
+ Requires-Dist: types-ujson>=5.10.0.20250822
30
+ Requires-Dist: ujson>=5.8.0
31
+ Requires-Dist: uvicorn>=0.24.0
32
+ Description-Content-Type: text/markdown
33
+
34
+ # Multi-Agent Interface Layer (MAIL)
35
+
36
+ Single-swarm example | Multi-swarm example
37
+ :-------------------:|:-------------------:
38
+ ![](/assets/mail.png)| ![](/assets/interswarm.png)
39
+
40
+ **MAIL** is an **open protocol** for letting autonomous agents communicate, coordinate, and cooperate across local runtimes and distributed swarms. This repository hosts both the normative specification and a production-grade **Python/FastAPI reference implementation** that demonstrate how to build interoperable agent systems on top of the MAIL contract.
41
+
42
+ ---
43
+
44
+ ## Quick Links
45
+ - **Protocol specification**: [spec/SPEC.md](/spec/SPEC.md)
46
+ - **JSON Schemas**: [spec/MAIL-core.schema.json](/spec/MAIL-core.schema.json), [spec/MAIL-interswarm.schema.json](/spec/MAIL-interswarm.schema.json)
47
+ - **REST transport** (OpenAPI 3.1): [spec/openapi.yaml](/spec/openapi.yaml)
48
+ - **Reference implementation source**: [src/mail/](/src/mail/__init__.py)
49
+ - **Command-line interface**: [docs/cli.md](/docs/cli.md), `uv run mail …`
50
+ - **Asynchronous HTTP client**: [docs/client.md](/docs/client.md), [src/mail/client.py](/src/mail/client.py)
51
+ - **Deployment examples and docs**: [docs/](/docs/README.md)
52
+
53
+ ## 1. MAIL Protocol Overview
54
+
55
+ ### Goals
56
+ - Provide a transport-agnostic **message contract** so agents from different vendors can interoperate.
57
+ - Encode **routing, addressing, and task lifecycle semantics** that work for single-swarm and cross-swarm topologies.
58
+ - Support reliable inter-swarm federation over **standard HTTP** infrastructure.
59
+ - Remain **minimal enough** to embed inside bespoke agent runtimes or platform orchestrators.
60
+
61
+ ### Message Primitives
62
+ MAIL defines five core message types that all conforming systems MUST understand. Each payload is validated against `MAIL-core.schema.json`.
63
+
64
+ | `msg_type` | Required payload fields | Typical use case |
65
+ |----------------------|-------------------------------------------------------------------------------------------|---------------------------------------------------|
66
+ | `request` | `task_id`, `request_id`, `sender`, `recipient`, `subject`, `body` | Agent-to-agent task delegation |
67
+ | `response` | `task_id`, `request_id`, `sender`, `recipient`, `subject`, `body` | Reply that correlates with a prior request |
68
+ | `broadcast` | `task_id`, `broadcast_id`, `sender`, `recipients[]`, `subject`, `body` | Notify many agents in a swarm |
69
+ | `interrupt` | `task_id`, `interrupt_id`, `sender`, `recipients[]`, `subject`, `body` | High-priority stop/alter instructions |
70
+ | `broadcast_complete` | `task_id`, `broadcast_id`, `sender`, `recipients[]`, `subject`, `body` (MAILBroadcast) | Marks task completion by a supervisor agent |
71
+
72
+ All messages are wrapped in a `MAILMessage` envelope with an `id` (UUID) and RFC 3339 timestamp. Optional fields such as `sender_swarm`, `recipient_swarm`, and `routing_info` carry federation metadata without altering the core contract.
73
+
74
+ ### Addressing & Routing
75
+ - **Local agents** are addressed by name (`agent-name`).
76
+ - **Interswarm addresses** append the remote swarm (`agent-name@swarm-name`).
77
+ - **Routers** MUST wrap cross-swarm traffic in a `MAILInterswarmMessage` that includes source/target swarm identifiers and optional metadata.
78
+ - **Priority tiers** ensure urgent system and user messages preempt regular agent chatter. Within a tier, messages are FIFO by enqueue sequence.
79
+
80
+ ### Transport Requirements
81
+ - The **normative HTTP binding** is published in [spec/openapi.yaml](/spec/openapi.yaml) and implemented by the reference **FastAPI** service.
82
+ - **`/message`** handles user tasks and local agent traffic. **`/tasks`** returns the caller's in-flight and completed tasks, and **`/task`** fetches a specific task record by ID. **`/interswarm/forward`** / **`/interswarm/back`** move agent traffic between swarms, and **`/interswarm/message`** proxies user/admin requests to a remote swarm.
83
+ - Implementations MUST replay responses from remote swarms back into the local queue to complete task lifecycles.
84
+
85
+ ### Conformance & Validation
86
+ - Use the **included JSON Schemas** for request/response validation in any runtime.
87
+ - Run **`uv run spec/validate_samples.py`** to check sample payloads against the schemas.
88
+ - Terms defined in the spec follow RFC 2119/RFC 8174 keywords.
89
+
90
+ ## 2. Reference Implementation
91
+
92
+ ### Key Features
93
+ - **Persistent swarm runtime** with pluggable agents, tools, and memory backends.
94
+ - **Task resume safety** via automatic queue snapshots that stash pending task messages on completion/breakpoints and restore them when the user resumes work.
95
+ - **FastAPI HTTP server** exposing REST endpoints, **Server-Sent Events (SSE)** streams, and **interswarm messaging** routes.
96
+ - **Task introspection API** surfaces `GET /tasks` and `GET /task` so callers can audit active work, inspect SSE timelines, and resume confidently from any state.
97
+ - **CLI launcher** (`mail server`, `mail client`) for running the server and an interactive REPL without writing code.
98
+ - **Async MAIL client** (`MAILClient`) mirroring the REST API with SSE helpers for quick integrations.
99
+ - Built-in **swarm registry** with **health checks** and **service discovery** for distributed deployments.
100
+ - **Configurable authentication layer** that plugs into external auth/token providers.
101
+ - **Example agents** (`supervisor`, `weather`, `math`, cross-swarm demos) showcasing MAIL usage patterns.
102
+
103
+ ### Architecture Highlights
104
+ - **[src/mail/core/runtime.py](/src/mail/core/runtime.py)**: Mailbox scheduling, task orchestration, priority queues, and tool execution.
105
+ - **[src/mail/server.py](/src/mail/server.py)**: FastAPI application with REST + SSE endpoints and interswarm routing.
106
+ - **[src/mail/net/router.py](/src/mail/net/router.py)**: HTTP federation between swarms, including metadata rewriting.
107
+ - **[src/mail/net/registry.py](/src/mail/net/registry.py)**: Service registry and liveness monitoring for remote swarms.
108
+ - **[src/mail/factories/](/src/mail/factories/__init__.py)**: Agent functions that instantiate agents with their LLM/tool configuration.
109
+ - **[src/mail/examples/](/src/mail/examples/__init__.py)**: Example agents and prompts.
110
+
111
+ The runtime processes MAIL messages **asynchronously**, tracks per-task state, and produces `broadcast_complete` events to signal overall task completion.
112
+
113
+ ## 3. Getting Started
114
+
115
+ ### Prerequisites
116
+ - **Python 3.12+**
117
+ - [`uv`](https://github.com/astral-sh/uv) package manager (recommended) or `pip`
118
+ - **[LiteLLM](https://github.com/BerriAI/litellm) proxy endpoint** for LLM calls
119
+ - **Authentication service** providing `/auth/login` and `/auth/check` (see below)
120
+
121
+ ### Installation
122
+ ```bash
123
+ # Clone and enter the repository
124
+ git clone https://github.com/charonlabs/mail --branch v1.3.1
125
+ cd mail
126
+
127
+ # Install dependencies (preferred)
128
+ uv sync
129
+
130
+ # or, using pip
131
+ pip install -e .
132
+ ```
133
+
134
+ ### Configuration
135
+ Set the following **environment variables** before starting the server:
136
+
137
+ ```bash
138
+ # Authentication endpoints
139
+ export AUTH_ENDPOINT=http://your-auth-server/auth/login
140
+ export TOKEN_INFO_ENDPOINT=http://your-auth-server/auth/check
141
+
142
+ # LLM proxy (required only if your swarm uses use_proxy=true)
143
+ export LITELLM_PROXY_API_BASE=http://your-litellm-proxy
144
+
145
+ # Optional provider keys (required for direct provider calls)
146
+ export OPENAI_API_KEY=sk-your-openai-api-key
147
+ export ANTHROPIC_API_KEY=sk-your-anthropic-key
148
+
149
+ # Optional persistence (set to "none" to disable)
150
+ export DATABASE_URL=postgresql://...
151
+ ```
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.
154
+
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
+
157
+ **Swarm definitions** live in [swarms.json](/swarms.json). Each entry declares the agents, entrypoint, tools, and default models for a swarm.
158
+
159
+ ### Run a Local Swarm
160
+ ```bash
161
+ # Start the FastAPI server (includes SSE + registry)
162
+ uv run mail server
163
+ # or explicitly
164
+ uv run -m mail.server
165
+ ```
166
+
167
+ ### Federate Two Swarms (Example)
168
+ ```bash
169
+ # Terminal 1
170
+ uv run mail server --port 8000 --swarm-name swarm-alpha --swarm-registry registries/swarm-alpha.json
171
+
172
+ # Terminal 2
173
+ uv run mail server --port 8001 --swarm-name swarm-beta --swarm-registry registries/swarm-beta.json
174
+
175
+ # Register each swarm with the other (requires admin bearer token)
176
+ curl -X POST http://localhost:8000/swarms \
177
+ -H "Authorization: Bearer $ADMIN_TOKEN" \
178
+ -H "Content-Type: application/json" \
179
+ -d '{"name": "swarm-beta", "base_url": "http://localhost:8001"}'
180
+
181
+ curl -X POST http://localhost:8001/swarms \
182
+ -H "Authorization: Bearer $ADMIN_TOKEN" \
183
+ -H "Content-Type: application/json" \
184
+ -d '{"name": "swarm-alpha", "base_url": "http://localhost:8000"}'
185
+ ```
186
+ Agents can now address peers using `agent-name@swarm-name`, and responses will route back automatically.
187
+
188
+ ## 4. Repository Layout
189
+ ```
190
+ mail/
191
+ ├── spec/ # Protocol specification, schemas, validation utilities
192
+ ├── src/mail/ # Reference implementation (core runtime + FastAPI services)
193
+ ├── docs/ # Supplemental docs (registry, inter-swarm, auth, etc.)
194
+ ├── swarms.json # Default swarm configurations
195
+ ├── tests/ # Pytest suite covering protocol + runtime behaviors
196
+ ├── scripts/ # Operational helpers (deploy, smoke tests, tooling)
197
+ ├── registries/ # Swarm registry persistence (created as needed)
198
+ ├── assets/ # Diagrams and static assets (README image, etc.)
199
+ └── pyproject.toml # Project metadata and dependency definitions
200
+ ```
201
+
202
+ ## 5. Development Workflow
203
+ - **`uv run mail server`** – run the reference server locally.
204
+ - **`uv run pytest -q`** – execute the automated test suite.
205
+ - **`uv run ruff check --fix .`** – lint and auto-fix style issues.
206
+ - **`uv run spec/validate_samples.py`** – validate example MAIL payloads against the schemas.
207
+
208
+ ## 6. Documentation & Resources
209
+ - **Quickstart guide**: [docs/quickstart.md](/docs/quickstart.md)
210
+ - **Architecture deep-dive**: [docs/architecture.md](/docs/architecture.md)
211
+ - **Protocol message format reference**: [docs/message-format.md](/docs/message-format.md)
212
+ - **HTTP/API surface**: [docs/api.md](/docs/api.md)
213
+ - **Swarm configuration & registry operations**: [docs/configuration.md](/docs/configuration.md), [docs/registry.md](/docs/registry.md)
214
+ - **Database persistence**: [docs/database.md](/docs/database.md)
215
+ - **HTTP client usage**: [docs/client.md](/docs/client.md)
216
+ - **Security hardening checklist**: [docs/security.md](/docs/security.md)
217
+ - **Agents, tools, and examples**: [docs/agents-and-tools.md](/docs/agents-and-tools.md), [docs/examples.md](/docs/examples.md)
218
+ - **Testing and troubleshooting**: [docs/testing.md](/docs/testing.md), [docs/troubleshooting.md](/docs/troubleshooting.md)
219
+ - **Runtime source directories**: [src/mail/examples/](/src/mail/examples/__init__.py), [src/mail/factories/](/src/mail/factories/__init__.py)
220
+
221
+ ## 7. Contributing
222
+ - **Read [CONTRIBUTING.md](/CONTRIBUTING.md)** for branching, issue, and review guidelines.
223
+ - All commits require a **Developer Certificate of Origin sign-off** (`git commit -s`).
224
+ - Please open an issue to propose significant protocol changes before implementation.
225
+ - Core maintainers are listed in [MAINTAINERS.md](/MAINTAINERS.md).
226
+
227
+ ## 8. Licensing & Trademarks
228
+ - Reference implementation code: **Apache License 2.0** ([LICENSE](/LICENSE)).
229
+ - Specification text: **Creative Commons Attribution 4.0** ([SPEC-LICENSE](/SPEC-LICENSE)).
230
+ - Essential patent claims: **Open Web Foundation Final Specification Agreement 1.0** ([SPEC-PATENT-LICENSE](/SPEC-PATENT-LICENSE)).
231
+ - Trademarks and descriptive use policy: [TRADEMARKS.md](/TRADEMARKS.md).
232
+
233
+ Using the spec or code implies acceptance of their respective terms.
234
+
235
+ ---
236
+
237
+ For questions, bug reports, or feature requests, open an issue or start a discussion in this repository.
@@ -0,0 +1,137 @@
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
4
+ mail/client.py,sha256=igbcjGlz2Z-9LvGHf_qyACfVdeMVLnFuMXaMn740daY,56909
5
+ mail/server.py,sha256=NFANKkk0L19BKrxk1UkXaaWs7XQjOQWiN5F9cg9Ezh0,55966
6
+ mail/summarizer.py,sha256=clG4d1mcSHmGagvKva_P3trw46sd2XJPJ7lJ_o-e0qM,7468
7
+ mail/url_scheme.py,sha256=RRqXuIzmQAq_depvn1-bht9yEnTgxPy8R2s_8FbDF9M,1229
8
+ mail/config/__init__.py,sha256=bP2yX8fTyRm5Iv362uiQBf18rsh9H7coNoPtbpZJAeU,153
9
+ mail/config/client.py,sha256=aFuCqqvGnZQsDDqAi6aaWIjU8o3OPc41PkDAqYtnPZs,2581
10
+ mail/config/server.py,sha256=u1bJzu1IBA9kpuztY1oWObpUxPrVXh8e9NmogWubhok,5829
11
+ mail/core/__init__.py,sha256=v85xchqjsprvsOUUyf3lxdD0_89Il3TEQE2sMyJyk0I,1833
12
+ mail/core/actions.py,sha256=ZwXfceB-6aNrCEjcwOreUTxku2nTuh22_pemqY-cDWE,2249
13
+ mail/core/agents.py,sha256=hiCugGB8t3XicdiPmNWBd9Yfn1FqBJoAYNWao9Joy74,2084
14
+ mail/core/message.py,sha256=q70d0b5GB8YHMTCMrdvWhyTRDlazfydbc-5sktBqeUY,10812
15
+ mail/core/runtime.py,sha256=rCsU8SUZwMXZ9yOAlMkB8B0nm6ONd8sR740zerdjBGw,154773
16
+ mail/core/tasks.py,sha256=CUtc8SQIoAuvBhqSl6uPPCI-bVWbG538EOH6optDzyw,10048
17
+ mail/core/tools.py,sha256=DMrUme5gBgoMbR2Tv3aE_pTAumHNAKRTqW2ganPI1uc,42993
18
+ mail/db/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
19
+ mail/db/init.py,sha256=EZnV4qqbblhMRjv6nTZCiST0BLp4CUl9J87okJjB_tU,6812
20
+ mail/db/types.py,sha256=Ni6tym6FupiAgHcPQT-mATbf6R8ehUBg9wKMbHCBeP0,1387
21
+ mail/db/utils.py,sha256=-TaPxvhO5Fe8C5OEH6_RKfSTNTV5kZSpmP2hJHt_GWE,15312
22
+ mail/examples/__init__.py,sha256=Gu2iR2yTRweHz1CBP6RG7r2dDeHg8TEPZOIduCCdXcI,595
23
+ mail/examples/analyst_dummy/__init__.py,sha256=BgdDt_re2OO8io8PDCf5n96tN2grWnABvngITVgaioQ,292
24
+ mail/examples/analyst_dummy/agent.py,sha256=KqJxwmQBZZ9uFh3Ql8HPpcXZ2EV_9hXtwyMP8cwFN8M,4173
25
+ mail/examples/analyst_dummy/prompts.py,sha256=UfIB2MC4Gu9x36FYxwWwKqe2o6lrthyx1qT4EaL5uZU,1893
26
+ mail/examples/consultant_dummy/__init__.py,sha256=YKPpjCqFfT3fo5Ehp3D2O4lmLSFzMwRkuUIFxMXB9Rc,316
27
+ mail/examples/consultant_dummy/agent.py,sha256=Ru9MaBZbRN1nPqTC1O0BdbzdL6VtoYODv0l7c-Bdiow,4218
28
+ mail/examples/consultant_dummy/prompts.py,sha256=QXNZvdz55XakGUwKB99YvHUliJh4IujkYw6GuTok7SA,1809
29
+ mail/examples/data_analysis/__init__.py,sha256=XkXO7_4_IY3btIrnIbk_bRHJOXTvjxg84Qrs6sNiB7U,1408
30
+ mail/examples/data_analysis/analyst/__init__.py,sha256=1VSn1JU2vkK35YrgeWelrqLHWcgRNW_wceJ79lc9r10,316
31
+ mail/examples/data_analysis/analyst/agent.py,sha256=Qq0V4AxIxOEpdIB0LFH_TWuQnPECf2rjNgT47UYR1VQ,2227
32
+ mail/examples/data_analysis/analyst/prompts.py,sha256=UM1UqYhF4D5wdd3UJuyicW_l2uX8QMoLVW3hfkNLtFc,2337
33
+ mail/examples/data_analysis/processor/__init__.py,sha256=_V3So5jU7iY6506UG8qNscedEgsUhHO1EjqpGi41aI0,466
34
+ mail/examples/data_analysis/processor/actions.py,sha256=VH_SALwpJBObSuTCkvmdXdgIGHVLJcP2zP72BgEuaOo,8487
35
+ mail/examples/data_analysis/processor/agent.py,sha256=JeoWM9G1T87z9ZrxyK0TMhe4MsSBwqnjHt_EssXFpuQ,2211
36
+ mail/examples/data_analysis/processor/prompts.py,sha256=7jalEXKRI8XvTrZsLBXfYEAhKxRynzmybiDpxp2WnQs,2104
37
+ mail/examples/data_analysis/reporter/__init__.py,sha256=U6SB6CEvIKO7GqhgGnFngWNASvxO1UpiCDy3GSqLRvM,409
38
+ mail/examples/data_analysis/reporter/actions.py,sha256=bwQYxH0rhqwXk3e1TnXnemock_YyBjT9qw7tifKTclM,5690
39
+ mail/examples/data_analysis/reporter/agent.py,sha256=6tOWAw4qYpLE5mtXEg2xarYA5tlGUTFYx7nw8DGrfwU,2205
40
+ mail/examples/data_analysis/reporter/prompts.py,sha256=7j7Cz2ge1PyUUe1yZmQI2ZDMewdFSF6Liwhms0jknms,1945
41
+ mail/examples/data_analysis/statistics/__init__.py,sha256=uab_NHOEsXpJmlduIly-Sh9PRGz0c8I3h0n78Wr7Mnc,503
42
+ mail/examples/data_analysis/statistics/actions.py,sha256=Mniv6CNIhGcjoi6BjikDOwH8Tjq8wIkyTfKVnlPFmlw,11073
43
+ mail/examples/data_analysis/statistics/agent.py,sha256=lBWlkm9fy9WEOQopPmfQCaOjn_-mVHZpsWx4a0d69A8,2211
44
+ mail/examples/data_analysis/statistics/prompts.py,sha256=JWIYak7bsfqYi9BDf88Om61Dpd3ZtdQiVZZGjQGq32Q,2323
45
+ mail/examples/mafia/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
46
+ mail/examples/mafia/game.py,sha256=1QM3f3DXglJx2hkUHTRx0faJOKLNcS0XDXs4fBvbzJk,57383
47
+ mail/examples/mafia/narrator_tools.py,sha256=Kr3wJsm7Fb8vANjwx5SHCUHWqPb6drQ3MWI2BhkEvzM,13585
48
+ mail/examples/mafia/personas.py,sha256=I96R2rGsIDlKWPhtOPhOpni7qxtUkHEFzGbE-8MNSas,9856
49
+ mail/examples/mafia/prompts.py,sha256=qwTn9zJeqmzDo0lP8tMCHkgniR3u4IVOj-Pu0ucrdCw,19984
50
+ mail/examples/mafia/roles.py,sha256=8513m-QzP0KBBDVty23xAbDS6jJqf92opRq7n6g0yTk,4942
51
+ mail/examples/mafia/spec.md,sha256=-oBi5SkKHcwhvFXLde1nHf7Oh6wcrIWo6xAO1YjGKTk,12245
52
+ mail/examples/math_dummy/__init__.py,sha256=8KGsRPeUyXyH54e0SbpKUFsjsCkeUN9KVty1UYsmpYQ,438
53
+ mail/examples/math_dummy/actions.py,sha256=yZyIOe8vk4Zb8rkTh2sQI78nZLWTAmpsalxI6kiP5cM,8180
54
+ mail/examples/math_dummy/agent.py,sha256=mDM0PakGHzLBAs7utfT4rYNhoDAvJCCbPTP3B-mkTGU,4128
55
+ mail/examples/math_dummy/prompts.py,sha256=EKpo32QK32GvxsDLBf_dJahmzb4d5Z78sui4p6zdrcs,1882
56
+ mail/examples/math_dummy/types.py,sha256=7KGmI8A8lHKsaQykiZyF4CNZBUoaMTlSZi1BuzOrBxA,161
57
+ mail/examples/research/__init__.py,sha256=DgH2F-FoI7Td_AG0q1jtlExAu5gEkEW5zUPKQbqqieo,1371
58
+ mail/examples/research/researcher/__init__.py,sha256=4N5Or899iDSGyqErlSmK8JZLgx5sK4trYk13-lFlnnU,326
59
+ mail/examples/research/researcher/agent.py,sha256=0YCkYhMqNFfsQ8o8mhNAWtvYncFnfiRSeF57dYCvl2Q,2230
60
+ mail/examples/research/researcher/prompts.py,sha256=z5venCFODGSYtZLCnmrmQ5FahF7lva8hLJ5IkfLZHnM,2293
61
+ mail/examples/research/searcher/__init__.py,sha256=UBu2mwuD85lepeQrb3wNYuHXAQXTX3B2PMqwH4MBW3w,429
62
+ mail/examples/research/searcher/actions.py,sha256=oYWOPxklpRBcp2RvbAr7Yxmg8NSVQEjoQyvuOS6q19s,12489
63
+ mail/examples/research/searcher/agent.py,sha256=Vfs48tI-R2AiV3xTjLFBuUCMwnP9FLr29Ik_Nmz-agA,2206
64
+ mail/examples/research/searcher/prompts.py,sha256=29knJOyjIDtdo0RSZM2fhAeSK2oVaqwlkZq2tdp9-Aw,2066
65
+ mail/examples/research/summarizer/__init__.py,sha256=hmQMcpnKC5AOFlCO65tw3Apx-wkxlpxW6x-JNFrv1fI,489
66
+ mail/examples/research/summarizer/actions.py,sha256=xKJMBasIC8iqkJWuS_PqDwsLdCLweD7MOXCpa6gZlkY,7556
67
+ mail/examples/research/summarizer/agent.py,sha256=_GYYaHexI8NTdiKkD8oUZY163OpcFlEybIBxgLOYmcY,2207
68
+ mail/examples/research/summarizer/prompts.py,sha256=JySnxz1YjGcaciaDzsfJG5IyJ-3J4NOpRFTTQPxPTH8,2098
69
+ mail/examples/research/verifier/__init__.py,sha256=EOtRMdYTQdOrFFu8pKEfjbs-NUkThUkDAnJzgaDYzV0,433
70
+ mail/examples/research/verifier/actions.py,sha256=AOnYgJmYOxuKJ9A3ac9vfLDPb-sr1omIryrBKhfn_i4,9875
71
+ mail/examples/research/verifier/agent.py,sha256=8W85hNe7F7h8w7eAGzyjU-jFKh7n6F1qJFfY-iUjGz8,2208
72
+ mail/examples/research/verifier/prompts.py,sha256=stl3dNksEota7L4zYJFZf0kCgOZsB5G2GmENSsMcxhA,2262
73
+ mail/examples/supervisor/__init__.py,sha256=g9ult4K_iDshcmuFQ_2kMy7vnUlxw6pjeKdzx2QH7mc,190
74
+ mail/examples/supervisor/agent.py,sha256=ipJz1MfprICqzr3-hILQntz1Skq8mFx98xmiOVhnsMk,122
75
+ mail/examples/supervisor/prompts.py,sha256=q2jVcXJg1Lnp8X-CWWzeYSGf6ik4W_fq8lWuKpODJUA,3802
76
+ mail/examples/support/__init__.py,sha256=_Km4yG9mdV679uEIAb8xSE79FfXUkDRvkmyC2ZyZWL4,1276
77
+ mail/examples/support/classifier/__init__.py,sha256=I0xt9-lOcVz50DpB6kOj4HlA7G3CTNsjDvQEmxxElho,410
78
+ mail/examples/support/classifier/actions.py,sha256=EcBhjxR4BNuWNnlY1aesklMGhsuk0vUpgNRvJY7X3hY,7812
79
+ mail/examples/support/classifier/agent.py,sha256=LkYkJQWjiGvg4vJ1cMZmoUqf-7Qt4Vg0LN6mxBVQAd0,2307
80
+ mail/examples/support/classifier/prompts.py,sha256=15_S-14JZeutt6n3DpNMPUXpajDSMHt-eaP7MTDkl1o,2350
81
+ mail/examples/support/coordinator/__init__.py,sha256=fB6YMAgC669S7Sy-I1HuxXBf95H9fZLF1O2W0KNi_5s,327
82
+ mail/examples/support/coordinator/agent.py,sha256=-4BJckoa7kkIbCn6CeM446ifCdxh-9b8htzmoW7IKG0,2255
83
+ mail/examples/support/coordinator/prompts.py,sha256=VYS11iSq-Du0DlBSbrZlQtS-HS6sLG1FSAa4LNJwwhg,2109
84
+ mail/examples/support/faq/__init__.py,sha256=PmG5et3rhcMElLv5xjfDmsTHvbcWROxGYHlbkqa20G0,358
85
+ mail/examples/support/faq/actions.py,sha256=BVHALd0DgJDh9C9wMBIoLsR-BJJG-0_rzJpXxmPeCp0,7970
86
+ mail/examples/support/faq/agent.py,sha256=BIEjMLgwtpA3egJ0BdVPwjsfT0pBwGcuQ_lRLp3tQ5Y,2194
87
+ mail/examples/support/faq/prompts.py,sha256=XxMLCkbUQXpDmBiQUAoixQHlQitQaFfvtNDc2Loypks,1866
88
+ mail/examples/support/sentiment/__init__.py,sha256=LlBZF6UEP0jzwDYtaS3hEBF3inRXHCk7YT7Y_bZTWEA,467
89
+ mail/examples/support/sentiment/actions.py,sha256=u84lWtpCN_TF_MOfby9XJlaR5Id6zcC5XpHrJuA3K2Y,9823
90
+ mail/examples/support/sentiment/agent.py,sha256=mj3mu8pdrJT2WCIgU9KWk3QyaG3GSrF3BX1IC3d5CQY,2246
91
+ mail/examples/support/sentiment/prompts.py,sha256=ANs-vLRjk4egZPJfXxQyWzSJCUIk-z7uMlWdsXccKN0,2169
92
+ mail/examples/weather_dummy/__init__.py,sha256=uiOuZ_s6eGqXRkNVrJPGU1BJqgm1Kzv3wUGlQE_8dfc,462
93
+ mail/examples/weather_dummy/actions.py,sha256=dDMERJ8kL2muzHAZeSefqYYsIU8fsdNGN_Gk8Lab-Zk,2187
94
+ mail/examples/weather_dummy/agent.py,sha256=ehoMg_0fXZcRYJ9VfsSwpKwxyG4mSvjBlyHUw0KNZKU,4187
95
+ mail/examples/weather_dummy/prompts.py,sha256=sCAeGktBbSf_RGWkC1CKHLlLidura86hyOE7tF5UPRY,1586
96
+ mail/examples/weather_dummy/types.py,sha256=rWNU2Fz_1LJdm54iyzBgy3H_Mx6IzIsdpA_ofTO56OM,164
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
101
+ mail/net/__init__.py,sha256=s6obszeuL0nMHsfR9zROMKi1aRDAwtf1XXB5z6jqtJE,133
102
+ mail/net/registry.py,sha256=rP-_E53JC9iyt83SzDKlRHHR6pSmBm38sjx9XiCxnwQ,27894
103
+ mail/net/router.py,sha256=gc2wB_hgWL8WJmZryZQPT0tslbO9Dtct7IpFCa2RKGE,28729
104
+ mail/net/server_utils.py,sha256=JpXW91_pT8XLr7SBfGmFe-8PIAcvIvQGqSbckxo76EM,2737
105
+ mail/net/types.py,sha256=2jp243e3eW7oT-gbQcELSocnY3GBTaJsqyUUjrF7ipU,6313
106
+ mail/stdlib/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
107
+ mail/stdlib/anthropic/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
108
+ mail/stdlib/fs/__init__.py,sha256=_5d5sT7R4_hMb2raLV7WKyDjoEZUrjUsZES1WWY4nKY,230
109
+ mail/stdlib/fs/actions.py,sha256=_K31oJokid2Ne5lUZ-JRF2HTmLjpD-6KsXtSzM40-rs,5119
110
+ mail/stdlib/http/__init__.py,sha256=oucV0pITPwap_TKstKHiatxtT8lQGZjC6shPAX2oVA4,272
111
+ mail/stdlib/http/actions.py,sha256=7av58CSlzeC-JenvYeDrNRmLLCfe90R72l-SemqXObg,8417
112
+ mail/stdlib/interswarm/__init__.py,sha256=RjxIdf3G3n6M4YggaqbgUUIEV91fPpgvKPOVWgqV7oQ,170
113
+ mail/stdlib/interswarm/actions.py,sha256=BHuth6CyXoMxUqbW4M8b1bsp_zh6Nnj9RSB94Ag0uOU,6319
114
+ mail/stdlib/mcp/__init__.py,sha256=DsuojnjpFCtXxOl2AbQOdrnrWUv69uSDhSFUeKoWFyg,338
115
+ mail/stdlib/mcp/actions.py,sha256=u9Mq2JJd12Y1bb9r8OxFIDVQVfcXHaaP15xGhDWZUcM,7765
116
+ mail/stdlib/openai/__init__.py,sha256=73eGUIbeKNns_jq9Jd6OCWa4BtIfZL8evaXtt3MYveA,363
117
+ mail/stdlib/openai/agents.py,sha256=QRsJgtlB_xgecVvp8Pp1Jh4hCfLIm45jFssTV2oVvSM,15511
118
+ mail/swarms_json/__init__.py,sha256=Qfp9yATeshxYJwENfs-4gsldMt0b7nKMvEDtgqvl1t0,657
119
+ mail/swarms_json/types.py,sha256=YFonlB3fvcEjZrNZ_Pba7RDgh9lYAZOXLQRjfBSDGkY,3047
120
+ mail/swarms_json/utils.py,sha256=ZoIfJvVLUFEgvQJBdNBTeIkEWt8oST_mPtEDLeC87PQ,8892
121
+ mail/utils/__init__.py,sha256=bFLtt96grHA3xCF1cIYzu7qnsYSk5OikQT8EOg1xHjA,1039
122
+ mail/utils/auth.py,sha256=6mFifvk3LHMAFgKxJjp6RCPd3Iqro8mScTYO08cRgZQ,6183
123
+ mail/utils/context.py,sha256=BJSqndPOBhKh3q57OGGpIRXTW7S0Zw4aw0GPgs3Es6Y,420
124
+ mail/utils/logger.py,sha256=YfE-f2weOpndNSb84Owtu5WBLcmjXcz5FdBVL2lPp0c,2206
125
+ mail/utils/openai.py,sha256=Brjst_Q6VcSHK03cta3xtAeiVBTRY4PU_BO9NSKs4II,8684
126
+ mail/utils/parsing.py,sha256=pWIp3IeN_sg7ifRYDmhwfzkXb6qhuvbT5zx5xb299yk,2540
127
+ mail/utils/serialize.py,sha256=S-nqIwodDXZrsgHDrBg2ndur4fMnmFXKRf8kKl_Z0yc,9753
128
+ mail/utils/store.py,sha256=VJ9GoHjFWcWeDWoOwS7Ujh-8rHqxvMQtGJDg2XA1ekI,1495
129
+ mail/utils/string_builder.py,sha256=eAlGUzfKqxgfsAIJfpSoFlZ2hqP2PvSVnNE5FxjprII,4516
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,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.28.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ mail = mail.cli:main