camel-ai 0.2.77__py3-none-any.whl → 0.2.78__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.
Potentially problematic release.
This version of camel-ai might be problematic. Click here for more details.
- camel/__init__.py +1 -1
- camel/agents/chat_agent.py +17 -313
- camel/toolkits/excel_toolkit.py +1 -1
- camel/toolkits/file_toolkit.py +3 -2
- {camel_ai-0.2.77.dist-info → camel_ai-0.2.78.dist-info}/METADATA +10 -1
- {camel_ai-0.2.77.dist-info → camel_ai-0.2.78.dist-info}/RECORD +8 -8
- {camel_ai-0.2.77.dist-info → camel_ai-0.2.78.dist-info}/WHEEL +0 -0
- {camel_ai-0.2.77.dist-info → camel_ai-0.2.78.dist-info}/licenses/LICENSE +0 -0
camel/__init__.py
CHANGED
camel/agents/chat_agent.py
CHANGED
|
@@ -30,7 +30,6 @@ import threading
|
|
|
30
30
|
import time
|
|
31
31
|
import uuid
|
|
32
32
|
import warnings
|
|
33
|
-
from dataclasses import dataclass
|
|
34
33
|
from datetime import datetime
|
|
35
34
|
from pathlib import Path
|
|
36
35
|
from typing import (
|
|
@@ -160,53 +159,6 @@ SIMPLE_FORMAT_PROMPT = TextPrompt(
|
|
|
160
159
|
)
|
|
161
160
|
|
|
162
161
|
|
|
163
|
-
@dataclass
|
|
164
|
-
class _ToolOutputHistoryEntry:
|
|
165
|
-
tool_name: str
|
|
166
|
-
tool_call_id: str
|
|
167
|
-
result_text: str
|
|
168
|
-
record_uuids: List[str]
|
|
169
|
-
record_timestamps: List[float]
|
|
170
|
-
preview_text: str
|
|
171
|
-
cached: bool = False
|
|
172
|
-
cache_id: Optional[str] = None
|
|
173
|
-
|
|
174
|
-
|
|
175
|
-
class _ToolOutputCacheManager:
|
|
176
|
-
r"""Minimal persistent store for caching verbose tool outputs."""
|
|
177
|
-
|
|
178
|
-
def __init__(self, base_dir: Union[str, Path]) -> None:
|
|
179
|
-
self.base_dir = Path(base_dir).expanduser().resolve()
|
|
180
|
-
self.base_dir.mkdir(parents=True, exist_ok=True)
|
|
181
|
-
|
|
182
|
-
def save(
|
|
183
|
-
self,
|
|
184
|
-
tool_name: str,
|
|
185
|
-
tool_call_id: str,
|
|
186
|
-
content: str,
|
|
187
|
-
) -> Tuple[str, Path]:
|
|
188
|
-
cache_id = uuid.uuid4().hex
|
|
189
|
-
filename = f"{cache_id}.txt"
|
|
190
|
-
path = self.base_dir / filename
|
|
191
|
-
header = (
|
|
192
|
-
f"# Cached tool output\n"
|
|
193
|
-
f"tool_name: {tool_name}\n"
|
|
194
|
-
f"tool_call_id: {tool_call_id}\n"
|
|
195
|
-
f"cache_id: {cache_id}\n"
|
|
196
|
-
f"---\n"
|
|
197
|
-
)
|
|
198
|
-
path.write_text(f"{header}{content}", encoding="utf-8")
|
|
199
|
-
return cache_id, path
|
|
200
|
-
|
|
201
|
-
def load(self, cache_id: str) -> str:
|
|
202
|
-
path = self.base_dir / f"{cache_id}.txt"
|
|
203
|
-
if not path.exists():
|
|
204
|
-
raise FileNotFoundError(
|
|
205
|
-
f"Cached tool output {cache_id} not found at {path}"
|
|
206
|
-
)
|
|
207
|
-
return path.read_text(encoding="utf-8")
|
|
208
|
-
|
|
209
|
-
|
|
210
162
|
class StreamContentAccumulator:
|
|
211
163
|
r"""Manages content accumulation across streaming responses to ensure
|
|
212
164
|
all responses contain complete cumulative content."""
|
|
@@ -452,19 +404,6 @@ class ChatAgent(BaseAgent):
|
|
|
452
404
|
usage. When enabled, removes FUNCTION/TOOL role messages and
|
|
453
405
|
ASSISTANT messages with tool_calls after each step.
|
|
454
406
|
(default: :obj:`False`)
|
|
455
|
-
enable_tool_output_cache (bool, optional): Whether to offload verbose
|
|
456
|
-
historical tool outputs to a local cache and replace them with
|
|
457
|
-
lightweight references in memory. Only older tool results whose
|
|
458
|
-
payload length exceeds ``tool_output_cache_threshold`` are cached.
|
|
459
|
-
(default: :obj:`False`)
|
|
460
|
-
tool_output_cache_threshold (int, optional): Minimum character length
|
|
461
|
-
of a tool result before it becomes eligible for caching. Values
|
|
462
|
-
below or equal to zero disable caching regardless of the toggle.
|
|
463
|
-
(default: :obj:`2000`)
|
|
464
|
-
tool_output_cache_dir (Optional[Union[str, Path]], optional): Target
|
|
465
|
-
directory for cached tool outputs. When omitted, a ``tool_cache``
|
|
466
|
-
directory relative to the current working directory is used.
|
|
467
|
-
(default: :obj:`None`)
|
|
468
407
|
retry_attempts (int, optional): Maximum number of retry attempts for
|
|
469
408
|
rate limit errors. (default: :obj:`3`)
|
|
470
409
|
retry_delay (float, optional): Initial delay in seconds between
|
|
@@ -516,9 +455,6 @@ class ChatAgent(BaseAgent):
|
|
|
516
455
|
mask_tool_output: bool = False,
|
|
517
456
|
pause_event: Optional[Union[threading.Event, asyncio.Event]] = None,
|
|
518
457
|
prune_tool_calls_from_memory: bool = False,
|
|
519
|
-
enable_tool_output_cache: bool = False,
|
|
520
|
-
tool_output_cache_threshold: int = 2000,
|
|
521
|
-
tool_output_cache_dir: Optional[Union[str, Path]] = None,
|
|
522
458
|
retry_attempts: int = 3,
|
|
523
459
|
retry_delay: float = 1.0,
|
|
524
460
|
step_timeout: Optional[float] = None,
|
|
@@ -538,28 +474,6 @@ class ChatAgent(BaseAgent):
|
|
|
538
474
|
# Assign unique ID
|
|
539
475
|
self.agent_id = agent_id if agent_id else str(uuid.uuid4())
|
|
540
476
|
|
|
541
|
-
self._tool_output_cache_enabled = (
|
|
542
|
-
enable_tool_output_cache and tool_output_cache_threshold > 0
|
|
543
|
-
)
|
|
544
|
-
self._tool_output_cache_threshold = max(0, tool_output_cache_threshold)
|
|
545
|
-
self._tool_output_cache_dir: Optional[Path]
|
|
546
|
-
self._tool_output_cache_manager: Optional[_ToolOutputCacheManager]
|
|
547
|
-
if self._tool_output_cache_enabled:
|
|
548
|
-
cache_dir = (
|
|
549
|
-
Path(tool_output_cache_dir).expanduser()
|
|
550
|
-
if tool_output_cache_dir is not None
|
|
551
|
-
else Path("tool_cache")
|
|
552
|
-
)
|
|
553
|
-
self._tool_output_cache_dir = cache_dir
|
|
554
|
-
self._tool_output_cache_manager = _ToolOutputCacheManager(
|
|
555
|
-
cache_dir
|
|
556
|
-
)
|
|
557
|
-
else:
|
|
558
|
-
self._tool_output_cache_dir = None
|
|
559
|
-
self._tool_output_cache_manager = None
|
|
560
|
-
self._tool_output_history: List[_ToolOutputHistoryEntry] = []
|
|
561
|
-
self._cache_lookup_tool_name = "retrieve_cached_tool_output"
|
|
562
|
-
|
|
563
477
|
# Set up memory
|
|
564
478
|
context_creator = ScoreBasedContextCreator(
|
|
565
479
|
self.model_backend.token_counter,
|
|
@@ -606,8 +520,6 @@ class ChatAgent(BaseAgent):
|
|
|
606
520
|
convert_to_function_tool(tool) for tool in (tools or [])
|
|
607
521
|
]
|
|
608
522
|
}
|
|
609
|
-
if self._tool_output_cache_enabled:
|
|
610
|
-
self._ensure_tool_cache_lookup_tool()
|
|
611
523
|
|
|
612
524
|
# Register agent with toolkits that have RegisteredAgentToolkit mixin
|
|
613
525
|
if toolkits_to_register_agent:
|
|
@@ -644,8 +556,6 @@ class ChatAgent(BaseAgent):
|
|
|
644
556
|
r"""Resets the :obj:`ChatAgent` to its initial state."""
|
|
645
557
|
self.terminated = False
|
|
646
558
|
self.init_messages()
|
|
647
|
-
if self._tool_output_cache_enabled:
|
|
648
|
-
self._tool_output_history.clear()
|
|
649
559
|
for terminator in self.response_terminators:
|
|
650
560
|
terminator.reset()
|
|
651
561
|
|
|
@@ -866,178 +776,6 @@ class ChatAgent(BaseAgent):
|
|
|
866
776
|
for tool in tools:
|
|
867
777
|
self.add_tool(tool)
|
|
868
778
|
|
|
869
|
-
def retrieve_cached_tool_output(self, cache_id: str) -> str:
|
|
870
|
-
r"""Load a cached tool output by its cache identifier.
|
|
871
|
-
|
|
872
|
-
Args:
|
|
873
|
-
cache_id (str): Identifier provided in cached tool messages.
|
|
874
|
-
|
|
875
|
-
Returns:
|
|
876
|
-
str: The cached content or an explanatory error message.
|
|
877
|
-
"""
|
|
878
|
-
if not self._tool_output_cache_manager:
|
|
879
|
-
return "Tool output caching is disabled for this agent instance."
|
|
880
|
-
|
|
881
|
-
normalized_cache_id = cache_id.strip()
|
|
882
|
-
if not normalized_cache_id:
|
|
883
|
-
return "Please provide a non-empty cache_id."
|
|
884
|
-
|
|
885
|
-
try:
|
|
886
|
-
return self._tool_output_cache_manager.load(normalized_cache_id)
|
|
887
|
-
except FileNotFoundError:
|
|
888
|
-
return (
|
|
889
|
-
f"Cache entry '{normalized_cache_id}' was not found. "
|
|
890
|
-
"Verify the identifier and try again."
|
|
891
|
-
)
|
|
892
|
-
|
|
893
|
-
def _ensure_tool_cache_lookup_tool(self) -> None:
|
|
894
|
-
if not self._tool_output_cache_enabled:
|
|
895
|
-
return
|
|
896
|
-
lookup_name = self._cache_lookup_tool_name
|
|
897
|
-
if lookup_name in self._internal_tools:
|
|
898
|
-
return
|
|
899
|
-
lookup_tool = convert_to_function_tool(
|
|
900
|
-
self.retrieve_cached_tool_output
|
|
901
|
-
)
|
|
902
|
-
self._internal_tools[lookup_tool.get_function_name()] = lookup_tool
|
|
903
|
-
|
|
904
|
-
def _serialize_tool_result(self, result: Any) -> str:
|
|
905
|
-
if isinstance(result, str):
|
|
906
|
-
return result
|
|
907
|
-
try:
|
|
908
|
-
return json.dumps(result, ensure_ascii=False)
|
|
909
|
-
except (TypeError, ValueError):
|
|
910
|
-
return str(result)
|
|
911
|
-
|
|
912
|
-
def _summarize_tool_result(self, text: str, limit: int = 160) -> str:
|
|
913
|
-
normalized = re.sub(r"\s+", " ", text).strip()
|
|
914
|
-
if len(normalized) <= limit:
|
|
915
|
-
return normalized
|
|
916
|
-
return normalized[: max(0, limit - 3)].rstrip() + "..."
|
|
917
|
-
|
|
918
|
-
def _register_tool_output_for_cache(
|
|
919
|
-
self,
|
|
920
|
-
func_name: str,
|
|
921
|
-
tool_call_id: str,
|
|
922
|
-
result_text: str,
|
|
923
|
-
records: List[MemoryRecord],
|
|
924
|
-
) -> None:
|
|
925
|
-
if not records:
|
|
926
|
-
return
|
|
927
|
-
|
|
928
|
-
entry = _ToolOutputHistoryEntry(
|
|
929
|
-
tool_name=func_name,
|
|
930
|
-
tool_call_id=tool_call_id,
|
|
931
|
-
result_text=result_text,
|
|
932
|
-
record_uuids=[str(record.uuid) for record in records],
|
|
933
|
-
record_timestamps=[record.timestamp for record in records],
|
|
934
|
-
preview_text=self._summarize_tool_result(result_text),
|
|
935
|
-
)
|
|
936
|
-
self._tool_output_history.append(entry)
|
|
937
|
-
self._process_tool_output_cache()
|
|
938
|
-
|
|
939
|
-
def _process_tool_output_cache(self) -> None:
|
|
940
|
-
if (
|
|
941
|
-
not self._tool_output_cache_enabled
|
|
942
|
-
or not self._tool_output_history
|
|
943
|
-
or self._tool_output_cache_manager is None
|
|
944
|
-
):
|
|
945
|
-
return
|
|
946
|
-
|
|
947
|
-
# Only cache older results; keep the latest expanded for immediate use.
|
|
948
|
-
for entry in self._tool_output_history[:-1]:
|
|
949
|
-
if entry.cached:
|
|
950
|
-
continue
|
|
951
|
-
if len(entry.result_text) < self._tool_output_cache_threshold:
|
|
952
|
-
continue
|
|
953
|
-
self._cache_tool_output_entry(entry)
|
|
954
|
-
|
|
955
|
-
def _cache_tool_output_entry(self, entry: _ToolOutputHistoryEntry) -> None:
|
|
956
|
-
if self._tool_output_cache_manager is None or not entry.record_uuids:
|
|
957
|
-
return
|
|
958
|
-
|
|
959
|
-
try:
|
|
960
|
-
cache_id, cache_path = self._tool_output_cache_manager.save(
|
|
961
|
-
entry.tool_name,
|
|
962
|
-
entry.tool_call_id,
|
|
963
|
-
entry.result_text,
|
|
964
|
-
)
|
|
965
|
-
except Exception as exc: # pragma: no cover - defensive
|
|
966
|
-
logger.warning(
|
|
967
|
-
"Failed to persist cached tool output for %s (%s): %s",
|
|
968
|
-
entry.tool_name,
|
|
969
|
-
entry.tool_call_id,
|
|
970
|
-
exc,
|
|
971
|
-
)
|
|
972
|
-
return
|
|
973
|
-
|
|
974
|
-
timestamp = (
|
|
975
|
-
entry.record_timestamps[0]
|
|
976
|
-
if entry.record_timestamps
|
|
977
|
-
else time.time_ns() / 1_000_000_000
|
|
978
|
-
)
|
|
979
|
-
reference_message = FunctionCallingMessage(
|
|
980
|
-
role_name=self.role_name,
|
|
981
|
-
role_type=self.role_type,
|
|
982
|
-
meta_dict={
|
|
983
|
-
"cache_id": cache_id,
|
|
984
|
-
"cached_preview": entry.preview_text,
|
|
985
|
-
"cached_tool_output_path": str(cache_path),
|
|
986
|
-
},
|
|
987
|
-
content="",
|
|
988
|
-
func_name=entry.tool_name,
|
|
989
|
-
result=self._build_cache_reference_text(entry, cache_id),
|
|
990
|
-
tool_call_id=entry.tool_call_id,
|
|
991
|
-
)
|
|
992
|
-
|
|
993
|
-
chat_history_block = getattr(self.memory, "_chat_history_block", None)
|
|
994
|
-
storage = getattr(chat_history_block, "storage", None)
|
|
995
|
-
if storage is None:
|
|
996
|
-
return
|
|
997
|
-
|
|
998
|
-
existing_records = storage.load()
|
|
999
|
-
updated_records = [
|
|
1000
|
-
record
|
|
1001
|
-
for record in existing_records
|
|
1002
|
-
if record["uuid"] not in entry.record_uuids
|
|
1003
|
-
]
|
|
1004
|
-
new_record = MemoryRecord(
|
|
1005
|
-
message=reference_message,
|
|
1006
|
-
role_at_backend=OpenAIBackendRole.FUNCTION,
|
|
1007
|
-
timestamp=timestamp,
|
|
1008
|
-
agent_id=self.agent_id,
|
|
1009
|
-
)
|
|
1010
|
-
updated_records.append(new_record.to_dict())
|
|
1011
|
-
updated_records.sort(key=lambda record: record["timestamp"])
|
|
1012
|
-
storage.clear()
|
|
1013
|
-
storage.save(updated_records)
|
|
1014
|
-
|
|
1015
|
-
logger.info(
|
|
1016
|
-
"Cached tool output '%s' (%s) to %s with cache_id=%s",
|
|
1017
|
-
entry.tool_name,
|
|
1018
|
-
entry.tool_call_id,
|
|
1019
|
-
cache_path,
|
|
1020
|
-
cache_id,
|
|
1021
|
-
)
|
|
1022
|
-
|
|
1023
|
-
entry.cached = True
|
|
1024
|
-
entry.cache_id = cache_id
|
|
1025
|
-
entry.record_uuids = [str(new_record.uuid)]
|
|
1026
|
-
entry.record_timestamps = [timestamp]
|
|
1027
|
-
|
|
1028
|
-
def _build_cache_reference_text(
|
|
1029
|
-
self, entry: _ToolOutputHistoryEntry, cache_id: str
|
|
1030
|
-
) -> str:
|
|
1031
|
-
preview = entry.preview_text or "[no preview available]"
|
|
1032
|
-
return (
|
|
1033
|
-
"[cached tool output]\n"
|
|
1034
|
-
f"tool: {entry.tool_name}\n"
|
|
1035
|
-
f"cache_id: {cache_id}\n"
|
|
1036
|
-
f"preview: {preview}\n"
|
|
1037
|
-
f"Use `{self._cache_lookup_tool_name}` with this cache_id to "
|
|
1038
|
-
"retrieve the full content."
|
|
1039
|
-
)
|
|
1040
|
-
|
|
1041
779
|
def add_external_tool(
|
|
1042
780
|
self, tool: Union[FunctionTool, Callable, Dict[str, Any]]
|
|
1043
781
|
) -> None:
|
|
@@ -1082,8 +820,7 @@ class ChatAgent(BaseAgent):
|
|
|
1082
820
|
message: BaseMessage,
|
|
1083
821
|
role: OpenAIBackendRole,
|
|
1084
822
|
timestamp: Optional[float] = None,
|
|
1085
|
-
|
|
1086
|
-
) -> Optional[List[MemoryRecord]]:
|
|
823
|
+
) -> None:
|
|
1087
824
|
r"""Updates the agent memory with a new message.
|
|
1088
825
|
|
|
1089
826
|
If the single *message* exceeds the model's context window, it will
|
|
@@ -1103,29 +840,21 @@ class ChatAgent(BaseAgent):
|
|
|
1103
840
|
timestamp (Optional[float], optional): Custom timestamp for the
|
|
1104
841
|
memory record. If `None`, the current time will be used.
|
|
1105
842
|
(default: :obj:`None`)
|
|
1106
|
-
|
|
1107
|
-
the list of :class:`MemoryRecord` objects written to memory.
|
|
1108
|
-
(default: :obj:`False`)
|
|
1109
|
-
|
|
1110
|
-
Returns:
|
|
1111
|
-
Optional[List[MemoryRecord]]: The records that were written when
|
|
1112
|
-
``return_records`` is ``True``; otherwise ``None``.
|
|
843
|
+
(default: obj:`None`)
|
|
1113
844
|
"""
|
|
1114
845
|
|
|
1115
|
-
written_records: List[MemoryRecord] = []
|
|
1116
|
-
|
|
1117
846
|
# 1. Helper to write a record to memory
|
|
1118
847
|
def _write_single_record(
|
|
1119
848
|
message: BaseMessage, role: OpenAIBackendRole, timestamp: float
|
|
1120
849
|
):
|
|
1121
|
-
|
|
1122
|
-
|
|
1123
|
-
|
|
1124
|
-
|
|
1125
|
-
|
|
850
|
+
self.memory.write_record(
|
|
851
|
+
MemoryRecord(
|
|
852
|
+
message=message,
|
|
853
|
+
role_at_backend=role,
|
|
854
|
+
timestamp=timestamp,
|
|
855
|
+
agent_id=self.agent_id,
|
|
856
|
+
)
|
|
1126
857
|
)
|
|
1127
|
-
written_records.append(record)
|
|
1128
|
-
self.memory.write_record(record)
|
|
1129
858
|
|
|
1130
859
|
base_ts = (
|
|
1131
860
|
timestamp
|
|
@@ -1140,7 +869,7 @@ class ChatAgent(BaseAgent):
|
|
|
1140
869
|
token_limit = context_creator.token_limit
|
|
1141
870
|
except AttributeError:
|
|
1142
871
|
_write_single_record(message, role, base_ts)
|
|
1143
|
-
return
|
|
872
|
+
return
|
|
1144
873
|
|
|
1145
874
|
# 3. Check if slicing is necessary
|
|
1146
875
|
try:
|
|
@@ -1156,14 +885,14 @@ class ChatAgent(BaseAgent):
|
|
|
1156
885
|
|
|
1157
886
|
if current_tokens <= remaining_budget:
|
|
1158
887
|
_write_single_record(message, role, base_ts)
|
|
1159
|
-
return
|
|
888
|
+
return
|
|
1160
889
|
except Exception as e:
|
|
1161
890
|
logger.warning(
|
|
1162
891
|
f"Token calculation failed before chunking, "
|
|
1163
892
|
f"writing message as-is. Error: {e}"
|
|
1164
893
|
)
|
|
1165
894
|
_write_single_record(message, role, base_ts)
|
|
1166
|
-
return
|
|
895
|
+
return
|
|
1167
896
|
|
|
1168
897
|
# 4. Perform slicing
|
|
1169
898
|
logger.warning(
|
|
@@ -1184,18 +913,18 @@ class ChatAgent(BaseAgent):
|
|
|
1184
913
|
|
|
1185
914
|
if not text_to_chunk or not text_to_chunk.strip():
|
|
1186
915
|
_write_single_record(message, role, base_ts)
|
|
1187
|
-
return
|
|
916
|
+
return
|
|
1188
917
|
# Encode the entire text to get a list of all token IDs
|
|
1189
918
|
try:
|
|
1190
919
|
all_token_ids = token_counter.encode(text_to_chunk)
|
|
1191
920
|
except Exception as e:
|
|
1192
921
|
logger.error(f"Failed to encode text for chunking: {e}")
|
|
1193
922
|
_write_single_record(message, role, base_ts) # Fallback
|
|
1194
|
-
return
|
|
923
|
+
return
|
|
1195
924
|
|
|
1196
925
|
if not all_token_ids:
|
|
1197
926
|
_write_single_record(message, role, base_ts) # Nothing to chunk
|
|
1198
|
-
return
|
|
927
|
+
return
|
|
1199
928
|
|
|
1200
929
|
# 1. Base chunk size: one-tenth of the smaller of (a) total token
|
|
1201
930
|
# limit and (b) current remaining budget. This prevents us from
|
|
@@ -1261,8 +990,6 @@ class ChatAgent(BaseAgent):
|
|
|
1261
990
|
# Increment timestamp slightly to maintain order
|
|
1262
991
|
_write_single_record(new_msg, role, base_ts + i * 1e-6)
|
|
1263
992
|
|
|
1264
|
-
return written_records if return_records else None
|
|
1265
|
-
|
|
1266
993
|
def load_memory(self, memory: AgentMemory) -> None:
|
|
1267
994
|
r"""Load the provided memory into the agent.
|
|
1268
995
|
|
|
@@ -1583,8 +1310,6 @@ class ChatAgent(BaseAgent):
|
|
|
1583
1310
|
None
|
|
1584
1311
|
"""
|
|
1585
1312
|
self.memory.clear()
|
|
1586
|
-
if self._tool_output_cache_enabled:
|
|
1587
|
-
self._tool_output_history.clear()
|
|
1588
1313
|
|
|
1589
1314
|
if self.system_message is not None:
|
|
1590
1315
|
self.update_memory(self.system_message, OpenAIBackendRole.SYSTEM)
|
|
@@ -3015,18 +2740,14 @@ class ChatAgent(BaseAgent):
|
|
|
3015
2740
|
base_timestamp = current_time_ns / 1_000_000_000 # Convert to seconds
|
|
3016
2741
|
|
|
3017
2742
|
self.update_memory(
|
|
3018
|
-
assist_msg,
|
|
3019
|
-
OpenAIBackendRole.ASSISTANT,
|
|
3020
|
-
timestamp=base_timestamp,
|
|
3021
|
-
return_records=self._tool_output_cache_enabled,
|
|
2743
|
+
assist_msg, OpenAIBackendRole.ASSISTANT, timestamp=base_timestamp
|
|
3022
2744
|
)
|
|
3023
2745
|
|
|
3024
2746
|
# Add minimal increment to ensure function message comes after
|
|
3025
|
-
|
|
2747
|
+
self.update_memory(
|
|
3026
2748
|
func_msg,
|
|
3027
2749
|
OpenAIBackendRole.FUNCTION,
|
|
3028
2750
|
timestamp=base_timestamp + 1e-6,
|
|
3029
|
-
return_records=self._tool_output_cache_enabled,
|
|
3030
2751
|
)
|
|
3031
2752
|
|
|
3032
2753
|
# Record information about this tool call
|
|
@@ -3037,20 +2758,6 @@ class ChatAgent(BaseAgent):
|
|
|
3037
2758
|
tool_call_id=tool_call_id,
|
|
3038
2759
|
)
|
|
3039
2760
|
|
|
3040
|
-
if (
|
|
3041
|
-
self._tool_output_cache_enabled
|
|
3042
|
-
and not mask_output
|
|
3043
|
-
and func_records
|
|
3044
|
-
and self._tool_output_cache_manager is not None
|
|
3045
|
-
):
|
|
3046
|
-
serialized_result = self._serialize_tool_result(result)
|
|
3047
|
-
self._register_tool_output_for_cache(
|
|
3048
|
-
func_name,
|
|
3049
|
-
tool_call_id,
|
|
3050
|
-
serialized_result,
|
|
3051
|
-
cast(List[MemoryRecord], func_records),
|
|
3052
|
-
)
|
|
3053
|
-
|
|
3054
2761
|
return tool_record
|
|
3055
2762
|
|
|
3056
2763
|
def _stream(
|
|
@@ -4402,9 +4109,6 @@ class ChatAgent(BaseAgent):
|
|
|
4402
4109
|
tool_execution_timeout=self.tool_execution_timeout,
|
|
4403
4110
|
pause_event=self.pause_event,
|
|
4404
4111
|
prune_tool_calls_from_memory=self.prune_tool_calls_from_memory,
|
|
4405
|
-
enable_tool_output_cache=self._tool_output_cache_enabled,
|
|
4406
|
-
tool_output_cache_threshold=self._tool_output_cache_threshold,
|
|
4407
|
-
tool_output_cache_dir=self._tool_output_cache_dir,
|
|
4408
4112
|
stream_accumulate=self.stream_accumulate,
|
|
4409
4113
|
)
|
|
4410
4114
|
|
camel/toolkits/excel_toolkit.py
CHANGED
|
@@ -872,7 +872,7 @@ class ExcelToolkit(BaseToolkit):
|
|
|
872
872
|
import csv
|
|
873
873
|
|
|
874
874
|
with open(
|
|
875
|
-
resolved_csv_path, 'w', newline='', encoding='utf-8'
|
|
875
|
+
resolved_csv_path, 'w', newline='', encoding='utf-8-sig'
|
|
876
876
|
) as csvfile:
|
|
877
877
|
writer = csv.writer(csvfile)
|
|
878
878
|
writer.writerows(data)
|
camel/toolkits/file_toolkit.py
CHANGED
|
@@ -906,7 +906,7 @@ class FileToolkit(BaseToolkit):
|
|
|
906
906
|
self,
|
|
907
907
|
file_path: Path,
|
|
908
908
|
content: Union[str, List[List]],
|
|
909
|
-
encoding: str = "utf-8",
|
|
909
|
+
encoding: str = "utf-8-sig",
|
|
910
910
|
) -> None:
|
|
911
911
|
r"""Write CSV content to a file.
|
|
912
912
|
|
|
@@ -914,7 +914,8 @@ class FileToolkit(BaseToolkit):
|
|
|
914
914
|
file_path (Path): The target file path.
|
|
915
915
|
content (Union[str, List[List]]): The CSV content as a string or
|
|
916
916
|
list of lists.
|
|
917
|
-
encoding (str): Character encoding to use.
|
|
917
|
+
encoding (str): Character encoding to use.
|
|
918
|
+
(default: :obj:`utf-8-sig`)
|
|
918
919
|
"""
|
|
919
920
|
import csv
|
|
920
921
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: camel-ai
|
|
3
|
-
Version: 0.2.
|
|
3
|
+
Version: 0.2.78
|
|
4
4
|
Summary: Communicative Agents for AI Society Study
|
|
5
5
|
Project-URL: Homepage, https://www.camel-ai.org/
|
|
6
6
|
Project-URL: Repository, https://github.com/camel-ai/camel
|
|
@@ -916,6 +916,7 @@ Real-world usecases demonstrating how CAMEL’s multi-agent framework enables re
|
|
|
916
916
|
|:---|:---|
|
|
917
917
|
| **[ChatDev](https://github.com/OpenBMB/ChatDev/tree/main/camel)** | Communicative Agents for software Development |
|
|
918
918
|
| **[Paper2Poster](https://github.com/Paper2Poster/Paper2Poster)** | Multimodal poster automation from scientific papers |
|
|
919
|
+
| **[Paper2Video](https://github.com/showlab/Paper2Video)** | Automatic video generation from scientific papers |
|
|
919
920
|
|
|
920
921
|
### Product Projects
|
|
921
922
|
|
|
@@ -948,6 +949,14 @@ We are actively involved in community events including:
|
|
|
948
949
|
>
|
|
949
950
|
> We also welcome you to help CAMEL grow by sharing it on social media, at events, or during conferences. Your support makes a big difference!
|
|
950
951
|
|
|
952
|
+
## Contributors
|
|
953
|
+
|
|
954
|
+
<a href="https://github.com/camel-ai/camel/graphs/contributors">
|
|
955
|
+
<img src="https://contrib.rocks/image?repo=camel-ai/camel" />
|
|
956
|
+
</a>
|
|
957
|
+
|
|
958
|
+
Made with [contrib.rocks](https://contrib.rocks).
|
|
959
|
+
|
|
951
960
|
<br>
|
|
952
961
|
|
|
953
962
|
## Community & Contact
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
camel/__init__.py,sha256=
|
|
1
|
+
camel/__init__.py,sha256=cpFup8atJGzU-oY43vhHAU_qEtlLnvGaBB3WCCgAWUE,899
|
|
2
2
|
camel/generators.py,sha256=JRqj9_m1PF4qT6UtybzTQ-KBT9MJQt18OAAYvQ_fr2o,13844
|
|
3
3
|
camel/human.py,sha256=Xg8x1cS5KK4bQ1SDByiHZnzsRpvRP-KZViNvmu38xo4,5475
|
|
4
4
|
camel/logger.py,sha256=WgEwael_eT6D-lVAKHpKIpwXSTjvLbny5jbV1Ab8lnA,5760
|
|
@@ -7,7 +7,7 @@ camel/agents/__init__.py,sha256=64weKqdvmpZcGWyVkO-OKASAmVUdrQjv60JApgPk_SA,1644
|
|
|
7
7
|
camel/agents/_types.py,sha256=MeFZzay2kJA6evALQ-MbBTKW-0lu_0wBuKsxzH_4gWI,1552
|
|
8
8
|
camel/agents/_utils.py,sha256=AR7Qqgbkmn4X2edYUQf1rdksGUyV5hm3iK1z-Dn0Mcg,6266
|
|
9
9
|
camel/agents/base.py,sha256=c4bJYL3G3Z41SaFdMPMn8ZjLdFiFaVOFO6EQIfuCVR8,1124
|
|
10
|
-
camel/agents/chat_agent.py,sha256=
|
|
10
|
+
camel/agents/chat_agent.py,sha256=hdO7dFEDwCpRbfOXMlVPRaFc5-pKPlwq6UGyZ5ey6mc,175592
|
|
11
11
|
camel/agents/critic_agent.py,sha256=L6cTbYjyZB0DCa51tQ6LZLA6my8kHLC4nktHySH78H4,10433
|
|
12
12
|
camel/agents/deductive_reasoner_agent.py,sha256=6BZGaq1hR6hKJuQtOfoYQnk_AkZpw_Mr7mUy2MspQgs,13540
|
|
13
13
|
camel/agents/embodied_agent.py,sha256=XBxBu5ZMmSJ4B2U3Z7SMwvLlgp6yNpaBe8HNQmY9CZA,7536
|
|
@@ -342,8 +342,8 @@ camel/toolkits/dappier_toolkit.py,sha256=OEHOYXX_oXhgbVtWYAy13nO9uXf9i5qEXSwY4Pe
|
|
|
342
342
|
camel/toolkits/data_commons_toolkit.py,sha256=aHZUSL1ACpnYGaf1rE2csVKTmXTmN8lMGRUBYhZ_YEk,14168
|
|
343
343
|
camel/toolkits/dingtalk.py,sha256=TD-3dSzzV9S_yrOKQ4Yfp1DOjEOJruiIG-WytKx2EAE,36689
|
|
344
344
|
camel/toolkits/edgeone_pages_mcp_toolkit.py,sha256=vD6nOF__pue5HSJZTPwjzB_evpDdFJtPEG-bKszOOQE,1712
|
|
345
|
-
camel/toolkits/excel_toolkit.py,sha256
|
|
346
|
-
camel/toolkits/file_toolkit.py,sha256=
|
|
345
|
+
camel/toolkits/excel_toolkit.py,sha256=-3dqFyIPoCtej3z-_6D3BOdo2gtzw91BLBbWaIE8dxo,35772
|
|
346
|
+
camel/toolkits/file_toolkit.py,sha256=ngK-2KIxOmNxufrZH3Xo71Kshm745GTSvQm3aBHtkX8,45542
|
|
347
347
|
camel/toolkits/function_tool.py,sha256=ke02awKhiHJo2FBHLewvimcJKf4DaAzgJ-fdA5RmrDo,34542
|
|
348
348
|
camel/toolkits/github_toolkit.py,sha256=TYkrAiQuLgAolatTKSMZQkI9wKuV85B26HcLao1CCWw,16380
|
|
349
349
|
camel/toolkits/google_calendar_toolkit.py,sha256=E-sdgdbtNBs_CXbhht9t1dsVr4DsTr5NguHkx4fvSmc,15410
|
|
@@ -487,7 +487,7 @@ camel/verifiers/math_verifier.py,sha256=tA1D4S0sm8nsWISevxSN0hvSVtIUpqmJhzqfbuMo
|
|
|
487
487
|
camel/verifiers/models.py,sha256=GdxYPr7UxNrR1577yW4kyroRcLGfd-H1GXgv8potDWU,2471
|
|
488
488
|
camel/verifiers/physics_verifier.py,sha256=c1grrRddcrVN7szkxhv2QirwY9viIRSITWeWFF5HmLs,30187
|
|
489
489
|
camel/verifiers/python_verifier.py,sha256=ogTz77wODfEcDN4tMVtiSkRQyoiZbHPY2fKybn59lHw,20558
|
|
490
|
-
camel_ai-0.2.
|
|
491
|
-
camel_ai-0.2.
|
|
492
|
-
camel_ai-0.2.
|
|
493
|
-
camel_ai-0.2.
|
|
490
|
+
camel_ai-0.2.78.dist-info/METADATA,sha256=tcNZDsN832ZzzwQHP7zUcKhSoYuP65CS9qyzClO4vJo,55507
|
|
491
|
+
camel_ai-0.2.78.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
|
|
492
|
+
camel_ai-0.2.78.dist-info/licenses/LICENSE,sha256=id0nB2my5kG0xXeimIu5zZrbHLS6EQvxvkKkzIHaT2k,11343
|
|
493
|
+
camel_ai-0.2.78.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|