swarms 7.8.4__py3-none-any.whl → 7.8.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.
- swarms/agents/ape_agent.py +5 -22
- swarms/agents/consistency_agent.py +1 -1
- swarms/agents/i_agent.py +1 -1
- swarms/agents/reasoning_agents.py +99 -3
- swarms/agents/reasoning_duo.py +1 -1
- swarms/cli/main.py +1 -1
- swarms/communication/__init__.py +1 -0
- swarms/communication/duckdb_wrap.py +32 -2
- swarms/communication/pulsar_struct.py +45 -19
- swarms/communication/redis_wrap.py +56 -11
- swarms/communication/supabase_wrap.py +1659 -0
- swarms/prompts/prompt.py +0 -3
- swarms/schemas/agent_completion_response.py +71 -0
- swarms/schemas/agent_rag_schema.py +7 -0
- swarms/schemas/conversation_schema.py +9 -0
- swarms/schemas/llm_agent_schema.py +99 -81
- swarms/schemas/swarms_api_schemas.py +164 -0
- swarms/structs/__init__.py +14 -11
- swarms/structs/agent.py +219 -199
- swarms/structs/agent_rag_handler.py +685 -0
- swarms/structs/base_swarm.py +2 -1
- swarms/structs/conversation.py +608 -87
- swarms/structs/csv_to_agent.py +153 -100
- swarms/structs/deep_research_swarm.py +197 -193
- swarms/structs/dynamic_conversational_swarm.py +18 -7
- swarms/structs/hiearchical_swarm.py +1 -1
- swarms/structs/hybrid_hiearchical_peer_swarm.py +2 -18
- swarms/structs/image_batch_processor.py +261 -0
- swarms/structs/interactive_groupchat.py +356 -0
- swarms/structs/ma_blocks.py +75 -0
- swarms/structs/majority_voting.py +1 -1
- swarms/structs/mixture_of_agents.py +1 -1
- swarms/structs/multi_agent_router.py +3 -2
- swarms/structs/rearrange.py +3 -3
- swarms/structs/sequential_workflow.py +3 -3
- swarms/structs/swarm_matcher.py +500 -411
- swarms/structs/swarm_router.py +15 -97
- swarms/structs/swarming_architectures.py +1 -1
- swarms/tools/mcp_client_call.py +3 -0
- swarms/utils/__init__.py +10 -2
- swarms/utils/check_all_model_max_tokens.py +43 -0
- swarms/utils/generate_keys.py +0 -27
- swarms/utils/history_output_formatter.py +5 -20
- swarms/utils/litellm_wrapper.py +208 -60
- swarms/utils/output_types.py +24 -0
- swarms/utils/vllm_wrapper.py +5 -6
- swarms/utils/xml_utils.py +37 -2
- {swarms-7.8.4.dist-info → swarms-7.8.7.dist-info}/METADATA +31 -55
- {swarms-7.8.4.dist-info → swarms-7.8.7.dist-info}/RECORD +53 -48
- swarms/structs/multi_agent_collab.py +0 -242
- swarms/structs/output_types.py +0 -6
- swarms/utils/markdown_message.py +0 -21
- swarms/utils/visualizer.py +0 -510
- swarms/utils/wrapper_clusterop.py +0 -127
- /swarms/{tools → schemas}/tool_schema_base_model.py +0 -0
- {swarms-7.8.4.dist-info → swarms-7.8.7.dist-info}/LICENSE +0 -0
- {swarms-7.8.4.dist-info → swarms-7.8.7.dist-info}/WHEEL +0 -0
- {swarms-7.8.4.dist-info → swarms-7.8.7.dist-info}/entry_points.txt +0 -0
swarms/agents/ape_agent.py
CHANGED
@@ -1,27 +1,17 @@
|
|
1
|
-
from typing import
|
1
|
+
from typing import Callable
|
2
2
|
|
3
|
-
from tenacity import retry, stop_after_attempt, wait_exponential
|
4
3
|
|
5
|
-
from swarms.prompts.prompt_generator import (
|
6
|
-
prompt_generator_sys_prompt as second_sys_prompt,
|
7
|
-
)
|
8
4
|
from swarms.prompts.prompt_generator_optimizer import (
|
9
|
-
|
5
|
+
OPENAI_PROMPT_GENERATOR_SYS_PROMPT,
|
10
6
|
)
|
11
7
|
from swarms.utils.loguru_logger import initialize_logger
|
12
8
|
|
13
9
|
logger = initialize_logger(log_folder="ape_agent")
|
14
10
|
|
15
11
|
|
16
|
-
@retry(
|
17
|
-
stop=stop_after_attempt(3),
|
18
|
-
wait=wait_exponential(multiplier=1, min=4, max=10),
|
19
|
-
)
|
20
12
|
def auto_generate_prompt(
|
21
13
|
task: str = None,
|
22
|
-
model:
|
23
|
-
max_tokens: int = 4000,
|
24
|
-
use_second_sys_prompt: bool = True,
|
14
|
+
model: Callable = None,
|
25
15
|
*args,
|
26
16
|
**kwargs,
|
27
17
|
):
|
@@ -38,16 +28,9 @@ def auto_generate_prompt(
|
|
38
28
|
str: The generated prompt.
|
39
29
|
"""
|
40
30
|
try:
|
41
|
-
|
42
|
-
|
43
|
-
if use_second_sys_prompt
|
44
|
-
else prompt_generator_sys_prompt.get_prompt()
|
45
|
-
)
|
46
|
-
output = model.run(
|
47
|
-
system_prompt + task, max_tokens=max_tokens
|
31
|
+
return model.run(
|
32
|
+
task=f"{OPENAI_PROMPT_GENERATOR_SYS_PROMPT} \n\n Task: {task}"
|
48
33
|
)
|
49
|
-
print(output)
|
50
|
-
return output
|
51
34
|
except Exception as e:
|
52
35
|
logger.error(f"Error generating prompt: {str(e)}")
|
53
36
|
raise
|
@@ -7,7 +7,7 @@ from loguru import logger
|
|
7
7
|
from swarms.structs.agent import Agent
|
8
8
|
from swarms.structs.conversation import Conversation
|
9
9
|
from swarms.structs.malt import majority_voting_prompt
|
10
|
-
from swarms.
|
10
|
+
from swarms.utils.output_types import OutputType
|
11
11
|
from swarms.utils.any_to_str import any_to_str
|
12
12
|
from swarms.utils.history_output_formatter import (
|
13
13
|
history_output_formatter,
|
swarms/agents/i_agent.py
CHANGED
@@ -22,7 +22,7 @@ from typing import List, Tuple
|
|
22
22
|
from loguru import logger
|
23
23
|
from swarms.structs.agent import Agent
|
24
24
|
from swarms.structs.conversation import Conversation
|
25
|
-
from swarms.
|
25
|
+
from swarms.utils.output_types import OutputType
|
26
26
|
from swarms.utils.history_output_formatter import (
|
27
27
|
history_output_formatter,
|
28
28
|
)
|
@@ -1,4 +1,4 @@
|
|
1
|
-
from typing import List, Literal
|
1
|
+
from typing import List, Literal, Dict, Callable, Any
|
2
2
|
|
3
3
|
from swarms.agents.consistency_agent import SelfConsistencyAgent
|
4
4
|
from swarms.agents.flexion_agent import ReflexionAgent
|
@@ -7,7 +7,7 @@ from swarms.agents.i_agent import (
|
|
7
7
|
IterativeReflectiveExpansion as IREAgent,
|
8
8
|
)
|
9
9
|
from swarms.agents.reasoning_duo import ReasoningDuo
|
10
|
-
from swarms.
|
10
|
+
from swarms.utils.output_types import OutputType
|
11
11
|
from swarms.agents.agent_judge import AgentJudge
|
12
12
|
|
13
13
|
agent_types = Literal[
|
@@ -62,13 +62,100 @@ class ReasoningAgentRouter:
|
|
62
62
|
self.num_knowledge_items = num_knowledge_items
|
63
63
|
self.memory_capacity = memory_capacity
|
64
64
|
|
65
|
+
# Added: Initialize the factory mapping dictionary
|
66
|
+
self._initialize_agent_factories()
|
67
|
+
|
68
|
+
# Added: Factory method initialization function
|
69
|
+
def _initialize_agent_factories(self) -> None:
|
70
|
+
"""
|
71
|
+
Initialize the agent factory mapping dictionary, mapping various agent types to their respective creation functions.
|
72
|
+
This method replaces the original if-elif chain, making the code easier to maintain and extend.
|
73
|
+
"""
|
74
|
+
self.agent_factories: Dict[str, Callable[[], Any]] = {
|
75
|
+
# ReasoningDuo factory methods
|
76
|
+
"reasoning-duo": self._create_reasoning_duo,
|
77
|
+
"reasoning-agent": self._create_reasoning_duo,
|
78
|
+
# SelfConsistencyAgent factory methods
|
79
|
+
"self-consistency": self._create_consistency_agent,
|
80
|
+
"consistency-agent": self._create_consistency_agent,
|
81
|
+
# IREAgent factory methods
|
82
|
+
"ire": self._create_ire_agent,
|
83
|
+
"ire-agent": self._create_ire_agent,
|
84
|
+
# Other agent type factory methods
|
85
|
+
"AgentJudge": self._create_agent_judge,
|
86
|
+
"ReflexionAgent": self._create_reflexion_agent,
|
87
|
+
"GKPAgent": self._create_gkp_agent,
|
88
|
+
}
|
89
|
+
|
90
|
+
# Added: Concrete factory methods for various agent types
|
91
|
+
def _create_reasoning_duo(self):
|
92
|
+
"""Creates an agent instance for ReasoningDuo type"""
|
93
|
+
return ReasoningDuo(
|
94
|
+
agent_name=self.agent_name,
|
95
|
+
agent_description=self.description,
|
96
|
+
model_name=[self.model_name, self.model_name],
|
97
|
+
system_prompt=self.system_prompt,
|
98
|
+
output_type=self.output_type,
|
99
|
+
)
|
100
|
+
|
101
|
+
def _create_consistency_agent(self):
|
102
|
+
"""Creates an agent instance for SelfConsistencyAgent type"""
|
103
|
+
return SelfConsistencyAgent(
|
104
|
+
agent_name=self.agent_name,
|
105
|
+
description=self.description,
|
106
|
+
model_name=self.model_name,
|
107
|
+
system_prompt=self.system_prompt,
|
108
|
+
max_loops=self.max_loops,
|
109
|
+
num_samples=self.num_samples,
|
110
|
+
output_type=self.output_type,
|
111
|
+
)
|
112
|
+
|
113
|
+
def _create_ire_agent(self):
|
114
|
+
"""Creates an agent instance for IREAgent type"""
|
115
|
+
return IREAgent(
|
116
|
+
agent_name=self.agent_name,
|
117
|
+
description=self.description,
|
118
|
+
model_name=self.model_name,
|
119
|
+
system_prompt=self.system_prompt,
|
120
|
+
max_loops=self.max_loops,
|
121
|
+
max_iterations=self.num_samples,
|
122
|
+
output_type=self.output_type,
|
123
|
+
)
|
124
|
+
|
125
|
+
def _create_agent_judge(self):
|
126
|
+
"""Creates an agent instance for AgentJudge type"""
|
127
|
+
return AgentJudge(
|
128
|
+
agent_name=self.agent_name,
|
129
|
+
model_name=self.model_name,
|
130
|
+
system_prompt=self.system_prompt,
|
131
|
+
max_loops=self.max_loops,
|
132
|
+
)
|
133
|
+
|
134
|
+
def _create_reflexion_agent(self):
|
135
|
+
"""Creates an agent instance for ReflexionAgent type"""
|
136
|
+
return ReflexionAgent(
|
137
|
+
agent_name=self.agent_name,
|
138
|
+
system_prompt=self.system_prompt,
|
139
|
+
model_name=self.model_name,
|
140
|
+
max_loops=self.max_loops,
|
141
|
+
)
|
142
|
+
|
143
|
+
def _create_gkp_agent(self):
|
144
|
+
"""Creates an agent instance for GKPAgent type"""
|
145
|
+
return GKPAgent(
|
146
|
+
agent_name=self.agent_name,
|
147
|
+
model_name=self.model_name,
|
148
|
+
num_knowledge_items=self.num_knowledge_items,
|
149
|
+
)
|
150
|
+
|
65
151
|
def select_swarm(self):
|
66
152
|
"""
|
67
153
|
Selects and initializes the appropriate reasoning swarm based on the specified swarm type.
|
68
|
-
|
69
154
|
Returns:
|
70
155
|
An instance of the selected reasoning swarm.
|
71
156
|
"""
|
157
|
+
# Commented out original if-elif chain implementation
|
158
|
+
"""
|
72
159
|
if (
|
73
160
|
self.swarm_type == "reasoning-duo"
|
74
161
|
or self.swarm_type == "reasoning-agent"
|
@@ -132,6 +219,15 @@ class ReasoningAgentRouter:
|
|
132
219
|
)
|
133
220
|
else:
|
134
221
|
raise ValueError(f"Invalid swarm type: {self.swarm_type}")
|
222
|
+
"""
|
223
|
+
|
224
|
+
# Added: Implementation using factory pattern and dictionary mapping
|
225
|
+
try:
|
226
|
+
# Get the corresponding creation function from the factory dictionary and call it
|
227
|
+
return self.agent_factories[self.swarm_type]()
|
228
|
+
except KeyError:
|
229
|
+
# Maintain the same error handling as the original code
|
230
|
+
raise ValueError(f"Invalid swarm type: {self.swarm_type}")
|
135
231
|
|
136
232
|
def run(self, task: str, *args, **kwargs):
|
137
233
|
"""
|
swarms/agents/reasoning_duo.py
CHANGED
@@ -4,7 +4,7 @@ from loguru import logger
|
|
4
4
|
|
5
5
|
from swarms.prompts.reasoning_prompt import REASONING_PROMPT
|
6
6
|
from swarms.structs.agent import Agent
|
7
|
-
from swarms.
|
7
|
+
from swarms.utils.output_types import OutputType
|
8
8
|
from swarms.structs.conversation import Conversation
|
9
9
|
from swarms.utils.history_output_formatter import (
|
10
10
|
history_output_formatter,
|
swarms/cli/main.py
CHANGED
@@ -67,7 +67,7 @@ def show_ascii_art():
|
|
67
67
|
Text(ASCII_ART, style=f"bold {COLORS['primary']}"),
|
68
68
|
border_style=COLORS["secondary"],
|
69
69
|
title="[bold]Welcome to Swarms[/bold]",
|
70
|
-
subtitle="[dim]
|
70
|
+
subtitle="[dim]swarms.ai[/dim]",
|
71
71
|
)
|
72
72
|
console.print(panel)
|
73
73
|
|
swarms/communication/__init__.py
CHANGED
@@ -0,0 +1 @@
|
|
1
|
+
|
@@ -7,7 +7,6 @@ from contextlib import contextmanager
|
|
7
7
|
from pathlib import Path
|
8
8
|
from typing import Any, Callable, Dict, List, Optional, Union
|
9
9
|
|
10
|
-
import duckdb
|
11
10
|
import yaml
|
12
11
|
|
13
12
|
from swarms.communication.base_communication import (
|
@@ -76,6 +75,37 @@ class DuckDBConversation(BaseCommunication):
|
|
76
75
|
*args,
|
77
76
|
**kwargs,
|
78
77
|
):
|
78
|
+
# Lazy load duckdb with auto-installation
|
79
|
+
try:
|
80
|
+
import duckdb
|
81
|
+
|
82
|
+
self.duckdb = duckdb
|
83
|
+
self.duckdb_available = True
|
84
|
+
except ImportError:
|
85
|
+
# Auto-install duckdb if not available
|
86
|
+
print("📦 DuckDB not found. Installing automatically...")
|
87
|
+
try:
|
88
|
+
import subprocess
|
89
|
+
import sys
|
90
|
+
|
91
|
+
# Install duckdb
|
92
|
+
subprocess.check_call(
|
93
|
+
[sys.executable, "-m", "pip", "install", "duckdb"]
|
94
|
+
)
|
95
|
+
print("✅ DuckDB installed successfully!")
|
96
|
+
|
97
|
+
# Try importing again
|
98
|
+
import duckdb
|
99
|
+
|
100
|
+
self.duckdb = duckdb
|
101
|
+
self.duckdb_available = True
|
102
|
+
print("✅ DuckDB loaded successfully!")
|
103
|
+
|
104
|
+
except Exception as e:
|
105
|
+
raise ImportError(
|
106
|
+
f"Failed to auto-install DuckDB. Please install manually with 'pip install duckdb': {e}"
|
107
|
+
)
|
108
|
+
|
79
109
|
super().__init__(
|
80
110
|
system_prompt=system_prompt,
|
81
111
|
time_enabled=time_enabled,
|
@@ -171,7 +201,7 @@ class DuckDBConversation(BaseCommunication):
|
|
171
201
|
conn = None
|
172
202
|
for attempt in range(self.max_retries):
|
173
203
|
try:
|
174
|
-
conn = duckdb.connect(str(self.db_path))
|
204
|
+
conn = self.duckdb.connect(str(self.db_path))
|
175
205
|
yield conn
|
176
206
|
break
|
177
207
|
except Exception as e:
|
@@ -12,20 +12,6 @@ from swarms.communication.base_communication import (
|
|
12
12
|
)
|
13
13
|
|
14
14
|
|
15
|
-
# Check if Pulsar is available
|
16
|
-
try:
|
17
|
-
import pulsar
|
18
|
-
|
19
|
-
PULSAR_AVAILABLE = True
|
20
|
-
logger.info("Apache Pulsar client library is available")
|
21
|
-
except ImportError as e:
|
22
|
-
PULSAR_AVAILABLE = False
|
23
|
-
logger.error(
|
24
|
-
f"Apache Pulsar client library is not installed: {e}"
|
25
|
-
)
|
26
|
-
logger.error("Please install it using: pip install pulsar-client")
|
27
|
-
|
28
|
-
|
29
15
|
class PulsarConnectionError(Exception):
|
30
16
|
"""Exception raised for Pulsar connection errors."""
|
31
17
|
|
@@ -77,11 +63,48 @@ class PulsarConversation(BaseCommunication):
|
|
77
63
|
**kwargs,
|
78
64
|
):
|
79
65
|
"""Initialize the Pulsar conversation interface."""
|
80
|
-
|
81
|
-
|
82
|
-
|
83
|
-
|
66
|
+
# Lazy load Pulsar with auto-installation
|
67
|
+
try:
|
68
|
+
import pulsar
|
69
|
+
|
70
|
+
self.pulsar = pulsar
|
71
|
+
self.pulsar_available = True
|
72
|
+
except ImportError:
|
73
|
+
# Auto-install pulsar-client if not available
|
74
|
+
print(
|
75
|
+
"📦 Pulsar client not found. Installing automatically..."
|
84
76
|
)
|
77
|
+
try:
|
78
|
+
import subprocess
|
79
|
+
import sys
|
80
|
+
|
81
|
+
# Install pulsar-client
|
82
|
+
subprocess.check_call(
|
83
|
+
[
|
84
|
+
sys.executable,
|
85
|
+
"-m",
|
86
|
+
"pip",
|
87
|
+
"install",
|
88
|
+
"pulsar-client",
|
89
|
+
]
|
90
|
+
)
|
91
|
+
print("✅ Pulsar client installed successfully!")
|
92
|
+
|
93
|
+
# Try importing again
|
94
|
+
import pulsar
|
95
|
+
|
96
|
+
self.pulsar = pulsar
|
97
|
+
self.pulsar_available = True
|
98
|
+
print("✅ Pulsar loaded successfully!")
|
99
|
+
|
100
|
+
except Exception as e:
|
101
|
+
self.pulsar_available = False
|
102
|
+
logger.error(
|
103
|
+
f"Failed to auto-install Pulsar client. Please install manually with 'pip install pulsar-client': {e}"
|
104
|
+
)
|
105
|
+
raise ImportError(
|
106
|
+
f"Failed to auto-install Pulsar client. Please install manually with 'pip install pulsar-client': {e}"
|
107
|
+
)
|
85
108
|
|
86
109
|
logger.info(
|
87
110
|
f"Initializing PulsarConversation with host: {pulsar_host}"
|
@@ -631,7 +654,10 @@ class PulsarConversation(BaseCommunication):
|
|
631
654
|
Returns:
|
632
655
|
bool: True if Pulsar is available and accessible, False otherwise
|
633
656
|
"""
|
634
|
-
|
657
|
+
try:
|
658
|
+
import pulsar
|
659
|
+
|
660
|
+
except ImportError:
|
635
661
|
logger.error("Pulsar client library is not installed")
|
636
662
|
return False
|
637
663
|
|
@@ -11,6 +11,17 @@ from typing import Any, Dict, List, Optional, Union
|
|
11
11
|
|
12
12
|
import yaml
|
13
13
|
|
14
|
+
from loguru import logger
|
15
|
+
|
16
|
+
from swarms.structs.base_structure import BaseStructure
|
17
|
+
from swarms.utils.any_to_str import any_to_str
|
18
|
+
from swarms.utils.formatter import formatter
|
19
|
+
from swarms.utils.litellm_tokenizer import count_tokens
|
20
|
+
|
21
|
+
# Module-level variable to track Redis availability
|
22
|
+
REDIS_AVAILABLE = False
|
23
|
+
|
24
|
+
# Try to import Redis and set availability flag
|
14
25
|
try:
|
15
26
|
import redis
|
16
27
|
from redis.exceptions import (
|
@@ -23,14 +34,36 @@ try:
|
|
23
34
|
|
24
35
|
REDIS_AVAILABLE = True
|
25
36
|
except ImportError:
|
26
|
-
|
37
|
+
# Auto-install Redis at import time
|
38
|
+
print("📦 Redis not found. Installing automatically...")
|
39
|
+
try:
|
40
|
+
import subprocess
|
41
|
+
import sys
|
42
|
+
|
43
|
+
# Install redis
|
44
|
+
subprocess.check_call(
|
45
|
+
[sys.executable, "-m", "pip", "install", "redis"]
|
46
|
+
)
|
47
|
+
print("✅ Redis installed successfully!")
|
48
|
+
|
49
|
+
# Try importing again
|
50
|
+
import redis
|
51
|
+
from redis.exceptions import (
|
52
|
+
AuthenticationError,
|
53
|
+
BusyLoadingError,
|
54
|
+
ConnectionError,
|
55
|
+
RedisError,
|
56
|
+
TimeoutError,
|
57
|
+
)
|
27
58
|
|
28
|
-
|
59
|
+
REDIS_AVAILABLE = True
|
60
|
+
print("✅ Redis loaded successfully!")
|
29
61
|
|
30
|
-
|
31
|
-
|
32
|
-
|
33
|
-
|
62
|
+
except Exception as e:
|
63
|
+
REDIS_AVAILABLE = False
|
64
|
+
print(
|
65
|
+
f"❌ Failed to auto-install Redis. Please install manually with 'pip install redis': {e}"
|
66
|
+
)
|
34
67
|
|
35
68
|
|
36
69
|
class RedisConnectionError(Exception):
|
@@ -96,6 +129,11 @@ rdbchecksum yes
|
|
96
129
|
bool: True if server started successfully, False otherwise
|
97
130
|
"""
|
98
131
|
try:
|
132
|
+
# Check if Redis is available
|
133
|
+
if not REDIS_AVAILABLE:
|
134
|
+
logger.error("Redis package is not installed")
|
135
|
+
return False
|
136
|
+
|
99
137
|
# Use data directory if persistence is enabled and auto_persist is True
|
100
138
|
if not (self.persist and self.auto_persist):
|
101
139
|
self.data_dir = tempfile.mkdtemp()
|
@@ -152,7 +190,11 @@ rdbchecksum yes
|
|
152
190
|
try:
|
153
191
|
if self.process:
|
154
192
|
# Send SAVE and BGSAVE commands before stopping if persistence is enabled
|
155
|
-
if
|
193
|
+
if (
|
194
|
+
self.persist
|
195
|
+
and self.auto_persist
|
196
|
+
and REDIS_AVAILABLE
|
197
|
+
):
|
156
198
|
try:
|
157
199
|
r = redis.Redis(
|
158
200
|
host="localhost", port=self.port
|
@@ -293,14 +335,17 @@ class RedisConversation(BaseStructure):
|
|
293
335
|
RedisConnectionError: If connection to Redis fails.
|
294
336
|
RedisOperationError: If Redis operations fail.
|
295
337
|
"""
|
338
|
+
global REDIS_AVAILABLE
|
339
|
+
|
340
|
+
# Check if Redis is available (should be True after module import auto-installation)
|
296
341
|
if not REDIS_AVAILABLE:
|
297
|
-
logger.error(
|
298
|
-
"Redis package is not installed. Please install it with 'pip install redis'"
|
299
|
-
)
|
300
342
|
raise ImportError(
|
301
|
-
"Redis
|
343
|
+
"Redis is not available. Module-level auto-installation failed. "
|
344
|
+
"Please install manually with 'pip install redis'"
|
302
345
|
)
|
303
346
|
|
347
|
+
self.redis_available = True
|
348
|
+
|
304
349
|
super().__init__()
|
305
350
|
self.system_prompt = system_prompt
|
306
351
|
self.time_enabled = time_enabled
|