Skip to content

Commit b76cb0b

Browse files
committed
Merge master into fix/all-except-first-drops-an-agent
Resolved conversation.py:1364 in favour of _index_after_first_message(). master had reached [1:] on both methods (kyegomez#2079 for the dict variant, kyegomez#2133 for the string one), which is the opposite fixed guess to the [2:] this PR was opened against. Both are wrong for one of the two history shapes.
2 parents 730e3d7 + f57053c commit b76cb0b

50 files changed

Lines changed: 3034 additions & 2773 deletions

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

example.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
from dotenv import load_dotenv
22

3-
from swarms import Agent
3+
from swarms.structs.agent import Agent
44

55
load_dotenv()
66

@@ -25,7 +25,7 @@
2525
max_loops=1,
2626
top_p=None,
2727
temperature=None,
28-
reasoning_effort="medium",
28+
reasoning_effort=None,
2929
persistent_memory=False,
3030
)
3131

examples/multi_agent/concurrent_examples/concurrent_mix.py

Lines changed: 4 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -18,15 +18,12 @@
1818
corporate law and ensure that all hiring practices are in compliance with
1919
state and federal regulations.
2020
""",
21-
model_name="claude-sonnet-4-20250514",
21+
model_name="claude-sonnet-5",
2222
max_loops=1,
2323
autosave=False,
2424
dashboard=False,
2525
verbose=True,
26-
output_type="str",
27-
artifacts_on=True,
28-
artifacts_output_path="delaware_ccorp_hiring_description.md",
29-
artifacts_file_extension=".md",
26+
temperature=None,
3027
)
3128

3229
indian_foreign_agent = Agent(
@@ -45,15 +42,12 @@
4542
implications of hiring foreign nationals and the requirements for obtaining
4643
necessary visas and work permits.
4744
""",
48-
model_name="claude-sonnet-4-20250514",
45+
model_name="claude-sonnet-5",
4946
max_loops=1,
5047
autosave=False,
5148
dashboard=False,
5249
verbose=True,
53-
output_type="str",
54-
artifacts_on=True,
55-
artifacts_output_path="indian_foreign_hiring_description.md",
56-
artifacts_file_extension=".md",
50+
temperature=None,
5751
)
5852

5953
# List of agents and corresponding tasks
Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,39 @@
1+
from swarms import Agent, HierarchicalSwarm
2+
3+
4+
def main() -> None:
5+
"""Run a director with two specialized workers.
6+
7+
Returns:
8+
None.
9+
"""
10+
researcher = Agent(
11+
agent_name="Researcher",
12+
agent_description="Finds relevant facts and key considerations.",
13+
system_prompt="Research the assigned topic and return concise facts.",
14+
model_name="gpt-5.4",
15+
max_loops=1,
16+
)
17+
writer = Agent(
18+
agent_name="Writer",
19+
agent_description="Turns research into a clear final explanation.",
20+
system_prompt="Write a concise explanation for a general audience.",
21+
model_name="gpt-5.4",
22+
max_loops=1,
23+
)
24+
25+
swarm = HierarchicalSwarm(
26+
name="ResearchWritingSwarm",
27+
description="Researches a topic and explains the findings.",
28+
agents=[researcher, writer],
29+
max_loops=1,
30+
)
31+
32+
result = swarm.run(
33+
"Explain three practical benefits of multi-agent systems."
34+
)
35+
print(result)
36+
37+
38+
if __name__ == "__main__":
39+
main()

pyproject.toml

Lines changed: 1 addition & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@ build-backend = "poetry.core.masonry.api"
55

66
[tool.poetry]
77
name = "swarms"
8-
version = "14.0.2"
8+
version = "15.0.0"
99
description = "Swarms - TGSC"
1010
license = "Apache-2.0"
1111
authors = ["Kye Gomez <kye@swarms.world>"]
@@ -99,8 +99,6 @@ pytest = "*"
9999

