Skip to content

Commit 759e8ed

Browse files
committed
Merge branch 'master' into feat-trigger
2 parents 2b1e14a + 8d45c8a commit 759e8ed

File tree

13 files changed

+350
-599
lines changed

13 files changed

+350
-599
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.83a9
29+
placeholder: E.g., 0.2.83a7
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.83a9'
17+
__version__ = '0.2.83a7'
1818

1919
__all__ = [
2020
'__version__',

camel/environments/tic_tac_toe.py

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -413,6 +413,9 @@ def evaluate_position_for_x(
413413
Args:
414414
board (List[str]): The current game board as a list of strings.
415415
is_x_turn (bool): True if it's X's turn to move, False otherwise.
416+
depth (int): Current recursion depth. (default: :obj:`0`)
417+
max_depth (int): Maximum recursion depth to prevent stack overflow.
418+
(default: :obj:`10`)
416419
417420
Returns:
418421
float: A float value representing the position evaluation:
@@ -435,14 +438,17 @@ def evaluate_position_for_x(
435438
return 0.5 # Return draw evaluation at max depth
436439

437440
moves = TicTacToeEnv.available_moves(board)
441+
if not moves:
442+
return 0.5
443+
symbol = "X" if is_x_turn else "O"
438444
values = []
439-
# Create a copy of the board to avoid side effects
445+
440446
for move in moves:
441-
board_copy = board.copy()
442-
board_copy[move] = "X" if is_x_turn else "O"
447+
board[move] = symbol
443448
value = TicTacToeEnv.evaluate_position_for_x(
444-
board_copy, not is_x_turn, depth + 1, max_depth
449+
board, not is_x_turn, depth + 1, max_depth
445450
)
451+
board[move] = " " # undo the move
446452
values.append(value)
447453

448454
return max(values) if is_x_turn else min(values)

camel/societies/workforce/prompts.py

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -340,15 +340,12 @@
340340
341341
**DECISION GUIDELINES:**
342342
343-
**IMPORTANT: You MUST ONLY select from the ENABLED strategies listed above.**
344-
If a strategy is not in the ENABLED list, you CANNOT use it regardless of the guidelines below.
345-
346-
**Priority Rules (apply ONLY if the strategy is ENABLED):**
347-
1. Connection/Network Errors → prefer **retry** if enabled
348-
2. Deep Tasks (depth > 2) → Avoid decompose, prefer **retry** or **replan** if enabled
349-
3. Worker Skill Mismatch → prefer **reassign** (quality) or **decompose** (failure) if enabled, otherwise use **replan**
350-
4. Unclear Requirements → prefer **replan** with specifics if enabled
351-
5. Task Too Complex → prefer **decompose** into subtasks if enabled, otherwise use **replan**
343+
**Priority Rules:**
344+
1. Connection/Network Errors → **retry** (almost always)
345+
2. Deep Tasks (depth > 2) → Avoid decompose, prefer **retry** or **replan**
346+
3. Worker Skill Mismatch → **reassign** (quality) or **decompose** (failure)
347+
4. Unclear Requirements → **replan** with specifics
348+
5. Task Too Complex → **decompose** into subtasks
352349
353350
**RESPONSE FORMAT:**
354351
{response_format}
@@ -358,7 +355,7 @@
358355
- No explanations or text outside the JSON structure
359356
- Ensure all required fields are included
360357
- Use null for optional fields when not applicable
361-
- **MANDATORY: The recovery_strategy MUST be one of the ENABLED strategies listed above. Using a disabled strategy will cause an error.**
358+
- ONLY use strategies listed above as ENABLED
362359
"""
363360
)
364361

camel/societies/workforce/workforce.py

Lines changed: 6 additions & 44 deletions
Original file line numberDiff line numberDiff line change
@@ -3862,8 +3862,6 @@ async def _post_task(self, task: Task, assignee_id: str) -> None:
38623862
# Record the start time when a task is posted
38633863
self._task_start_times[task.id] = time.time()
38643864

3865-
# Ensure assignee mapping exists for retries and follow-up handling.
3866-
self._assignees[task.id] = assignee_id
38673865
task.assigned_worker_id = assignee_id
38683866

38693867
task_started_event = TaskStartedEvent(
@@ -4544,29 +4542,15 @@ async def _handle_failed_task(self, task: Task) -> bool:
45444542
task, for_failure=True, error_message=detailed_error
45454543
)
45464544

4547-
# Validate and fallback recovery strategy based on enabled_strategies
4548-
config_strategies = self.failure_handling_config.enabled_strategies
4545+
# Fallback to first enabled strategy if no strategy recommended
45494546
if recovery_decision.recovery_strategy is None:
4550-
# No strategy recommended - use fallback
4547+
config_strategies = self.failure_handling_config.enabled_strategies
45514548
# config_strategies is None means all enabled, use RETRY as default
45524549
# otherwise use the first enabled strategy from user's config
45534550
if config_strategies is None:
45544551
recovery_decision.recovery_strategy = RecoveryStrategy.RETRY
45554552
else:
45564553
recovery_decision.recovery_strategy = config_strategies[0]
4557-
elif config_strategies is not None:
4558-
# Strategy recommended - validate it's in enabled list
4559-
if recovery_decision.recovery_strategy not in config_strategies:
4560-
# LLM recommended a disabled strategy, use first enabled
4561-
recommended = recovery_decision.recovery_strategy.value
4562-
enabled_list = [s.value for s in config_strategies]
4563-
fallback = config_strategies[0].value
4564-
logger.warning(
4565-
f"Task {task.id}: LLM recommended '{recommended}' "
4566-
f"but it's not in enabled_strategies {enabled_list}. "
4567-
f"Using '{fallback}' instead."
4568-
)
4569-
recovery_decision.recovery_strategy = config_strategies[0]
45704554

45714555
strategy_str = recovery_decision.recovery_strategy.value
45724556
logger.info(
@@ -5324,12 +5308,11 @@ async def _listen_to_channel(self) -> None:
53245308
f"Issues: {', '.join(quality_eval.issues)}"
53255309
)
53265310

5327-
# Validate and fallback recovery strategy based on
5328-
# enabled_strategies
5329-
config = self.failure_handling_config
5330-
config_strategies = config.enabled_strategies
5311+
# Fallback to first enabled strategy if none
5312+
# recommended
53315313
if quality_eval.recovery_strategy is None:
5332-
# No strategy recommended - use fallback
5314+
config = self.failure_handling_config
5315+
config_strategies = config.enabled_strategies
53335316
if config_strategies is None:
53345317
quality_eval.recovery_strategy = (
53355318
RecoveryStrategy.RETRY
@@ -5338,27 +5321,6 @@ async def _listen_to_channel(self) -> None:
53385321
quality_eval.recovery_strategy = (
53395322
config_strategies[0]
53405323
)
5341-
elif config_strategies is not None:
5342-
# Strategy recommended - validate it's enabled
5343-
if (
5344-
quality_eval.recovery_strategy
5345-
not in config_strategies
5346-
):
5347-
# LLM recommended a disabled strategy
5348-
rec = quality_eval.recovery_strategy.value
5349-
enabled = [
5350-
s.value for s in config_strategies
5351-
]
5352-
fallback = config_strategies[0].value
5353-
logger.warning(
5354-
f"Task {returned_task.id}: LLM "
5355-
f"recommended '{rec}' but it's not in "
5356-
f"enabled_strategies {enabled}. "
5357-
f"Using '{fallback}' instead."
5358-
)
5359-
quality_eval.recovery_strategy = (
5360-
config_strategies[0]
5361-
)
53625324

53635325
# Preserve assignee before cleanup - in normal
53645326
# flow, a task must be assigned before it can fail

camel/toolkits/lark_toolkit.py

Lines changed: 0 additions & 67 deletions
Original file line numberDiff line numberDiff line change
@@ -356,72 +356,6 @@ def lark_get_chat_messages(
356356
logger.error(f"Error getting chat messages: {e}")
357357
return {"error": f"Error getting chat messages: {e!s}"}
358358

359-
def lark_send_message(
360-
self,
361-
receive_id: str,
362-
text: str,
363-
receive_id_type: Literal[
364-
"open_id", "user_id", "union_id", "email", "chat_id"
365-
] = "chat_id",
366-
) -> Dict[str, object]:
367-
r"""Sends a message to a user or chat. If send message to
368-
a chat, use lark_list_chats to get chat_id first, if send
369-
message to a user, need user provide open_id, user_id,
370-
union_id or email.
371-
372-
Args:
373-
receive_id (str): The recipient identifier.
374-
text (str): The text message content.
375-
receive_id_type (str): The recipient ID type. Options:
376-
- "open_id"
377-
- "user_id"
378-
- "union_id"
379-
- "email"
380-
- "chat_id" (default)
381-
382-
Returns:
383-
Dict[str, object]: A dictionary containing:
384-
- message_id: The sent message ID
385-
- chat_id: The chat ID the message belongs to
386-
- msg_type: Message type (text)
387-
"""
388-
# NOTE: Currently supports plain text messages only.
389-
try:
390-
url = f"{self._domain}/open-apis/im/v1/messages"
391-
headers = self._get_tenant_http_headers()
392-
params = {"receive_id_type": receive_id_type}
393-
payload = {
394-
"receive_id": receive_id,
395-
"msg_type": "text",
396-
"content": json.dumps({"text": text}),
397-
}
398-
399-
response = requests.post(
400-
url, headers=headers, params=params, json=payload, timeout=30
401-
)
402-
result = response.json()
403-
404-
if result.get("code") != 0:
405-
logger.error(
406-
f"Failed to send message: {result.get('code')} - "
407-
f"{result.get('msg')}"
408-
)
409-
return {
410-
"error": f"Failed to send message: {result.get('msg')}",
411-
"code": result.get("code"),
412-
}
413-
414-
data = result.get("data", {}) or {}
415-
return {
416-
"message_id": data.get("message_id"),
417-
"chat_id": data.get("chat_id"),
418-
"msg_type": data.get("msg_type"),
419-
}
420-
421-
except Exception as e:
422-
logger.error(f"Error sending message: {e}")
423-
return {"error": f"Error sending message: {e!s}"}
424-
425359
def lark_get_message_resource(
426360
self,
427361
message_id: str,
@@ -573,7 +507,6 @@ def get_tools(self) -> List[FunctionTool]:
573507
return [
574508
FunctionTool(self.lark_list_chats),
575509
FunctionTool(self.lark_get_chat_messages),
576-
FunctionTool(self.lark_send_message),
577510
FunctionTool(self.lark_get_message_resource),
578511
FunctionTool(self.lark_get_message_resource_key),
579512
]

docs/conf.py

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@
2727
project = 'CAMEL'
2828
copyright = '2024, CAMEL-AI.org'
2929
author = 'CAMEL-AI.org'
30-
release = '0.2.83a9'
30+
release = '0.2.83a7'
3131

3232
html_favicon = (
3333
'https://raw.githubusercontent.com/camel-ai/camel/master/misc/favicon.png'

docs/mintlify/reference/camel.toolkits.lark_toolkit.mdx

Lines changed: 0 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -157,37 +157,6 @@ member of the chat.
157157
- has_more: Whether there are more messages to fetch
158158
- page_token: Token to fetch the next page
159159

160-
<a id="camel.toolkits.lark_toolkit.LarkToolkit.lark_send_message"></a>
161-
162-
### lark_send_message
163-
164-
```python
165-
def lark_send_message(
166-
self,
167-
receive_id: str,
168-
text: str,
169-
receive_id_type: Literal['open_id', 'user_id', 'union_id', 'email', 'chat_id'] = 'chat_id'
170-
):
171-
```
172-
173-
Sends a message to a user or chat. If send message to
174-
a chat, use lark_list_chats to get chat_id first, if send
175-
message to a user, need user provide open_id, user_id,
176-
union_id or email.
177-
178-
**Parameters:**
179-
180-
- **receive_id** (str): The recipient identifier.
181-
- **text** (str): The text message content.
182-
- **receive_id_type** (str): The recipient ID type. Options: - "open_id" - "user_id" - "union_id" - "email" - "chat_id" (default)
183-
184-
**Returns:**
185-
186-
Dict[str, object]: A dictionary containing:
187-
- message_id: The sent message ID
188-
- chat_id: The chat ID the message belongs to
189-
- msg_type: Message type (text)
190-
191160
<a id="camel.toolkits.lark_toolkit.LarkToolkit.lark_get_message_resource"></a>
192161

193162
### lark_get_message_resource

examples/toolkits/lark_toolkit_example.py

Lines changed: 2 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -64,17 +64,9 @@
6464
)
6565
print(f"Response: {response.msgs[0].content}\n")
6666

67-
# Example 4: Send a message to chat
67+
# Example 4: Direct toolkit usage (without agent)
6868
print("=" * 60)
69-
print("Example 4: Send a message to chat")
70-
print("=" * 60)
71-
72-
response = agent.step("Say hi to my first chat ")
73-
print(f"Response: {response.msgs[0].content}\n")
74-
75-
# Example 5: Direct toolkit usage (without agent)
76-
print("=" * 60)
77-
print("Example 5: Direct toolkit usage")
69+
print("Example 4: Direct toolkit usage")
7870
print("=" * 60)
7971

8072
# List chats directly

misc/wechat.jpeg

-24.1 KB
Loading

0 commit comments

Comments
 (0)