swarms 7.7.5__py3-none-any.whl → 7.7.7__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.
@@ -1,6 +1,8 @@
1
1
  import datetime
2
2
  import json
3
- from typing import Any, List, Optional, Union
3
+ from typing import Any, List, Optional, Union, Dict
4
+ import threading
5
+ import hashlib
4
6
 
5
7
  import yaml
6
8
  from swarms.structs.base_structure import BaseStructure
@@ -8,7 +10,6 @@ from typing import TYPE_CHECKING
8
10
  from swarms.utils.any_to_str import any_to_str
9
11
  from swarms.utils.formatter import formatter
10
12
  from swarms.utils.litellm_tokenizer import count_tokens
11
- import threading
12
13
 
13
14
  if TYPE_CHECKING:
14
15
  from swarms.structs.agent import (
@@ -37,6 +38,9 @@ class Conversation(BaseStructure):
37
38
  save_as_json_bool (bool): Flag to save conversation history as JSON.
38
39
  token_count (bool): Flag to enable token counting for messages.
39
40
  conversation_history (list): List to store the history of messages.
41
+ cache_enabled (bool): Flag to enable prompt caching.
42
+ cache_stats (dict): Statistics about cache usage.
43
+ cache_lock (threading.Lock): Lock for thread-safe cache operations.
40
44
  """
41
45
 
42
46
  def __init__(
@@ -54,6 +58,7 @@ class Conversation(BaseStructure):
54
58
  save_as_yaml: bool = True,
55
59
  save_as_json_bool: bool = False,
56
60
  token_count: bool = True,
61
+ cache_enabled: bool = True,
57
62
  *args,
58
63
  **kwargs,
59
64
  ):
@@ -74,6 +79,7 @@ class Conversation(BaseStructure):
74
79
  save_as_yaml (bool): Flag to save conversation history as YAML.
75
80
  save_as_json_bool (bool): Flag to save conversation history as JSON.
76
81
  token_count (bool): Flag to enable token counting for messages.
82
+ cache_enabled (bool): Flag to enable prompt caching.
77
83
  """
78
84
  super().__init__()
79
85
  self.system_prompt = system_prompt
@@ -90,6 +96,14 @@ class Conversation(BaseStructure):
90
96
  self.save_as_yaml = save_as_yaml
91
97
  self.save_as_json_bool = save_as_json_bool
92
98
  self.token_count = token_count
99
+ self.cache_enabled = cache_enabled
100
+ self.cache_stats = {
101
+ "hits": 0,
102
+ "misses": 0,
103
+ "cached_tokens": 0,
104
+ "total_tokens": 0,
105
+ }
106
+ self.cache_lock = threading.Lock()
93
107
 
94
108
  # If system prompt is not None, add it to the conversation history
95
109
  if self.system_prompt is not None:
@@ -105,6 +119,61 @@ class Conversation(BaseStructure):
105
119
  if tokenizer is not None:
106
120
  self.truncate_memory_with_tokenizer()
107
121
 
122
+ def _generate_cache_key(
123
+ self, content: Union[str, dict, list]
124
+ ) -> str:
125
+ """Generate a cache key for the given content.
126
+
127
+ Args:
128
+ content (Union[str, dict, list]): The content to generate a cache key for.
129
+
130
+ Returns:
131
+ str: The cache key.
132
+ """
133
+ if isinstance(content, (dict, list)):
134
+ content = json.dumps(content, sort_keys=True)
135
+ return hashlib.md5(content.encode()).hexdigest()
136
+
137
+ def _get_cached_tokens(
138
+ self, content: Union[str, dict, list]
139
+ ) -> Optional[int]:
140
+ """Get the number of cached tokens for the given content.
141
+
142
+ Args:
143
+ content (Union[str, dict, list]): The content to check.
144
+
145
+ Returns:
146
+ Optional[int]: The number of cached tokens, or None if not cached.
147
+ """
148
+ if not self.cache_enabled:
149
+ return None
150
+
151
+ with self.cache_lock:
152
+ cache_key = self._generate_cache_key(content)
153
+ if cache_key in self.cache_stats:
154
+ self.cache_stats["hits"] += 1
155
+ return self.cache_stats[cache_key]
156
+ self.cache_stats["misses"] += 1
157
+ return None
158
+
159
+ def _update_cache_stats(
160
+ self, content: Union[str, dict, list], token_count: int
161
+ ):
162
+ """Update cache statistics for the given content.
163
+
164
+ Args:
165
+ content (Union[str, dict, list]): The content to update stats for.
166
+ token_count (int): The number of tokens in the content.
167
+ """
168
+ if not self.cache_enabled:
169
+ return
170
+
171
+ with self.cache_lock:
172
+ cache_key = self._generate_cache_key(content)
173
+ self.cache_stats[cache_key] = token_count
174
+ self.cache_stats["cached_tokens"] += token_count
175
+ self.cache_stats["total_tokens"] += token_count
176
+
108
177
  def add(
109
178
  self,
110
179
  role: str,
@@ -118,7 +187,6 @@ class Conversation(BaseStructure):
118
187
  role (str): The role of the speaker (e.g., 'User', 'System').
119
188
  content (Union[str, dict, list]): The content of the message to be added.
120
189
  """
121
-
122
190
  # Base message with role
123
191
  message = {
124
192
  "role": role,
@@ -134,10 +202,20 @@ class Conversation(BaseStructure):
134
202
  else:
135
203
  message["content"] = content
136
204
 
205
+ # Check cache for token count
206
+ cached_tokens = self._get_cached_tokens(content)
207
+ if cached_tokens is not None:
208
+ message["token_count"] = cached_tokens
209
+ message["cached"] = True
210
+ else:
211
+ message["cached"] = False
212
+
137
213
  # Add the message to history immediately without waiting for token count
138
214
  self.conversation_history.append(message)
139
215
 
140
- if self.token_count is True:
216
+ if self.token_count is True and not message.get(
217
+ "cached", False
218
+ ):
141
219
  self._count_tokens(content, message)
142
220
 
143
221
  def add_multiple_messages(
@@ -155,6 +233,8 @@ class Conversation(BaseStructure):
155
233
  tokens = count_tokens(any_to_str(content))
156
234
  # Update the message that's already in the conversation history
157
235
  message["token_count"] = int(tokens)
236
+ # Update cache stats
237
+ self._update_cache_stats(content, int(tokens))
158
238
 
159
239
  # If autosave is enabled, save after token count is updated
160
240
  if self.autosave:
@@ -277,13 +357,23 @@ class Conversation(BaseStructure):
277
357
  ]
278
358
  )
279
359
 
280
- def get_str(self):
360
+ def get_str(self) -> str:
281
361
  """Get the conversation history as a string.
282
362
 
283
363
  Returns:
284
364
  str: The conversation history.
285
365
  """
286
- return self.return_history_as_string()
366
+ messages = []
367
+ for message in self.conversation_history:
368
+ content = message["content"]
369
+ if isinstance(content, (dict, list)):
370
+ content = json.dumps(content)
371
+ messages.append(f"{message['role']}: {content}")
372
+ if "token_count" in message:
373
+ messages[-1] += f" (tokens: {message['token_count']})"
374
+ if message.get("cached", False):
375
+ messages[-1] += " [cached]"
376
+ return "\n".join(messages)
287
377
 
288
378
  def save_as_json(self, filename: str = None):
289
379
  """Save the conversation history as a JSON file.
@@ -512,6 +602,33 @@ class Conversation(BaseStructure):
512
602
  """
513
603
  self.conversation_history.extend(messages)
514
604
 
605
+ def get_cache_stats(self) -> Dict[str, int]:
606
+ """Get statistics about cache usage.
607
+
608
+ Returns:
609
+ Dict[str, int]: Statistics about cache usage.
610
+ """
611
+ with self.cache_lock:
612
+ return {
613
+ "hits": self.cache_stats["hits"],
614
+ "misses": self.cache_stats["misses"],
615
+ "cached_tokens": self.cache_stats["cached_tokens"],
616
+ "total_tokens": self.cache_stats["total_tokens"],
617
+ "hit_rate": (
618
+ self.cache_stats["hits"]
619
+ / (
620
+ self.cache_stats["hits"]
621
+ + self.cache_stats["misses"]
622
+ )
623
+ if (
624
+ self.cache_stats["hits"]
625
+ + self.cache_stats["misses"]
626
+ )
627
+ > 0
628
+ else 0
629
+ ),
630
+ }
631
+
515
632
 
516
633
  # # Example usage
517
634
  # # conversation = Conversation()
@@ -1,10 +1,8 @@
1
1
  import concurrent.futures
2
2
  import random
3
- from datetime import datetime
4
3
  from typing import Callable, List
5
4
 
6
5
  from loguru import logger
7
- from pydantic import BaseModel, Field
8
6
 
9
7
  from swarms.structs.agent import Agent
10
8
  from swarms.structs.conversation import Conversation
@@ -16,16 +14,6 @@ from swarms.prompts.multi_agent_collab_prompt import (
16
14
  MULTI_AGENT_COLLAB_PROMPT_TWO,
17
15
  )
18
16
 
19
-
20
- class AgentResponse(BaseModel):
21
- agent_name: str
22
- role: str
23
- message: str
24
- timestamp: datetime = Field(default_factory=datetime.now)
25
- turn_number: int
26
- preceding_context: List[str] = Field(default_factory=list)
27
-
28
-
29
17
  SpeakerFunction = Callable[[List[str], "Agent"], bool]
30
18
 
31
19
 
@@ -1168,7 +1168,6 @@ class ModelGrid:
1168
1168
  try:
1169
1169
  # This would need to be implemented based on the specific model types
1170
1170
  # and tasks supported. Here's a simple placeholder:
1171
- model = model_metadata.model
1172
1171
 
1173
1172
  if model_metadata.model_type == ModelType.PYTORCH:
1174
1173
  # Run PyTorch model
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: swarms
3
- Version: 7.7.5
3
+ Version: 7.7.7
4
4
  Summary: Swarms - TGSC
5
5
  Home-page: https://github.com/kyegomez/swarms
6
6
  License: MIT
@@ -1,5 +1,5 @@
1
1
  swarms/__init__.py,sha256=YxGdUrWHekSiNneyQUM7Yrdf6pCIy2-xgIzhocZY0Ek,561
2
- swarms/agents/__init__.py,sha256=ebUrX9rMccQokq5XthgnzGDMISn8EyQyOIOwVAlLs1E,1190
2
+ swarms/agents/__init__.py,sha256=hEp16SuPhlcLX84HAlaK_9RNf6JB0JQ27YTrTnvak04,1171
3
3
  swarms/agents/agent_judge.py,sha256=xT242CX5mV64cq2B-3RGkuEHiV5aD04P_Zq8_s64iMQ,3967
4
4
  swarms/agents/agent_print.py,sha256=SXqWA2ZzXwRFdv8hkuYwOPMTasvaGTG6U29413qRCAA,918
5
5
  swarms/agents/ape_agent.py,sha256=1kz_65LJgjLlY1yv2WLBeVMs7sP9BgEVWk0w1f67YLc,1563
@@ -22,7 +22,7 @@ swarms/cli/onboarding_process.py,sha256=3-2LKoLhjnaPbX9iiasqXPZZpqmwm-ZrXawH88M4
22
22
  swarms/client/__init__.py,sha256=VASeCEYoZskTU3NOw5tQ22uc2_7gyK0oLsxG_WB20ys,268
23
23
  swarms/client/main.py,sha256=f-RpvfKfRK2AaapkyPN2ihXJvIGN4JWB_A7pJu4WyiU,13735
24
24
  swarms/communication/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
25
- swarms/communication/duckdb_wrap.py,sha256=CFJ3OlIlBLT6y68I3FB_74yikyHqFAK0GNs14g383LM,33821
25
+ swarms/communication/duckdb_wrap.py,sha256=5wfvGM00fsxkp-wqXh7bxyQBlQ4a05Z-vh_YA7k3B5M,33938
26
26
  swarms/communication/sqlite_wrap.py,sha256=Yl8gnaHL685GwJc6eHAqJ5nY-xn_nZHyn4i7rhUj9kQ,26236
27
27
  swarms/prompts/__init__.py,sha256=ZFcghAs4b0Rsjcc_DIFssiztZub5tJ66rxmJD2_tXpQ,747
28
28
  swarms/prompts/accountant_swarm_prompts.py,sha256=swceN1B0fZCOedd3-y3gjNOHDmR-3H5YK17ytp7tTDM,11320
@@ -48,6 +48,7 @@ swarms/prompts/growth_agent_prompt.py,sha256=mOxIbuhsAp5QxE4m8DADNHnMI9rAmIbatNo
48
48
  swarms/prompts/idea2img.py,sha256=ZM-iD0ZFuqU2V1SY3V5Ds6ItTDd6JzQ4vpmz3faMzlM,880
49
49
  swarms/prompts/legal_agent_prompt.py,sha256=DhIroYuviqrU7cgKz6F8U2LNSBykLH57AZqoH5AfD0U,3346
50
50
  swarms/prompts/logistics.py,sha256=_XT_feYFgv-1IzHi5cPKuAp8xBjSX5KqwlPKh9xfK7E,4785
51
+ swarms/prompts/max_loop_prompt.py,sha256=04YPA71i0w5xxaDEtTYJbc4Jf1dRHDFCLCIvBRysjM0,1896
51
52
  swarms/prompts/meta_system_prompt.py,sha256=GOsWqtGfFezpKyg8c876Y-kCkWGI563iS2-0AaI__MI,3374
52
53
  swarms/prompts/multi_agent_collab_prompt.py,sha256=C2fX9fEJhGudG-lzvTqfzQbmJdZfgi0RRSPY9RZ1f38,13419
53
54
  swarms/prompts/multi_modal_autonomous_instruction_prompt.py,sha256=SHfaKs5Hj9sV4jgtVAFhv1N_N2e3jKwvdx_8G8-OdhM,10662
@@ -64,6 +65,7 @@ swarms/prompts/prompt_generator.py,sha256=56xRcy9J86c-Z18HGKExsArVff2AdmmSDs7C8n
64
65
  swarms/prompts/prompt_generator_optimizer.py,sha256=ODhXgN4cIHbuuSOPrt1iTzntKeQm71hNUiZsqf-gj1M,3823
65
66
  swarms/prompts/python.py,sha256=JgykzeNYLHHVvjoTR5FhZEVWJFc3SWCMgf-mRN3yMEo,13215
66
67
  swarms/prompts/react.py,sha256=nPuaIgKD2xV41y0PR06mrkC82GnWk4mw0apkrcYS_cY,2960
68
+ swarms/prompts/react_base_prompt.py,sha256=vN82wlxwj7c5PzIXMDcXg17950D2UZDDLaaRhGiAbQA,1928
67
69
  swarms/prompts/reasoning_prompt.py,sha256=tnuJWK9VHer0IvgwjUXCM5ixMn-yfozQL0KgKQKciu4,1113
68
70
  swarms/prompts/refiner_agent_prompt.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
69
71
  swarms/prompts/sales.py,sha256=tIr46slbRA8KxoOERE83DX10cGvwafzocpR00KcG_tM,5126
@@ -85,7 +87,7 @@ swarms/schemas/__init__.py,sha256=AZ7BZE3bLabA5_m83jbELB6SaOMHx1MhMy9EeUODBqs,10
85
87
  swarms/schemas/agent_step_schemas.py,sha256=a14gb58vR0xOwB_fwSJQbN6yb9HddEaT30E6hUrzEQA,2573
86
88
  swarms/schemas/base_schemas.py,sha256=UvBLVWg2qRen4tK5GJz50v42SiX95EQ5qK7hfyAHTEU,3267
87
89
  swarms/structs/__init__.py,sha256=jfvyqtA5WMpjYgvmngBqijwOhjLhRkjWAucPGe91THU,4051
88
- swarms/structs/agent.py,sha256=3RzXpVKnYYlAiOFxzTr9Jw9ej3J3j-Vz0BelQSZhxdg,99677
90
+ swarms/structs/agent.py,sha256=aLJXVI4C32HuhQCo4L9NujxWSL4vRVQewqM9lW3GHaA,98377
89
91
  swarms/structs/agent_builder.py,sha256=tYNpfO4_8cgfMHfgA5DAOWffHnt70p6CLt59esqfVCY,12133
90
92
  swarms/structs/agent_registry.py,sha256=il507cO1NF-d4ChyANVLuWrN8bXsEAi8_7bLJ_sTU6A,12112
91
93
  swarms/structs/agent_roles.py,sha256=8XEw6RjOOZelaZaWt4gXaYQm5WMLEhSO7W6Z8sQjmFg,582
@@ -96,14 +98,14 @@ swarms/structs/base_structure.py,sha256=GDu4QJQQmhU7IyuFJHIh9UVThACCva-L7uoMbVD9
96
98
  swarms/structs/base_swarm.py,sha256=LSGJDPJdyUCcK6698mNtjxoC1OU3s_J2NxC2k_ccGUs,23779
97
99
  swarms/structs/base_workflow.py,sha256=DTfFwX3AdFYxACDYwUDqhsbcDZnITlg5TeEYyxmJBCc,11414
98
100
  swarms/structs/concat.py,sha256=utezSxNyh1mIwXgdf8-dJ803NDPyEy79WE8zJHuooGk,732
99
- swarms/structs/concurrent_workflow.py,sha256=d1_slbALpxrdEGzZffUSAcEbONW0kc7fyTpVZTBmzi4,15517
100
- swarms/structs/conversation.py,sha256=pBJZ24ONvhpgjG21PAR4Jv9NSAZdpc-a3cQgg-vTapk,17683
101
+ swarms/structs/concurrent_workflow.py,sha256=IANeOnzHcHZfrmNG6HA1RXaZLRQv6q89DiOxUg2q0Hw,20490
102
+ swarms/structs/conversation.py,sha256=_b9YddnIi8uhTjDQMGQSW-oSUfMG5tcwIm0Yi6yMF_o,21899
101
103
  swarms/structs/csv_to_agent.py,sha256=ug9JqQFPguXeU9JQpSUXuVtOpHYdJhlpKJUJBovo694,9443
102
104
  swarms/structs/de_hallucination_swarm.py,sha256=9cC0rSSXGwYu6SRDwpeMbCcQ40C1WI1RE9SNapKRLOQ,10309
103
105
  swarms/structs/deep_research_swarm.py,sha256=axhzSK43-TViQJntt2Gz2AUhAc6zoBPzj9weRmQ8yE8,16733
104
106
  swarms/structs/dynamic_conversational_swarm.py,sha256=n_d1jDCzBwiGb0QjJpW_MlXxqEkhGEhC1ttaebH7f3Q,8098
105
107
  swarms/structs/graph_workflow.py,sha256=TAaUG_J3898hhghPOp0WEAV3Zf0in6s48ZSVbSTX-vQ,8629
106
- swarms/structs/groupchat.py,sha256=CivOw0QlpjugG8MIu5uGGVoA_0_oY6sBg0XlA08gViQ,15691
108
+ swarms/structs/groupchat.py,sha256=jjH0BqU9Nrd_3jl9QzrcvbSce527SFpUaepawaRiw2o,15391
107
109
  swarms/structs/hiearchical_swarm.py,sha256=2x3InS4HJg4T9Y195l_ANTGu6DYcllqCdJcR3v5Xuro,33402
108
110
  swarms/structs/hybrid_hiearchical_peer_swarm.py,sha256=D1iBtNNee_mxPoOWS5WGTqcci5FQKtt38mW-J42GvfM,9494
109
111
  swarms/structs/ma_utils.py,sha256=FxMNCmeSpYEczZOxK0gpgn5a50CJTc1USmRHCqvxP54,3091
@@ -116,7 +118,7 @@ swarms/structs/model_router.py,sha256=V5pZHYlxSmCvAA2Gsns7LaCz8dXtRi7pCvb-oLGHYI
116
118
  swarms/structs/multi_agent_collab.py,sha256=odh2NQRR23LidsphCxUfAke369lDdgL__w3Xovu9jkA,7731
117
119
  swarms/structs/multi_agent_exec.py,sha256=Gxwr9mHADX3n29pdxor-dQDnKPSNdnicpCxBLmPwnLg,14344
118
120
  swarms/structs/multi_agent_router.py,sha256=21PfswEuxMHqlWDBCyritj9UuHTShYVQRaK0o23eia8,10999
119
- swarms/structs/multi_model_gpu_manager.py,sha256=h5y4eNCeBRbBqK36ifPp0RkzVbdbTrIS-Vh_LXLD0-U,47400
121
+ swarms/structs/multi_model_gpu_manager.py,sha256=Rdzj1l6wkrYlSx21ImWMt88tFSI-gTM3S3_uTOpkUOI,47355
120
122
  swarms/structs/omni_agent_types.py,sha256=RdKLfZ-lXDJrEa0aJT_Rfx9TypJQo8SISqKz4fnLkAk,230
121
123
  swarms/structs/output_types.py,sha256=zseJBL2e50nXWy71VeAY31z9Bb2ugq9ohWUYk1xQV20,158
122
124
  swarms/structs/rearrange.py,sha256=5u7HwTVVH414w9rhEQvLdltW1ACHjgwn-zS8-8JEXmA,22576
@@ -179,8 +181,8 @@ swarms/utils/try_except_wrapper.py,sha256=appEGu9Afy3TmdkNNXUgQ9yU9lj2j0uNkIoW0J
179
181
  swarms/utils/visualizer.py,sha256=0ylohEk62MAS6iPRaDOV03m9qo2k5J56tWlKJk_46p4,16927
180
182
  swarms/utils/vllm_wrapper.py,sha256=OIGnU9Vf81vE_hul1FK-xEhChFK8fxqZX6-fhQeW22c,4987
181
183
  swarms/utils/wrapper_clusterop.py,sha256=PMSCVM7ZT1vgj1D_MYAe835RR3SMLYxA-si2JS02yNQ,4220
182
- swarms-7.7.5.dist-info/LICENSE,sha256=jwRtEmTWjLrEsvFB6QFdYs2cEeZPRMdj-UMOFkPF8_0,11363
183
- swarms-7.7.5.dist-info/METADATA,sha256=4upfKa3OHBekr8msGULk_k8SY28U0vpdjj3hzYi5ioQ,94905
184
- swarms-7.7.5.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
185
- swarms-7.7.5.dist-info/entry_points.txt,sha256=2K0rTtfO1X1WaO-waJlXIKw5Voa_EpAL_yU0HXE2Jgc,47
186
- swarms-7.7.5.dist-info/RECORD,,
184
+ swarms-7.7.7.dist-info/LICENSE,sha256=jwRtEmTWjLrEsvFB6QFdYs2cEeZPRMdj-UMOFkPF8_0,11363
185
+ swarms-7.7.7.dist-info/METADATA,sha256=8sfugkhNnSTdWHLiBYlN1wMcI6MktUn7ikNakfBytyw,94905
186
+ swarms-7.7.7.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
187
+ swarms-7.7.7.dist-info/entry_points.txt,sha256=2K0rTtfO1X1WaO-waJlXIKw5Voa_EpAL_yU0HXE2Jgc,47
188
+ swarms-7.7.7.dist-info/RECORD,,
File without changes