Skip to content

Commit 8d8fab2

Browse files
committed
Merge remote-tracking branch 'origin/master' into terminate-chatagent
2 parents ceb3ec4 + ddd05ff commit 8d8fab2

File tree

72 files changed

+13935
-11110
lines changed

Some content is hidden

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

72 files changed

+13935
-11110
lines changed

.github/workflows/build_package.yml

Lines changed: 38 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,15 @@ jobs:
1010
steps:
1111
- uses: actions/checkout@v3
1212

13-
- name: Clean up before build
13+
- name: Free disk space
1414
run: |
1515
sudo apt-get clean
16+
sudo apt-get autoremove -y
1617
sudo rm -rf /var/lib/apt/lists/*
18+
sudo rm -rf /usr/share/dotnet
19+
sudo rm -rf /opt/ghc
20+
sudo rm -rf /usr/local/share/boost
21+
sudo rm -rf /usr/local/lib/android
1722
sudo rm -rf /tmp/*
1823
sudo rm -rf $HOME/.cache/pip
1924
df -h
@@ -30,17 +35,38 @@ jobs:
3035
- name: Create virtual environment
3136
run: |
3237
uv venv .venv --python=3.10
38+
df -h
3339
34-
- name: Install dependencies
40+
- name: Install core dependencies
3541
run: |
3642
source .venv/bin/activate
37-
uv pip install -e ".[all, dev, docs]"
43+
# Install just the core dependencies first
44+
uv pip install -e "."
45+
df -h
3846
39-
- name: Build
47+
- name: Install dev dependencies
48+
run: |
49+
source .venv/bin/activate
50+
# Install dev dependencies separately
51+
uv pip install -e ".[dev]"
52+
df -h
53+
54+
- name: Install docs dependencies
55+
run: |
56+
source .venv/bin/activate
57+
# Install docs dependencies separately
58+
uv pip install -e ".[docs]"
59+
df -h
60+
61+
- name: Install build tools
4062
run: |
4163
source .venv/bin/activate
42-
uv pip install -e ".[all, dev, docs]"
4364
uv pip install build
65+
df -h
66+
67+
- name: Build
68+
run: |
69+
source .venv/bin/activate
4470
python -m build
4571
4672
- name: Set up test environment
@@ -108,6 +134,8 @@ jobs:
108134
BEDROCK_API_BASE_URL: "${{ secrets.BEDROCK_API_BASE_URL }}"
109135
NETMIND_API_KEY: "${{ secrets.NETMIND_API_KEY }}"
110136
NOVITA_API_KEY: "${{ secrets.NOVITA_API_KEY }}"
137+
WATSONX_API_KEY: "${{ secrets.WATSONX_API_KEY }}"
138+
WATSONX_PROJECT_ID: "${{ secrets.WATSONX_PROJECT_ID }}"
111139
run: |
112140
source test_venv/bin/activate
113141
pytest --fast-test-mode ./test
@@ -116,7 +144,12 @@ jobs:
116144
if: always()
117145
run: |
118146
sudo apt-get clean
147+
sudo apt-get autoremove -y
119148
sudo rm -rf /var/lib/apt/lists/*
149+
sudo rm -rf /usr/share/dotnet
150+
sudo rm -rf /opt/ghc
151+
sudo rm -rf /usr/local/share/boost
152+
sudo rm -rf /usr/local/lib/android
120153
sudo rm -rf /tmp/*
121154
sudo rm -rf $HOME/.cache/pip
122155
df -h

.github/workflows/pytest_package.yml

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,6 +73,8 @@ jobs:
7373
BEDROCK_API_BASE_URL: "${{ secrets.BEDROCK_API_BASE_URL }}"
7474
NETMIND_API_KEY: "${{ secrets.NETMIND_API_KEY }}"
7575
NOVITA_API_KEY: "${{ secrets.NOVITA_API_KEY }}"
76+
WATSONX_API_KEY: "${{ secrets.WATSONX_API_KEY }}"
77+
WATSONX_PROJECT_ID: "${{ secrets.WATSONX_PROJECT_ID }}"
7678
run: |
7779
source .venv/bin/activate
7880
uv pip install -e ".[all, dev, docs]"
@@ -138,6 +140,8 @@ jobs:
138140
BEDROCK_API_BASE_URL: "${{ secrets.BEDROCK_API_BASE_URL }}"
139141
NETMIND_API_KEY: "${{ secrets.NETMIND_API_KEY }}"
140142
NOVITA_API_KEY: "${{ secrets.NOVITA_API_KEY }}"
143+
WATSONX_API_KEY: "${{ secrets.WATSONX_API_KEY }}"
144+
WATSONX_PROJECT_ID: "${{ secrets.WATSONX_PROJECT_ID }}"
141145
run: |
142146
source .venv/bin/activate
143147
uv pip install -e ".[all, dev, docs]"
@@ -201,6 +205,8 @@ jobs:
201205
BEDROCK_API_BASE_URL: "${{ secrets.BEDROCK_API_BASE_URL }}"
202206
NETMIND_API_KEY: "${{ secrets.NETMIND_API_KEY }}"
203207
NOVITA_API_KEY: "${{ secrets.NOVITA_API_KEY }}"
208+
WATSONX_API_KEY: "${{ secrets.WATSONX_API_KEY }}"
209+
WATSONX_PROJECT_ID: "${{ secrets.WATSONX_PROJECT_ID }}"
204210
run: |
205211
source .venv/bin/activate
206212
uv pip install -e ".[all, dev, docs]"

camel/agents/chat_agent.py

Lines changed: 159 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,7 @@
2828
List,
2929
Optional,
3030
Set,
31+
Tuple,
3132
Type,
3233
Union,
3334
)
@@ -78,7 +79,6 @@
7879
if TYPE_CHECKING:
7980
from camel.terminators import ResponseTerminator
8081

81-
8282
logger = logging.getLogger(__name__)
8383

8484
# AgentOps decorator setting
@@ -110,10 +110,17 @@ class ChatAgent(BaseAgent):
110110
111111
Args:
112112
system_message (Union[BaseMessage, str], optional): The system message
113-
for the chat agent.
114-
model (BaseModelBackend, optional): The model backend to use for
115-
generating responses. (default: :obj:`ModelPlatformType.DEFAULT`
116-
with `ModelType.DEFAULT`)
113+
for the chat agent. (default: :obj:`None`)
114+
model (Union[BaseModelBackend, Tuple[str, str], str, ModelType,
115+
Tuple[ModelPlatformType, ModelType], List[BaseModelBackend],
116+
List[str], List[ModelType], List[Tuple[str, str]],
117+
List[Tuple[ModelPlatformType, ModelType]]], optional):
118+
The model backend(s) to use. Can be a single instance,
119+
a specification (string, enum, tuple), or a list of instances
120+
or specifications to be managed by `ModelManager`. If a list of
121+
specifications (not `BaseModelBackend` instances) is provided,
122+
they will be instantiated using `ModelFactory`. (default:
123+
:obj:`ModelPlatformType.DEFAULT` with `ModelType.DEFAULT`)
117124
memory (AgentMemory, optional): The agent memory for managing chat
118125
messages. If `None`, a :obj:`ChatHistoryMemory` will be used.
119126
(default: :obj:`None`)
@@ -150,7 +157,18 @@ def __init__(
150157
self,
151158
system_message: Optional[Union[BaseMessage, str]] = None,
152159
model: Optional[
153-
Union[BaseModelBackend, List[BaseModelBackend]]
160+
Union[
161+
BaseModelBackend,
162+
Tuple[str, str],
163+
str,
164+
ModelType,
165+
Tuple[ModelPlatformType, ModelType],
166+
List[BaseModelBackend],
167+
List[str],
168+
List[ModelType],
169+
List[Tuple[str, str]],
170+
List[Tuple[ModelPlatformType, ModelType]],
171+
]
154172
] = None,
155173
memory: Optional[AgentMemory] = None,
156174
message_window_size: Optional[int] = None,
@@ -165,19 +183,14 @@ def __init__(
165183
single_iteration: bool = False,
166184
agent_id: Optional[str] = None,
167185
) -> None:
168-
# Set up model backend
186+
# Resolve model backends and set up model manager
187+
resolved_models = self._resolve_models(model)
169188
self.model_backend = ModelManager(
170-
(
171-
model
172-
if model is not None
173-
else ModelFactory.create(
174-
model_platform=ModelPlatformType.DEFAULT,
175-
model_type=ModelType.DEFAULT,
176-
)
177-
),
189+
resolved_models,
178190
scheduling_strategy=scheduling_strategy,
179191
)
180192
self.model_type = self.model_backend.model_type
193+
181194
# Assign unique ID
182195
self.agent_id = agent_id if agent_id else str(uuid.uuid4())
183196

@@ -247,6 +260,137 @@ def reset(self):
247260
for terminator in self.response_terminators:
248261
terminator.reset()
249262

263+
def _resolve_models(
264+
self,
265+
model: Optional[
266+
Union[
267+
BaseModelBackend,
268+
Tuple[str, str],
269+
str,
270+
ModelType,
271+
Tuple[ModelPlatformType, ModelType],
272+
List[BaseModelBackend],
273+
List[str],
274+
List[ModelType],
275+
List[Tuple[str, str]],
276+
List[Tuple[ModelPlatformType, ModelType]],
277+
]
278+
],
279+
) -> Union[BaseModelBackend, List[BaseModelBackend]]:
280+
r"""Resolves model specifications into model backend instances.
281+
282+
This method handles various input formats for model specifications and
283+
returns the appropriate model backend(s).
284+
285+
Args:
286+
model: Model specification in various formats including single
287+
model, list of models, or model type specifications.
288+
289+
Returns:
290+
Union[BaseModelBackend, List[BaseModelBackend]]: Resolved model
291+
backend(s).
292+
293+
Raises:
294+
TypeError: If the model specification format is not supported.
295+
"""
296+
if model is None:
297+
# Default single model if none provided
298+
return ModelFactory.create(
299+
model_platform=ModelPlatformType.DEFAULT,
300+
model_type=ModelType.DEFAULT,
301+
)
302+
elif isinstance(model, BaseModelBackend):
303+
# Already a single pre-instantiated model
304+
return model
305+
elif isinstance(model, list):
306+
return self._resolve_model_list(model)
307+
elif isinstance(model, (ModelType, str)):
308+
# Single string or ModelType -> use default platform
309+
model_platform = ModelPlatformType.DEFAULT
310+
model_type = model
311+
logger.warning(
312+
f"Model type '{model_type}' provided without a platform. "
313+
f"Using platform '{model_platform}'. Note: platform "
314+
"is not automatically inferred based on model type."
315+
)
316+
return ModelFactory.create(
317+
model_platform=model_platform,
318+
model_type=model_type,
319+
)
320+
elif isinstance(model, tuple) and len(model) == 2:
321+
# Single tuple (platform, type)
322+
model_platform, model_type = model # type: ignore[assignment]
323+
return ModelFactory.create(
324+
model_platform=model_platform,
325+
model_type=model_type,
326+
)
327+
else:
328+
raise TypeError(
329+
f"Unsupported type for model parameter: {type(model)}"
330+
)
331+
332+
def _resolve_model_list(
333+
self, model_list: list
334+
) -> Union[BaseModelBackend, List[BaseModelBackend]]:
335+
r"""Resolves a list of model specifications into model backend
336+
instances.
337+
338+
Args:
339+
model_list (list): List of model specifications in various formats.
340+
341+
Returns:
342+
Union[BaseModelBackend, List[BaseModelBackend]]: Resolved model
343+
backend(s).
344+
345+
Raises:
346+
TypeError: If the list elements format is not supported.
347+
"""
348+
if not model_list: # Handle empty list
349+
logger.warning(
350+
"Empty list provided for model, using default model."
351+
)
352+
return ModelFactory.create(
353+
model_platform=ModelPlatformType.DEFAULT,
354+
model_type=ModelType.DEFAULT,
355+
)
356+
elif isinstance(model_list[0], BaseModelBackend):
357+
# List of pre-instantiated models
358+
return model_list # type: ignore[return-value]
359+
elif isinstance(model_list[0], (str, ModelType)):
360+
# List of strings or ModelTypes -> use default platform
361+
model_platform = ModelPlatformType.DEFAULT
362+
logger.warning(
363+
f"List of model types {model_list} provided without "
364+
f"platforms. Using platform '{model_platform}' for all. "
365+
"Note: platform is not automatically inferred based on "
366+
"model type."
367+
)
368+
resolved_models_list = []
369+
for model_type_item in model_list:
370+
resolved_models_list.append(
371+
ModelFactory.create(
372+
model_platform=model_platform,
373+
model_type=model_type_item, # type: ignore[arg-type]
374+
)
375+
)
376+
return resolved_models_list
377+
elif isinstance(model_list[0], tuple) and len(model_list[0]) == 2:
378+
# List of tuples (platform, type)
379+
resolved_models_list = []
380+
for model_spec in model_list:
381+
platform, type_ = model_spec[0], model_spec[1] # type: ignore[index]
382+
resolved_models_list.append(
383+
ModelFactory.create(
384+
model_platform=platform, model_type=type_
385+
)
386+
)
387+
return resolved_models_list
388+
else:
389+
raise TypeError(
390+
"Unsupported type for list elements in model: "
391+
f"{type(model_list[0])}"
392+
)
393+
250394
@property
251395
def system_message(self) -> Optional[BaseMessage]:
252396
r"""Returns the system message for the agent."""

camel/configs/__init__.py

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@
4444
from .siliconflow_config import SILICONFLOW_API_PARAMS, SiliconFlowConfig
4545
from .togetherai_config import TOGETHERAI_API_PARAMS, TogetherAIConfig
4646
from .vllm_config import VLLM_API_PARAMS, VLLMConfig
47+
from .watsonx_config import WATSONX_API_PARAMS, WatsonXConfig
4748
from .yi_config import YI_API_PARAMS, YiConfig
4849
from .zhipuai_config import ZHIPUAI_API_PARAMS, ZhipuAIConfig
4950

@@ -109,4 +110,6 @@
109110
'OPENROUTER_API_PARAMS',
110111
'LMSTUDIO_API_PARAMS',
111112
'LMStudioConfig',
113+
'WatsonXConfig',
114+
'WATSONX_API_PARAMS',
112115
]

camel/configs/qwen_config.py

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -80,12 +80,5 @@ class QwenConfig(BaseConfig):
8080
stop: Optional[Union[str, List]] = None
8181
extra_body: Optional[Dict[str, Any]] = None
8282

83-
def __init__(self, include_usage: bool = True, **kwargs):
84-
super().__init__(**kwargs)
85-
# Only set stream_options when stream is True
86-
# Otherwise, it will raise error when calling the API
87-
if self.stream:
88-
self.stream_options = {"include_usage": include_usage}
89-
9083

9184
QWEN_API_PARAMS = {param for param in QwenConfig.model_fields.keys()}

0 commit comments

Comments
 (0)