Skip to content

Commit 2b4e1b2

Browse files
authored
Merge branch 'master' into change-workflow-folder-structure
2 parents 6958b5a + e6f6105 commit 2b4e1b2

Some content is hidden

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

55 files changed

+4502
-1732
lines changed

.github/ISSUE_TEMPLATE/bug_report.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ body:
2626
attributes:
2727
label: What version of camel are you using?
2828
description: Run command `python3 -c 'print(__import__("camel").__version__)'` in your shell and paste the output here.
29-
placeholder: E.g., 0.2.79
29+
placeholder: E.g., 0.2.80a3
3030
validations:
3131
required: true
3232

camel/__init__.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@
1414

1515
from camel.logger import disable_logging, enable_logging, set_log_level
1616

17-
__version__ = '0.2.79'
17+
__version__ = '0.2.80a3'
1818

1919
__all__ = [
2020
'__version__',

camel/agents/_types.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@ class ToolCallRequest(BaseModel):
2727
tool_name: str
2828
args: Dict[str, Any]
2929
tool_call_id: str
30+
extra_content: Optional[Dict[str, Any]] = None
3031

3132

3233
class ModelResponse(BaseModel):

camel/agents/chat_agent.py

Lines changed: 243 additions & 76 deletions
Large diffs are not rendered by default.

camel/configs/deepseek_config.py

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -96,13 +96,12 @@ class DeepSeekConfig(BaseConfig):
9696
tool_choice: Optional[Union[dict[str, str], str]] = None
9797
logprobs: Optional[bool] = None
9898
top_logprobs: Optional[int] = None
99+
stream_options: Optional[dict[str, bool]] = None
99100

100101
def __init__(self, include_usage: bool = True, **kwargs):
102+
if kwargs.get("stream") and "stream_options" not in kwargs:
103+
kwargs["stream_options"] = {"include_usage": include_usage}
101104
super().__init__(**kwargs)
102-
# Only set stream_options when stream is True
103-
# Otherwise, it will raise error when calling the API
104-
if self.stream:
105-
self.stream_options = {"include_usage": include_usage}
106105

107106

108107
DEEPSEEK_API_PARAMS = {param for param in DeepSeekConfig.model_fields.keys()}

camel/messages/base.py

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -71,8 +71,10 @@ class BaseMessage:
7171
images associated with the message. (default: :obj:`auto`)
7272
video_detail (Literal["auto", "low", "high"]): Detail level of the
7373
videos associated with the message. (default: :obj:`auto`)
74-
parsed: Optional[Union[Type[BaseModel], dict]]: Optional object which
74+
parsed (Optional[Union[Type[BaseModel], dict]]): Optional object which
7575
is parsed from the content. (default: :obj:`None`)
76+
reasoning_content (Optional[str]): Optional reasoning trace associated
77+
with the message. (default: :obj:`None`)
7678
"""
7779

7880
role_name: str
@@ -85,6 +87,7 @@ class BaseMessage:
8587
image_detail: Literal["auto", "low", "high"] = "auto"
8688
video_detail: Literal["auto", "low", "high"] = "auto"
8789
parsed: Optional[Union[BaseModel, dict]] = None
90+
reasoning_content: Optional[str] = None
8891

8992
@classmethod
9093
def make_user_message(
@@ -219,6 +222,12 @@ def create_new_instance(self, content: str) -> "BaseMessage":
219222
role_type=self.role_type,
220223
meta_dict=self.meta_dict,
221224
content=content,
225+
video_bytes=self.video_bytes,
226+
image_list=self.image_list,
227+
image_detail=self.image_detail,
228+
video_detail=self.video_detail,
229+
parsed=self.parsed,
230+
reasoning_content=self.reasoning_content,
222231
)
223232

224233
def __add__(self, other: Any) -> Union["BaseMessage", Any]:

camel/messages/func_message.py

Lines changed: 20 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -50,13 +50,17 @@ class FunctionCallingMessage(BaseMessage):
5050
mask_output (Optional[bool]): Whether to return a sanitized placeholder
5151
instead of the raw tool output.
5252
(default: :obj:`False`)
53+
extra_content (Optional[Dict[str, Any]]): Additional content
54+
associated with the tool call.
55+
(default: :obj:`None`)
5356
"""
5457

5558
func_name: Optional[str] = None
5659
args: Optional[Dict] = None
5760
result: Optional[Any] = None
5861
tool_call_id: Optional[str] = None
5962
mask_output: Optional[bool] = False
63+
extra_content: Optional[Dict[str, Any]] = None
6064

6165
def to_openai_message(
6266
self,
@@ -131,19 +135,23 @@ def to_openai_assistant_message(self) -> OpenAIAssistantMessage:
131135
" due to missing function name or arguments."
132136
)
133137

138+
tool_call = {
139+
"id": self.tool_call_id or "null",
140+
"type": "function",
141+
"function": {
142+
"name": self.func_name,
143+
"arguments": json.dumps(self.args, ensure_ascii=False),
144+
},
145+
}
146+
147+
# Include extra_content if available
148+
if self.extra_content is not None:
149+
tool_call["extra_content"] = self.extra_content
150+
134151
return {
135152
"role": "assistant",
136153
"content": self.content or "",
137-
"tool_calls": [
138-
{
139-
"id": self.tool_call_id or "null",
140-
"type": "function",
141-
"function": {
142-
"name": self.func_name,
143-
"arguments": json.dumps(self.args, ensure_ascii=False),
144-
},
145-
}
146-
],
154+
"tool_calls": [tool_call], # type: ignore[list-item]
147155
}
148156

149157
def to_openai_tool_message(self) -> OpenAIToolMessageParam:
@@ -187,4 +195,6 @@ def to_dict(self) -> Dict:
187195
if self.tool_call_id is not None:
188196
base["tool_call_id"] = self.tool_call_id
189197
base["mask_output"] = self.mask_output
198+
if self.extra_content is not None:
199+
base["extra_content"] = self.extra_content
190200
return base

camel/models/base_audio_model.py

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@
1616
from abc import ABC, abstractmethod
1717
from typing import Any, Optional
1818

19+
from camel.utils import Constants
20+
1921

2022
class BaseAudioModel(ABC):
2123
r"""Base class for audio models providing Text-to-Speech (TTS) and
@@ -26,7 +28,7 @@ def __init__(
2628
self,
2729
api_key: Optional[str] = None,
2830
url: Optional[str] = None,
29-
timeout: Optional[float] = None,
31+
timeout: Optional[float] = Constants.TIMEOUT_THRESHOLD,
3032
) -> None:
3133
r"""Initialize an instance of BaseAudioModel.
3234

camel/models/base_model.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
ParsedChatCompletion,
3434
UnifiedModelType,
3535
)
36-
from camel.utils import BaseTokenCounter
36+
from camel.utils import BaseTokenCounter, Constants
3737

