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.
- mail/__init__.py +35 -0
- mail/api.py +1964 -0
- mail/cli.py +432 -0
- mail/client.py +1657 -0
- mail/config/__init__.py +8 -0
- mail/config/client.py +87 -0
- mail/config/server.py +165 -0
- mail/core/__init__.py +72 -0
- mail/core/actions.py +69 -0
- mail/core/agents.py +73 -0
- mail/core/message.py +366 -0
- mail/core/runtime.py +3537 -0
- mail/core/tasks.py +311 -0
- mail/core/tools.py +1206 -0
- mail/db/__init__.py +0 -0
- mail/db/init.py +182 -0
- mail/db/types.py +65 -0
- mail/db/utils.py +523 -0
- mail/examples/__init__.py +27 -0
- mail/examples/analyst_dummy/__init__.py +15 -0
- mail/examples/analyst_dummy/agent.py +136 -0
- mail/examples/analyst_dummy/prompts.py +44 -0
- mail/examples/consultant_dummy/__init__.py +15 -0
- mail/examples/consultant_dummy/agent.py +136 -0
- mail/examples/consultant_dummy/prompts.py +42 -0
- mail/examples/data_analysis/__init__.py +40 -0
- mail/examples/data_analysis/analyst/__init__.py +9 -0
- mail/examples/data_analysis/analyst/agent.py +67 -0
- mail/examples/data_analysis/analyst/prompts.py +53 -0
- mail/examples/data_analysis/processor/__init__.py +13 -0
- mail/examples/data_analysis/processor/actions.py +293 -0
- mail/examples/data_analysis/processor/agent.py +67 -0
- mail/examples/data_analysis/processor/prompts.py +48 -0
- mail/examples/data_analysis/reporter/__init__.py +10 -0
- mail/examples/data_analysis/reporter/actions.py +187 -0
- mail/examples/data_analysis/reporter/agent.py +67 -0
- mail/examples/data_analysis/reporter/prompts.py +49 -0
- mail/examples/data_analysis/statistics/__init__.py +18 -0
- mail/examples/data_analysis/statistics/actions.py +343 -0
- mail/examples/data_analysis/statistics/agent.py +67 -0
- mail/examples/data_analysis/statistics/prompts.py +60 -0
- mail/examples/mafia/__init__.py +0 -0
- mail/examples/mafia/game.py +1537 -0
- mail/examples/mafia/narrator_tools.py +396 -0
- mail/examples/mafia/personas.py +240 -0
- mail/examples/mafia/prompts.py +489 -0
- mail/examples/mafia/roles.py +147 -0
- mail/examples/mafia/spec.md +350 -0
- mail/examples/math_dummy/__init__.py +23 -0
- mail/examples/math_dummy/actions.py +252 -0
- mail/examples/math_dummy/agent.py +136 -0
- mail/examples/math_dummy/prompts.py +46 -0
- mail/examples/math_dummy/types.py +5 -0
- mail/examples/research/__init__.py +39 -0
- mail/examples/research/researcher/__init__.py +9 -0
- mail/examples/research/researcher/agent.py +67 -0
- mail/examples/research/researcher/prompts.py +54 -0
- mail/examples/research/searcher/__init__.py +10 -0
- mail/examples/research/searcher/actions.py +324 -0
- mail/examples/research/searcher/agent.py +67 -0
- mail/examples/research/searcher/prompts.py +53 -0
- mail/examples/research/summarizer/__init__.py +18 -0
- mail/examples/research/summarizer/actions.py +255 -0
- mail/examples/research/summarizer/agent.py +67 -0
- mail/examples/research/summarizer/prompts.py +55 -0
- mail/examples/research/verifier/__init__.py +10 -0
- mail/examples/research/verifier/actions.py +337 -0
- mail/examples/research/verifier/agent.py +67 -0
- mail/examples/research/verifier/prompts.py +52 -0
- mail/examples/supervisor/__init__.py +11 -0
- mail/examples/supervisor/agent.py +4 -0
- mail/examples/supervisor/prompts.py +93 -0
- mail/examples/support/__init__.py +33 -0
- mail/examples/support/classifier/__init__.py +10 -0
- mail/examples/support/classifier/actions.py +307 -0
- mail/examples/support/classifier/agent.py +68 -0
- mail/examples/support/classifier/prompts.py +56 -0
- mail/examples/support/coordinator/__init__.py +9 -0
- mail/examples/support/coordinator/agent.py +67 -0
- mail/examples/support/coordinator/prompts.py +48 -0
- mail/examples/support/faq/__init__.py +10 -0
- mail/examples/support/faq/actions.py +182 -0
- mail/examples/support/faq/agent.py +67 -0
- mail/examples/support/faq/prompts.py +42 -0
- mail/examples/support/sentiment/__init__.py +15 -0
- mail/examples/support/sentiment/actions.py +341 -0
- mail/examples/support/sentiment/agent.py +67 -0
- mail/examples/support/sentiment/prompts.py +54 -0
- mail/examples/weather_dummy/__init__.py +23 -0
- mail/examples/weather_dummy/actions.py +75 -0
- mail/examples/weather_dummy/agent.py +136 -0
- mail/examples/weather_dummy/prompts.py +35 -0
- mail/examples/weather_dummy/types.py +5 -0
- mail/factories/__init__.py +27 -0
- mail/factories/action.py +223 -0
- mail/factories/base.py +1531 -0
- mail/factories/supervisor.py +241 -0
- mail/net/__init__.py +7 -0
- mail/net/registry.py +712 -0
- mail/net/router.py +728 -0
- mail/net/server_utils.py +114 -0
- mail/net/types.py +247 -0
- mail/server.py +1605 -0
- mail/stdlib/__init__.py +0 -0
- mail/stdlib/anthropic/__init__.py +0 -0
- mail/stdlib/fs/__init__.py +15 -0
- mail/stdlib/fs/actions.py +209 -0
- mail/stdlib/http/__init__.py +19 -0
- mail/stdlib/http/actions.py +333 -0
- mail/stdlib/interswarm/__init__.py +11 -0
- mail/stdlib/interswarm/actions.py +208 -0
- mail/stdlib/mcp/__init__.py +19 -0
- mail/stdlib/mcp/actions.py +294 -0
- mail/stdlib/openai/__init__.py +13 -0
- mail/stdlib/openai/agents.py +451 -0
- mail/summarizer.py +234 -0
- mail/swarms_json/__init__.py +27 -0
- mail/swarms_json/types.py +87 -0
- mail/swarms_json/utils.py +255 -0
- mail/url_scheme.py +51 -0
- mail/utils/__init__.py +53 -0
- mail/utils/auth.py +194 -0
- mail/utils/context.py +17 -0
- mail/utils/logger.py +73 -0
- mail/utils/openai.py +212 -0
- mail/utils/parsing.py +89 -0
- mail/utils/serialize.py +292 -0
- mail/utils/store.py +49 -0
- mail/utils/string_builder.py +119 -0
- mail/utils/version.py +20 -0
- mail_swarms-1.3.2.dist-info/METADATA +237 -0
- mail_swarms-1.3.2.dist-info/RECORD +137 -0
- mail_swarms-1.3.2.dist-info/WHEEL +4 -0
- mail_swarms-1.3.2.dist-info/entry_points.txt +2 -0
- mail_swarms-1.3.2.dist-info/licenses/LICENSE +202 -0
- mail_swarms-1.3.2.dist-info/licenses/NOTICE +10 -0
- mail_swarms-1.3.2.dist-info/licenses/THIRD_PARTY_NOTICES.md +12334 -0
mail/db/__init__.py
ADDED
|
File without changes
|
mail/db/init.py
ADDED
|
@@ -0,0 +1,182 @@
|
|
|
1
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
# Copyright (c) 2025 Addison Kline
|
|
3
|
+
|
|
4
|
+
"""
|
|
5
|
+
Database initialization for MAIL persistence (agent histories, tasks, events, responses).
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
import os
|
|
9
|
+
import sys
|
|
10
|
+
|
|
11
|
+
import asyncpg
|
|
12
|
+
import dotenv
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
async def create_tables() -> None:
|
|
16
|
+
"""
|
|
17
|
+
Create all MAIL persistence tables and indexes in the database.
|
|
18
|
+
"""
|
|
19
|
+
dotenv.load_dotenv()
|
|
20
|
+
database_url = os.getenv("DATABASE_URL")
|
|
21
|
+
|
|
22
|
+
if not database_url:
|
|
23
|
+
print("ERROR: DATABASE_URL environment variable is not set")
|
|
24
|
+
print("Please set DATABASE_URL in your .env file or environment")
|
|
25
|
+
print("Example: DATABASE_URL=postgresql://user:password@localhost:5432/mail")
|
|
26
|
+
sys.exit(1)
|
|
27
|
+
|
|
28
|
+
print("Connecting to database...")
|
|
29
|
+
|
|
30
|
+
try:
|
|
31
|
+
conn = await asyncpg.connect(database_url)
|
|
32
|
+
except Exception as e:
|
|
33
|
+
print(f"ERROR: Failed to connect to database: {e}")
|
|
34
|
+
sys.exit(1)
|
|
35
|
+
|
|
36
|
+
print("Connected successfully")
|
|
37
|
+
|
|
38
|
+
# ==========================================================================
|
|
39
|
+
# Table: agent_histories
|
|
40
|
+
# ==========================================================================
|
|
41
|
+
create_agent_histories_sql = """
|
|
42
|
+
CREATE TABLE IF NOT EXISTS agent_histories (
|
|
43
|
+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
44
|
+
swarm_name TEXT NOT NULL,
|
|
45
|
+
caller_role TEXT NOT NULL,
|
|
46
|
+
caller_id TEXT NOT NULL,
|
|
47
|
+
tool_format TEXT NOT NULL,
|
|
48
|
+
task_id TEXT NOT NULL,
|
|
49
|
+
agent_name TEXT NOT NULL,
|
|
50
|
+
history JSONB NOT NULL,
|
|
51
|
+
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
|
|
52
|
+
updated_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW()
|
|
53
|
+
);
|
|
54
|
+
"""
|
|
55
|
+
|
|
56
|
+
agent_histories_indexes = [
|
|
57
|
+
"CREATE INDEX IF NOT EXISTS idx_agent_histories_swarm_name ON agent_histories (swarm_name);",
|
|
58
|
+
"CREATE INDEX IF NOT EXISTS idx_agent_histories_task_id ON agent_histories (task_id);",
|
|
59
|
+
"CREATE INDEX IF NOT EXISTS idx_agent_histories_caller ON agent_histories (caller_role, caller_id);",
|
|
60
|
+
"CREATE INDEX IF NOT EXISTS idx_agent_histories_agent_name ON agent_histories (agent_name);",
|
|
61
|
+
"CREATE INDEX IF NOT EXISTS idx_agent_histories_created_at ON agent_histories (created_at DESC);",
|
|
62
|
+
]
|
|
63
|
+
|
|
64
|
+
# ==========================================================================
|
|
65
|
+
# Table: tasks
|
|
66
|
+
# ==========================================================================
|
|
67
|
+
create_tasks_sql = """
|
|
68
|
+
CREATE TABLE IF NOT EXISTS tasks (
|
|
69
|
+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
70
|
+
task_id TEXT NOT NULL,
|
|
71
|
+
swarm_name TEXT NOT NULL,
|
|
72
|
+
caller_role TEXT NOT NULL,
|
|
73
|
+
caller_id TEXT NOT NULL,
|
|
74
|
+
task_owner TEXT NOT NULL,
|
|
75
|
+
task_contributors JSONB NOT NULL DEFAULT '[]',
|
|
76
|
+
remote_swarms JSONB NOT NULL DEFAULT '[]',
|
|
77
|
+
is_running BOOLEAN NOT NULL DEFAULT FALSE,
|
|
78
|
+
completed BOOLEAN NOT NULL DEFAULT FALSE,
|
|
79
|
+
title TEXT,
|
|
80
|
+
start_time TIMESTAMP WITH TIME ZONE NOT NULL,
|
|
81
|
+
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
|
|
82
|
+
updated_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
|
|
83
|
+
UNIQUE(task_id, swarm_name, caller_role, caller_id)
|
|
84
|
+
);
|
|
85
|
+
"""
|
|
86
|
+
|
|
87
|
+
tasks_indexes = [
|
|
88
|
+
"CREATE INDEX IF NOT EXISTS idx_tasks_lookup ON tasks (swarm_name, caller_role, caller_id);",
|
|
89
|
+
"CREATE INDEX IF NOT EXISTS idx_tasks_task_id ON tasks (task_id);",
|
|
90
|
+
]
|
|
91
|
+
|
|
92
|
+
# ==========================================================================
|
|
93
|
+
# Table: task_events
|
|
94
|
+
# ==========================================================================
|
|
95
|
+
create_task_events_sql = """
|
|
96
|
+
CREATE TABLE IF NOT EXISTS task_events (
|
|
97
|
+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
98
|
+
task_id TEXT NOT NULL,
|
|
99
|
+
swarm_name TEXT NOT NULL,
|
|
100
|
+
caller_role TEXT NOT NULL,
|
|
101
|
+
caller_id TEXT NOT NULL,
|
|
102
|
+
event_type TEXT,
|
|
103
|
+
event_data TEXT,
|
|
104
|
+
event_id TEXT,
|
|
105
|
+
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW()
|
|
106
|
+
);
|
|
107
|
+
"""
|
|
108
|
+
|
|
109
|
+
task_events_indexes = [
|
|
110
|
+
"CREATE INDEX IF NOT EXISTS idx_task_events_lookup ON task_events (task_id, swarm_name, caller_role, caller_id);",
|
|
111
|
+
"CREATE INDEX IF NOT EXISTS idx_task_events_created ON task_events (created_at);",
|
|
112
|
+
]
|
|
113
|
+
|
|
114
|
+
# ==========================================================================
|
|
115
|
+
# Table: task_responses
|
|
116
|
+
# ==========================================================================
|
|
117
|
+
create_task_responses_sql = """
|
|
118
|
+
CREATE TABLE IF NOT EXISTS task_responses (
|
|
119
|
+
id UUID PRIMARY KEY DEFAULT gen_random_uuid(),
|
|
120
|
+
task_id TEXT NOT NULL,
|
|
121
|
+
swarm_name TEXT NOT NULL,
|
|
122
|
+
caller_role TEXT NOT NULL,
|
|
123
|
+
caller_id TEXT NOT NULL,
|
|
124
|
+
response JSONB NOT NULL,
|
|
125
|
+
created_at TIMESTAMP WITH TIME ZONE NOT NULL DEFAULT NOW(),
|
|
126
|
+
UNIQUE(task_id, swarm_name, caller_role, caller_id)
|
|
127
|
+
);
|
|
128
|
+
"""
|
|
129
|
+
|
|
130
|
+
task_responses_indexes = [
|
|
131
|
+
"CREATE INDEX IF NOT EXISTS idx_task_responses_lookup ON task_responses (task_id, swarm_name, caller_role, caller_id);",
|
|
132
|
+
]
|
|
133
|
+
|
|
134
|
+
try:
|
|
135
|
+
# Create agent_histories table
|
|
136
|
+
print("Creating agent_histories table...")
|
|
137
|
+
await conn.execute(create_agent_histories_sql)
|
|
138
|
+
for idx_sql in agent_histories_indexes:
|
|
139
|
+
await conn.execute(idx_sql)
|
|
140
|
+
print(" agent_histories table created")
|
|
141
|
+
|
|
142
|
+
# Create tasks table
|
|
143
|
+
print("Creating tasks table...")
|
|
144
|
+
await conn.execute(create_tasks_sql)
|
|
145
|
+
for idx_sql in tasks_indexes:
|
|
146
|
+
await conn.execute(idx_sql)
|
|
147
|
+
print(" tasks table created")
|
|
148
|
+
|
|
149
|
+
# Create task_events table
|
|
150
|
+
print("Creating task_events table...")
|
|
151
|
+
await conn.execute(create_task_events_sql)
|
|
152
|
+
for idx_sql in task_events_indexes:
|
|
153
|
+
await conn.execute(idx_sql)
|
|
154
|
+
print(" task_events table created")
|
|
155
|
+
|
|
156
|
+
# Create task_responses table
|
|
157
|
+
print("Creating task_responses table...")
|
|
158
|
+
await conn.execute(create_task_responses_sql)
|
|
159
|
+
for idx_sql in task_responses_indexes:
|
|
160
|
+
await conn.execute(idx_sql)
|
|
161
|
+
print(" task_responses table created")
|
|
162
|
+
|
|
163
|
+
# Verify tables exist
|
|
164
|
+
print("\nVerifying tables...")
|
|
165
|
+
tables = ["agent_histories", "tasks", "task_events", "task_responses"]
|
|
166
|
+
for table_name in tables:
|
|
167
|
+
result = await conn.fetchrow(
|
|
168
|
+
"SELECT EXISTS (SELECT FROM information_schema.tables WHERE table_name = $1);",
|
|
169
|
+
table_name,
|
|
170
|
+
)
|
|
171
|
+
if result and result[0]:
|
|
172
|
+
print(f" {table_name}: OK")
|
|
173
|
+
else:
|
|
174
|
+
print(f" {table_name}: MISSING")
|
|
175
|
+
|
|
176
|
+
except Exception as e:
|
|
177
|
+
print(f"ERROR: Failed to create tables: {e}")
|
|
178
|
+
sys.exit(1)
|
|
179
|
+
finally:
|
|
180
|
+
await conn.close()
|
|
181
|
+
|
|
182
|
+
print("\nDatabase initialization complete!")
|
mail/db/types.py
ADDED
|
@@ -0,0 +1,65 @@
|
|
|
1
|
+
# SPDX-License-Identifier: Apache-2.0
|
|
2
|
+
# Copyright (c) 2025 Addison Kline
|
|
3
|
+
|
|
4
|
+
from typing import Any, Literal, TypedDict
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class AgentHistoriesDB(TypedDict):
|
|
8
|
+
"""
|
|
9
|
+
A database record for storing agent histories.
|
|
10
|
+
"""
|
|
11
|
+
|
|
12
|
+
id: str
|
|
13
|
+
swarm_name: str
|
|
14
|
+
caller_role: Literal["admin", "agent", "user"]
|
|
15
|
+
caller_id: str
|
|
16
|
+
tool_format: Literal["completions", "responses"]
|
|
17
|
+
task_id: str
|
|
18
|
+
agent_name: str
|
|
19
|
+
history: list[dict[str, Any]]
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class TaskDB(TypedDict):
|
|
23
|
+
"""
|
|
24
|
+
A database record for storing MAILTask metadata.
|
|
25
|
+
"""
|
|
26
|
+
|
|
27
|
+
id: str
|
|
28
|
+
task_id: str
|
|
29
|
+
swarm_name: str
|
|
30
|
+
caller_role: Literal["admin", "agent", "user"]
|
|
31
|
+
caller_id: str
|
|
32
|
+
task_owner: str
|
|
33
|
+
task_contributors: list[str]
|
|
34
|
+
remote_swarms: list[str]
|
|
35
|
+
is_running: bool
|
|
36
|
+
completed: bool
|
|
37
|
+
start_time: str # ISO format timestamp
|
|
38
|
+
|
|
39
|
+
|
|
40
|
+
class TaskEventDB(TypedDict):
|
|
41
|
+
"""
|
|
42
|
+
A database record for storing task SSE events.
|
|
43
|
+
"""
|
|
44
|
+
|
|
45
|
+
id: str
|
|
46
|
+
task_id: str
|
|
47
|
+
swarm_name: str
|
|
48
|
+
caller_role: Literal["admin", "agent", "user"]
|
|
49
|
+
caller_id: str
|
|
50
|
+
event_type: str | None
|
|
51
|
+
event_data: str | None
|
|
52
|
+
event_id: str | None
|
|
53
|
+
|
|
54
|
+
|
|
55
|
+
class TaskResponseDB(TypedDict):
|
|
56
|
+
"""
|
|
57
|
+
A database record for storing task response messages.
|
|
58
|
+
"""
|
|
59
|
+
|
|
60
|
+
id: str
|
|
61
|
+
task_id: str
|
|
62
|
+
swarm_name: str
|
|
63
|
+
caller_role: Literal["admin", "agent", "user"]
|
|
64
|
+
caller_id: str
|
|
65
|
+
response: dict[str, Any]
|