100100
[tool.pytest.ini_options]
101101
testpaths = ["tests"]
102-
# Without this, pytest-asyncio's strict default silently skips every bare
103-
# `async def test_`, reporting it as a failure that never ran.
104102
asyncio_mode = "auto"
105103
markers = [
106104
"remote: tests that hit a real remote MCP server over the network",
@@ -109,12 +107,6 @@ markers = [
109107
[tool.ruff]
110108
line-length = 70
111109

112-
# Library code under swarms/ is held to the full rule set. Example scripts,
113-
# test helpers and one-off scripts are not: an availability probe imports a
114-
# package to see whether it is installed (F401), a demo loads dotenv before
115-
# importing (E402), and a teaching example catches everything so it can print
116-
# a friendly message (E722). Enforcing those there produces churn without
117-
# making the library safer.
118110
[tool.ruff.lint.per-file-ignores]
119111
"examples/**" = ["E402", "E721", "E722", "F401", "F402"]
120112
"tests/**" = ["E402", "E721", "E722", "F401", "F402"]

requirements.txt

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,7 @@ networkx
1111
httpx
1212
requests
1313
litellm==1.76.1
14-
mcp>=1.28.1,<2.0.0
14+
mcp>=1.28.1,<3.0.0
1515
schedule
1616
opentelemetry-sdk
1717
opentelemetry-exporter-otlp-proto-http

swarms/__init__.py

Lines changed: 33 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -7,10 +7,42 @@
77
bootup()
88

99
from swarms.agents import * # noqa: E402, F403
10-
from swarms.artifacts import * # noqa: E402, F403
1110
from swarms.prompts import * # noqa: E402, F403
1211
from swarms.schemas import * # noqa: E402, F403
1312
from swarms.structs import * # noqa: E402, F403
1413
from swarms.telemetry import * # noqa: E402, F403
1514
from swarms.tools import * # noqa: E402, F403
1615
from swarms.utils import * # noqa: E402, F403
16+
17+
18+
def __getattr__(name: str) -> str:
19+
"""Resolve ``swarms.__version__`` on first access.
20+
21+
The version comes from the installed distribution's metadata rather
22+
than a literal here, so it cannot drift from ``pyproject.toml``.
23+
Resolving it lazily keeps the dist-info scan off the import path for
24+
the majority of programs, which never read it.
25+
"""
26+
if name == "__version__":
27+
from importlib.metadata import (
28+
PackageNotFoundError,
29+
version,
30+
)
31+
32+
try:
33+
resolved = version("swarms")
34+
except PackageNotFoundError:
35+
# A source checkout with no installed distribution.
36+
resolved = "unknown"
37+
38+
globals()["__version__"] = resolved
39+
return resolved
40+
41+
raise AttributeError(
42+
f"module {__name__!r} has no attribute {name!r}"
43+
)
44+
45+
46+
def __dir__() -> list:
47+
"""Advertise ``__version__`` before anything has accessed it."""
48+
return sorted(set(globals()) | {"__version__"})

swarms/agents/autonomous_loop.py

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -145,6 +145,42 @@ def _map_batch_results(
145145
formatter=format_data_structure,
146146
)
147147

148+
def _maybe_compress_context(self) -> bool:
149+
"""Compress the conversation when it nears the context limit.
150+
151+
``ContextCompressor`` measures and compacts
152+
``agent.short_memory``, but the request body actually sent to
153+
the model is ``self._transcript`` — so after a compaction the
154+
transcript is rebuilt around the summary. Compressing only the
155+
mirror would leave the payload growing unbounded, which is the
156+
failure the compressor exists to prevent.
157+
158+
Returns:
159+
bool: True when a compression ran and the transcript was
160+
re-seeded. The caller must then restore whatever immediate
161+
instruction the model needs (e.g. the prompt for the
162+
subtask in flight).
163+
"""
164+
compressor = getattr(self.agent, "_context_compressor", None)
165+
if compressor is None:
166+
return False
167+
summary = compressor.maybe_compress(self.agent)
168+
if summary is None:
169+
return False
170+
171+
# compact() already re-seeded short_memory with the summary,
172+
# so the transcript copy must not be mirrored back a second
173+
# time.
174+
self._transcript = Transcript()
175+
self._say_user(
176+
"[Compressed Memory Summary]\n"
177+
"Earlier turns were compressed to stay within the "
178+
"context window. Progress so far:\n\n"
179+
f"{summary}",
180+
mirror=False,
181+
)
182+
return True
183+
148184
def _run_autonomous_loop(
149185
self,
150186
task: Optional[Union[str, Any]] = None,
@@ -674,6 +710,16 @@ def _run_autonomous_loop(
674710
):
675711
subtask_iterations += 1
676712

713+
# Between iterations every recorded tool call has
714+
# been answered, so this is the one point the
715+
# transcript can be replaced without orphaning a
716+
# tool_call id.
717+
if self._maybe_compress_context():
718+
# The rebuilt transcript holds only the
719+
# summary; restore the instruction for the
720+
# subtask in flight.
721+
self._say_user(execution_prompt)
722+
677723
try:
678724
response = self.agent.call_llm(
679725
task=None,

swarms/artifacts/__init__.py

Lines changed: 0 additions & 5 deletions
This file was deleted.

0 commit comments

Comments
 (0)