3838
if os.environ.get("TRACEROOT_ENABLED", "False").lower() == "true":
3939
try:
@@ -103,7 +103,7 @@ def __init__(
103103
api_key: Optional[str] = None,
104104
url: Optional[str] = None,
105105
token_counter: Optional[BaseTokenCounter] = None,
106-
timeout: Optional[float] = None,
106+
timeout: Optional[float] = Constants.TIMEOUT_THRESHOLD,
107107
max_retries: int = 3,
108108
) -> None:
109109
self.model_type: UnifiedModelType = UnifiedModelType(model_type)

camel/models/deepseek_model.py

Lines changed: 2 additions & 40 deletions
Original file line numberDiff line numberDiff line change
@@ -165,44 +165,6 @@ def _prepare_request(
165165

166166
return request_config
167167

168-
def _post_handle_response(
169-
self, response: ChatCompletion
170-
) -> ChatCompletion:
171-
r"""Handle reasoning content with <think> tags at the beginning."""
172-
if (
173-
self.model_type in [ModelType.DEEPSEEK_REASONER]
174-
and os.environ.get("GET_REASONING_CONTENT", "false").lower()
175-
== "true"
176-
):
177-
reasoning_content = response.choices[0].message.reasoning_content # type: ignore[attr-defined]
178-
combined_content = ( # type: ignore[operator]
179-
f"<think>\n{reasoning_content}\n</think>\n"
180-
if reasoning_content
181-
else ""
182-
) + response.choices[0].message.content
183-
184-
response = ChatCompletion.construct(
185-
id=response.id,
186-
choices=[
187-
dict(
188-
index=response.choices[0].index,
189-
message={
190-
"role": response.choices[0].message.role,
191-
"content": combined_content,
192-
"tool_calls": None,
193-
},
194-
finish_reason=response.choices[0].finish_reason
195-
if response.choices[0].finish_reason
196-
else None,
197-
)
198-
],
199-
created=response.created,
200-
model=response.model,
201-
object="chat.completion",
202-
usage=response.usage,
203-
)
204-
return response
205-
206168
@observe()
207169
def _run(
208170
self,
@@ -244,7 +206,7 @@ def _run(
244206
**request_config,
245207
)
246208

247-
return self._post_handle_response(response)
209+
return response
248210

249211
@observe()
250212
async def _arun(
@@ -286,4 +248,4 @@ async def _arun(
286248
**request_config,
287249
)
288250

289-
return self._post_handle_response(response)
251+
return response

0 commit comments

Comments
 (0)