camel-ai 0.2.67__py3-none-any.whl → 0.2.80a2__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.
- camel/__init__.py +1 -1
- camel/agents/_types.py +6 -2
- camel/agents/_utils.py +38 -0
- camel/agents/chat_agent.py +4014 -410
- camel/agents/mcp_agent.py +30 -27
- camel/agents/repo_agent.py +2 -1
- camel/benchmarks/browsecomp.py +6 -6
- camel/configs/__init__.py +15 -0
- camel/configs/aihubmix_config.py +88 -0
- camel/configs/amd_config.py +70 -0
- camel/configs/cometapi_config.py +104 -0
- camel/configs/minimax_config.py +93 -0
- camel/configs/nebius_config.py +103 -0
- camel/configs/vllm_config.py +2 -0
- camel/data_collectors/alpaca_collector.py +15 -6
- camel/datagen/self_improving_cot.py +1 -1
- camel/datasets/base_generator.py +39 -10
- camel/environments/__init__.py +12 -0
- camel/environments/rlcards_env.py +860 -0
- camel/environments/single_step.py +28 -3
- camel/environments/tic_tac_toe.py +1 -1
- camel/interpreters/__init__.py +2 -0
- camel/interpreters/docker/Dockerfile +4 -16
- camel/interpreters/docker_interpreter.py +3 -2
- camel/interpreters/e2b_interpreter.py +34 -1
- camel/interpreters/internal_python_interpreter.py +51 -2
- camel/interpreters/microsandbox_interpreter.py +395 -0
- camel/loaders/__init__.py +11 -2
- camel/loaders/base_loader.py +85 -0
- camel/loaders/chunkr_reader.py +9 -0
- camel/loaders/firecrawl_reader.py +4 -4
- camel/logger.py +1 -1
- camel/memories/agent_memories.py +84 -1
- camel/memories/base.py +34 -0
- camel/memories/blocks/chat_history_block.py +122 -4
- camel/memories/blocks/vectordb_block.py +8 -1
- camel/memories/context_creators/score_based.py +29 -237
- camel/memories/records.py +88 -8
- camel/messages/base.py +166 -40
- camel/messages/func_message.py +32 -5
- camel/models/__init__.py +10 -0
- camel/models/aihubmix_model.py +83 -0
- camel/models/aiml_model.py +1 -16
- camel/models/amd_model.py +101 -0
- camel/models/anthropic_model.py +117 -18
- camel/models/aws_bedrock_model.py +2 -33
- camel/models/azure_openai_model.py +205 -91
- camel/models/base_audio_model.py +3 -1
- camel/models/base_model.py +189 -24
- camel/models/cohere_model.py +5 -17
- camel/models/cometapi_model.py +83 -0
- camel/models/crynux_model.py +1 -16
- camel/models/deepseek_model.py +6 -16
- camel/models/fish_audio_model.py +6 -0
- camel/models/gemini_model.py +71 -20
- camel/models/groq_model.py +1 -17
- camel/models/internlm_model.py +1 -16
- camel/models/litellm_model.py +49 -32
- camel/models/lmstudio_model.py +1 -17
- camel/models/minimax_model.py +83 -0
- camel/models/mistral_model.py +1 -16
- camel/models/model_factory.py +27 -1
- camel/models/model_manager.py +24 -6
- camel/models/modelscope_model.py +1 -16
- camel/models/moonshot_model.py +185 -19
- camel/models/nebius_model.py +83 -0
- camel/models/nemotron_model.py +0 -5
- camel/models/netmind_model.py +1 -16
- camel/models/novita_model.py +1 -16
- camel/models/nvidia_model.py +1 -16
- camel/models/ollama_model.py +4 -19
- camel/models/openai_compatible_model.py +171 -46
- camel/models/openai_model.py +205 -77
- camel/models/openrouter_model.py +1 -17
- camel/models/ppio_model.py +1 -16
- camel/models/qianfan_model.py +1 -16
- camel/models/qwen_model.py +1 -16
- camel/models/reka_model.py +1 -16
- camel/models/samba_model.py +34 -47
- camel/models/sglang_model.py +64 -31
- camel/models/siliconflow_model.py +1 -16
- camel/models/stub_model.py +0 -4
- camel/models/togetherai_model.py +1 -16
- camel/models/vllm_model.py +1 -16
- camel/models/volcano_model.py +0 -17
- camel/models/watsonx_model.py +1 -16
- camel/models/yi_model.py +1 -16
- camel/models/zhipuai_model.py +60 -16
- camel/parsers/__init__.py +18 -0
- camel/parsers/mcp_tool_call_parser.py +176 -0
- camel/retrievers/auto_retriever.py +1 -0
- camel/runtimes/configs.py +11 -11
- camel/runtimes/daytona_runtime.py +15 -16
- camel/runtimes/docker_runtime.py +6 -6
- camel/runtimes/remote_http_runtime.py +5 -5
- camel/services/agent_openapi_server.py +380 -0
- camel/societies/__init__.py +2 -0
- camel/societies/role_playing.py +26 -28
- camel/societies/workforce/__init__.py +2 -0
- camel/societies/workforce/events.py +122 -0
- camel/societies/workforce/prompts.py +249 -38
- camel/societies/workforce/role_playing_worker.py +82 -20
- camel/societies/workforce/single_agent_worker.py +634 -34
- camel/societies/workforce/structured_output_handler.py +512 -0
- camel/societies/workforce/task_channel.py +169 -23
- camel/societies/workforce/utils.py +176 -9
- camel/societies/workforce/worker.py +77 -23
- camel/societies/workforce/workflow_memory_manager.py +772 -0
- camel/societies/workforce/workforce.py +3168 -478
- camel/societies/workforce/workforce_callback.py +74 -0
- camel/societies/workforce/workforce_logger.py +203 -175
- camel/societies/workforce/workforce_metrics.py +33 -0
- camel/storages/__init__.py +4 -0
- camel/storages/key_value_storages/json.py +15 -2
- camel/storages/key_value_storages/mem0_cloud.py +48 -47
- camel/storages/object_storages/google_cloud.py +1 -1
- camel/storages/vectordb_storages/__init__.py +6 -0
- camel/storages/vectordb_storages/chroma.py +731 -0
- camel/storages/vectordb_storages/oceanbase.py +13 -13
- camel/storages/vectordb_storages/pgvector.py +349 -0
- camel/storages/vectordb_storages/qdrant.py +3 -3
- camel/storages/vectordb_storages/surreal.py +365 -0
- camel/storages/vectordb_storages/tidb.py +8 -6
- camel/tasks/task.py +244 -27
- camel/toolkits/__init__.py +46 -8
- camel/toolkits/aci_toolkit.py +64 -19
- camel/toolkits/arxiv_toolkit.py +6 -6
- camel/toolkits/base.py +63 -5
- camel/toolkits/code_execution.py +28 -1
- camel/toolkits/context_summarizer_toolkit.py +684 -0
- camel/toolkits/craw4ai_toolkit.py +93 -0
- camel/toolkits/dappier_toolkit.py +10 -6
- camel/toolkits/dingtalk.py +1135 -0
- camel/toolkits/edgeone_pages_mcp_toolkit.py +49 -0
- camel/toolkits/excel_toolkit.py +901 -67
- camel/toolkits/file_toolkit.py +1402 -0
- camel/toolkits/function_tool.py +30 -6
- camel/toolkits/github_toolkit.py +107 -20
- camel/toolkits/gmail_toolkit.py +1839 -0
- camel/toolkits/google_calendar_toolkit.py +38 -4
- camel/toolkits/google_drive_mcp_toolkit.py +54 -0
- camel/toolkits/human_toolkit.py +34 -10
- camel/toolkits/hybrid_browser_toolkit/__init__.py +18 -0
- camel/toolkits/hybrid_browser_toolkit/config_loader.py +185 -0
- camel/toolkits/hybrid_browser_toolkit/hybrid_browser_toolkit.py +246 -0
- camel/toolkits/hybrid_browser_toolkit/hybrid_browser_toolkit_ts.py +1973 -0
- camel/toolkits/hybrid_browser_toolkit/installer.py +203 -0
- camel/toolkits/hybrid_browser_toolkit/ts/package-lock.json +3749 -0
- camel/toolkits/hybrid_browser_toolkit/ts/package.json +32 -0
- camel/toolkits/hybrid_browser_toolkit/ts/src/browser-scripts.js +125 -0
- camel/toolkits/hybrid_browser_toolkit/ts/src/browser-session.ts +1815 -0
- camel/toolkits/hybrid_browser_toolkit/ts/src/config-loader.ts +233 -0
- camel/toolkits/hybrid_browser_toolkit/ts/src/hybrid-browser-toolkit.ts +590 -0
- camel/toolkits/hybrid_browser_toolkit/ts/src/index.ts +7 -0
- camel/toolkits/hybrid_browser_toolkit/ts/src/parent-child-filter.ts +226 -0
- camel/toolkits/hybrid_browser_toolkit/ts/src/snapshot-parser.ts +219 -0
- camel/toolkits/hybrid_browser_toolkit/ts/src/som-screenshot-injected.ts +543 -0
- camel/toolkits/hybrid_browser_toolkit/ts/src/types.ts +130 -0
- camel/toolkits/hybrid_browser_toolkit/ts/tsconfig.json +26 -0
- camel/toolkits/hybrid_browser_toolkit/ts/websocket-server.js +319 -0
- camel/toolkits/hybrid_browser_toolkit/ws_wrapper.py +1032 -0
- camel/toolkits/hybrid_browser_toolkit_py/__init__.py +17 -0
- camel/toolkits/hybrid_browser_toolkit_py/actions.py +575 -0
- camel/toolkits/hybrid_browser_toolkit_py/agent.py +311 -0
- camel/toolkits/hybrid_browser_toolkit_py/browser_session.py +787 -0
- camel/toolkits/hybrid_browser_toolkit_py/config_loader.py +490 -0
- camel/toolkits/hybrid_browser_toolkit_py/hybrid_browser_toolkit.py +2390 -0
- camel/toolkits/hybrid_browser_toolkit_py/snapshot.py +233 -0
- camel/toolkits/hybrid_browser_toolkit_py/stealth_script.js +0 -0
- camel/toolkits/hybrid_browser_toolkit_py/unified_analyzer.js +1043 -0
- camel/toolkits/image_generation_toolkit.py +390 -0
- camel/toolkits/jina_reranker_toolkit.py +3 -4
- camel/toolkits/klavis_toolkit.py +5 -1
- camel/toolkits/markitdown_toolkit.py +104 -0
- camel/toolkits/math_toolkit.py +64 -10
- camel/toolkits/mcp_toolkit.py +370 -45
- camel/toolkits/memory_toolkit.py +5 -1
- camel/toolkits/message_agent_toolkit.py +608 -0
- camel/toolkits/message_integration.py +724 -0
- camel/toolkits/minimax_mcp_toolkit.py +195 -0
- camel/toolkits/note_taking_toolkit.py +277 -0
- camel/toolkits/notion_mcp_toolkit.py +224 -0
- camel/toolkits/openbb_toolkit.py +5 -1
- camel/toolkits/origene_mcp_toolkit.py +56 -0
- camel/toolkits/playwright_mcp_toolkit.py +12 -31
- camel/toolkits/pptx_toolkit.py +25 -12
- camel/toolkits/resend_toolkit.py +168 -0
- camel/toolkits/screenshot_toolkit.py +213 -0
- camel/toolkits/search_toolkit.py +437 -142
- camel/toolkits/slack_toolkit.py +104 -50
- camel/toolkits/sympy_toolkit.py +1 -1
- camel/toolkits/task_planning_toolkit.py +3 -3
- camel/toolkits/terminal_toolkit/__init__.py +18 -0
- camel/toolkits/terminal_toolkit/terminal_toolkit.py +957 -0
- camel/toolkits/terminal_toolkit/utils.py +532 -0
- camel/toolkits/thinking_toolkit.py +1 -1
- camel/toolkits/vertex_ai_veo_toolkit.py +590 -0
- camel/toolkits/video_analysis_toolkit.py +106 -26
- camel/toolkits/video_download_toolkit.py +17 -14
- camel/toolkits/web_deploy_toolkit.py +1219 -0
- camel/toolkits/wechat_official_toolkit.py +483 -0
- camel/toolkits/zapier_toolkit.py +5 -1
- camel/types/__init__.py +2 -2
- camel/types/agents/tool_calling_record.py +4 -1
- camel/types/enums.py +316 -40
- camel/types/openai_types.py +2 -2
- camel/types/unified_model_type.py +31 -4
- camel/utils/commons.py +36 -5
- camel/utils/constants.py +3 -0
- camel/utils/context_utils.py +1003 -0
- camel/utils/mcp.py +138 -4
- camel/utils/mcp_client.py +45 -1
- camel/utils/message_summarizer.py +148 -0
- camel/utils/token_counting.py +43 -20
- camel/utils/tool_result.py +44 -0
- {camel_ai-0.2.67.dist-info → camel_ai-0.2.80a2.dist-info}/METADATA +296 -85
- {camel_ai-0.2.67.dist-info → camel_ai-0.2.80a2.dist-info}/RECORD +219 -146
- camel/loaders/pandas_reader.py +0 -368
- camel/toolkits/dalle_toolkit.py +0 -175
- camel/toolkits/file_write_toolkit.py +0 -444
- camel/toolkits/openai_agent_toolkit.py +0 -135
- camel/toolkits/terminal_toolkit.py +0 -1037
- {camel_ai-0.2.67.dist-info → camel_ai-0.2.80a2.dist-info}/WHEEL +0 -0
- {camel_ai-0.2.67.dist-info → camel_ai-0.2.80a2.dist-info}/licenses/LICENSE +0 -0
camel/runtimes/configs.py
CHANGED
|
@@ -21,22 +21,22 @@ class TaskConfig(BaseModel):
|
|
|
21
21
|
|
|
22
22
|
Arttributes:
|
|
23
23
|
cmd (str or list): Command to be executed
|
|
24
|
-
stdout (bool): Attach to stdout. (default: :obj
|
|
25
|
-
stderr (bool): Attach to stderr. (default: :obj
|
|
26
|
-
stdin (bool): Attach to stdin. (default: :obj
|
|
27
|
-
tty (bool): Allocate a pseudo-TTY. (default: :obj
|
|
28
|
-
privileged (bool): Run as privileged. (default: :obj
|
|
29
|
-
user (str): User to execute command as. (default: :obj
|
|
24
|
+
stdout (bool): Attach to stdout. (default: :obj:`True`)
|
|
25
|
+
stderr (bool): Attach to stderr. (default: :obj:`True`)
|
|
26
|
+
stdin (bool): Attach to stdin. (default: :obj:`False`)
|
|
27
|
+
tty (bool): Allocate a pseudo-TTY. (default: :obj:`False`)
|
|
28
|
+
privileged (bool): Run as privileged. (default: :obj:`False`)
|
|
29
|
+
user (str): User to execute command as. (default: :obj:`""`)
|
|
30
30
|
detach (bool): If true, detach from the exec command.
|
|
31
|
-
(default: :obj
|
|
32
|
-
stream (bool): Stream response data. (default: :obj
|
|
31
|
+
(default: :obj:`False`)
|
|
32
|
+
stream (bool): Stream response data. (default: :obj:`False`)
|
|
33
33
|
socket (bool): Return the connection socket to allow custom
|
|
34
|
-
read/write operations. (default: :obj
|
|
34
|
+
read/write operations. (default: :obj:`False`)
|
|
35
35
|
environment (dict or list): A dictionary or a list of strings in
|
|
36
36
|
the following format ``["PASSWORD=xxx"]`` or
|
|
37
|
-
``{"PASSWORD": "xxx"}``. (default: :obj
|
|
37
|
+
``{"PASSWORD": "xxx"}``. (default: :obj:`None`)
|
|
38
38
|
workdir (str): Path to working directory for this exec session.
|
|
39
|
-
(default: :obj
|
|
39
|
+
(default: :obj:`None`)
|
|
40
40
|
demux (bool): Return stdout and stderr separately. (default: :obj:
|
|
41
41
|
`False`)
|
|
42
42
|
"""
|
|
@@ -16,7 +16,7 @@ import inspect
|
|
|
16
16
|
import json
|
|
17
17
|
import os
|
|
18
18
|
from functools import wraps
|
|
19
|
-
from typing import Any, Dict, List, Optional, Union
|
|
19
|
+
from typing import Any, Callable, Dict, List, Optional, Union
|
|
20
20
|
|
|
21
21
|
from pydantic import BaseModel
|
|
22
22
|
|
|
@@ -34,13 +34,13 @@ class DaytonaRuntime(BaseRuntime):
|
|
|
34
34
|
Args:
|
|
35
35
|
api_key (Optional[str]): The Daytona API key for authentication. If not
|
|
36
36
|
provided, it will try to use the DAYTONA_API_KEY environment
|
|
37
|
-
variable. (default: :obj
|
|
37
|
+
variable. (default: :obj:`None`)
|
|
38
38
|
api_url (Optional[str]): The URL of the Daytona server. If not
|
|
39
39
|
provided, it will try to use the DAYTONA_API_URL environment
|
|
40
40
|
variable. If none is provided, it will use "http://localhost:8000".
|
|
41
|
-
(default: :obj
|
|
41
|
+
(default: :obj:`None`)
|
|
42
42
|
language (Optional[str]): The programming language for the sandbox.
|
|
43
|
-
(default: :obj
|
|
43
|
+
(default: :obj:`"python"`)
|
|
44
44
|
"""
|
|
45
45
|
|
|
46
46
|
def __init__(
|
|
@@ -49,7 +49,7 @@ class DaytonaRuntime(BaseRuntime):
|
|
|
49
49
|
api_url: Optional[str] = None,
|
|
50
50
|
language: Optional[str] = "python",
|
|
51
51
|
):
|
|
52
|
-
from daytona_sdk import Daytona, DaytonaConfig
|
|
52
|
+
from daytona_sdk import Daytona, DaytonaConfig, Sandbox
|
|
53
53
|
|
|
54
54
|
super().__init__()
|
|
55
55
|
self.api_key = api_key or os.environ.get('DAYTONA_API_KEY')
|
|
@@ -57,7 +57,7 @@ class DaytonaRuntime(BaseRuntime):
|
|
|
57
57
|
self.language = language
|
|
58
58
|
self.config = DaytonaConfig(api_key=self.api_key, api_url=self.api_url)
|
|
59
59
|
self.daytona = Daytona(self.config)
|
|
60
|
-
self.sandbox = None
|
|
60
|
+
self.sandbox: Optional[Sandbox] = None
|
|
61
61
|
self.entrypoint: Dict[str, str] = dict()
|
|
62
62
|
|
|
63
63
|
def build(self) -> "DaytonaRuntime":
|
|
@@ -66,10 +66,10 @@ class DaytonaRuntime(BaseRuntime):
|
|
|
66
66
|
Returns:
|
|
67
67
|
DaytonaRuntime: The current runtime.
|
|
68
68
|
"""
|
|
69
|
-
from daytona_sdk import
|
|
69
|
+
from daytona_sdk import CreateSandboxBaseParams
|
|
70
70
|
|
|
71
71
|
try:
|
|
72
|
-
params =
|
|
72
|
+
params = CreateSandboxBaseParams(language=self.language)
|
|
73
73
|
self.sandbox = self.daytona.create(params)
|
|
74
74
|
if self.sandbox is None:
|
|
75
75
|
raise RuntimeError("Failed to create sandbox.")
|
|
@@ -83,7 +83,7 @@ class DaytonaRuntime(BaseRuntime):
|
|
|
83
83
|
r"""Clean up the sandbox when exiting."""
|
|
84
84
|
if self.sandbox:
|
|
85
85
|
try:
|
|
86
|
-
self.daytona.
|
|
86
|
+
self.daytona.delete(self.sandbox)
|
|
87
87
|
logger.info(f"Sandbox {self.sandbox.id} removed")
|
|
88
88
|
self.sandbox = None
|
|
89
89
|
except Exception as e:
|
|
@@ -102,7 +102,7 @@ class DaytonaRuntime(BaseRuntime):
|
|
|
102
102
|
list of functions to add.
|
|
103
103
|
entrypoint (str): The entrypoint for the function.
|
|
104
104
|
arguments (Optional[Dict[str, Any]]): The arguments for the
|
|
105
|
-
function. (default: :obj
|
|
105
|
+
function. (default: :obj:`None`)
|
|
106
106
|
|
|
107
107
|
Returns:
|
|
108
108
|
DaytonaRuntime: The current runtime.
|
|
@@ -112,7 +112,7 @@ class DaytonaRuntime(BaseRuntime):
|
|
|
112
112
|
if arguments is not None:
|
|
113
113
|
entrypoint += json.dumps(arguments, ensure_ascii=False)
|
|
114
114
|
|
|
115
|
-
def make_wrapper(inner_func, func_name, func_code):
|
|
115
|
+
def make_wrapper(inner_func: Callable, func_name: str, func_code: str):
|
|
116
116
|
r"""Creates a wrapper for a function to execute it in the
|
|
117
117
|
Daytona sandbox.
|
|
118
118
|
|
|
@@ -208,12 +208,11 @@ class DaytonaRuntime(BaseRuntime):
|
|
|
208
208
|
RuntimeError: If the sandbox is not initialized.
|
|
209
209
|
"""
|
|
210
210
|
if self.sandbox is None:
|
|
211
|
-
raise RuntimeError("
|
|
212
|
-
info = self.sandbox.info()
|
|
211
|
+
raise RuntimeError("Sandbox not initialized.")
|
|
213
212
|
return (
|
|
214
|
-
f"Sandbox {
|
|
215
|
-
f"State: {
|
|
216
|
-
f"Resources: {
|
|
213
|
+
f"Sandbox {self.sandbox.id}:\n"
|
|
214
|
+
f"State: {self.sandbox.state}\n"
|
|
215
|
+
f"Resources: {self.sandbox.cpu} CPU, {self.sandbox.memory} RAM"
|
|
217
216
|
)
|
|
218
217
|
|
|
219
218
|
def __del__(self):
|
camel/runtimes/docker_runtime.py
CHANGED
|
@@ -45,7 +45,7 @@ class DockerRuntime(BaseRuntime):
|
|
|
45
45
|
port (int): The port number to use for the runtime API. (default: :obj:
|
|
46
46
|
`8000`)
|
|
47
47
|
remove (bool): Whether to remove the container after stopping it. '
|
|
48
|
-
(default: :obj
|
|
48
|
+
(default: :obj:`True`)
|
|
49
49
|
kwargs (dict): Additional keyword arguments to pass to the
|
|
50
50
|
Docker client.
|
|
51
51
|
"""
|
|
@@ -170,7 +170,7 @@ class DockerRuntime(BaseRuntime):
|
|
|
170
170
|
|
|
171
171
|
Args:
|
|
172
172
|
time_out (int): The number of seconds to wait for the container to
|
|
173
|
-
start. (default: :obj
|
|
173
|
+
start. (default: :obj:`15`)
|
|
174
174
|
|
|
175
175
|
Returns:
|
|
176
176
|
DockerRuntime: The DockerRuntime instance.
|
|
@@ -259,9 +259,9 @@ class DockerRuntime(BaseRuntime):
|
|
|
259
259
|
list of functions to add.
|
|
260
260
|
entrypoint (str): The entrypoint for the function.
|
|
261
261
|
redirect_stdout (bool): Whether to return the stdout of
|
|
262
|
-
the function. (default: :obj
|
|
262
|
+
the function. (default: :obj:`False`)
|
|
263
263
|
arguments (Optional[Dict[str, Any]]): The arguments for the
|
|
264
|
-
function. (default: :obj
|
|
264
|
+
function. (default: :obj:`None`)
|
|
265
265
|
|
|
266
266
|
Returns:
|
|
267
267
|
DockerRuntime: The DockerRuntime instance.
|
|
@@ -330,7 +330,7 @@ class DockerRuntime(BaseRuntime):
|
|
|
330
330
|
|
|
331
331
|
Args:
|
|
332
332
|
remove (Optional[bool]): Whether to remove the container
|
|
333
|
-
after stopping it. (default: :obj
|
|
333
|
+
after stopping it. (default: :obj:`None`)
|
|
334
334
|
|
|
335
335
|
Returns:
|
|
336
336
|
DockerRuntime: The DockerRuntime instance.
|
|
@@ -366,7 +366,7 @@ class DockerRuntime(BaseRuntime):
|
|
|
366
366
|
r"""Wait for the API Server to be ready.
|
|
367
367
|
|
|
368
368
|
Args:
|
|
369
|
-
timeout (int): The number of seconds to wait. (default: :obj
|
|
369
|
+
timeout (int): The number of seconds to wait. (default: :obj:`10`)
|
|
370
370
|
|
|
371
371
|
Returns:
|
|
372
372
|
bool: Whether the API Server is ready.
|
|
@@ -36,9 +36,9 @@ class RemoteHttpRuntime(BaseRuntime):
|
|
|
36
36
|
|
|
37
37
|
Args:
|
|
38
38
|
host (str): The host of the remote server.
|
|
39
|
-
port (int): The port of the remote server. (default: :obj
|
|
39
|
+
port (int): The port of the remote server. (default: :obj:`8000`)
|
|
40
40
|
python_exec (str): The python executable to run the API server.
|
|
41
|
-
(default: :obj
|
|
41
|
+
(default: :obj:`python3`)
|
|
42
42
|
"""
|
|
43
43
|
|
|
44
44
|
def __init__(
|
|
@@ -90,9 +90,9 @@ class RemoteHttpRuntime(BaseRuntime):
|
|
|
90
90
|
list of functions to add.
|
|
91
91
|
entrypoint (str): The entrypoint for the function.
|
|
92
92
|
redirect_stdout (bool): Whether to return the stdout of
|
|
93
|
-
the function. (default: :obj
|
|
93
|
+
the function. (default: :obj:`False`)
|
|
94
94
|
arguments (Optional[Dict[str, Any]]): The arguments for the
|
|
95
|
-
function. (default: :obj
|
|
95
|
+
function. (default: :obj:`None`)
|
|
96
96
|
|
|
97
97
|
Returns:
|
|
98
98
|
RemoteHttpRuntime: The current runtime.
|
|
@@ -162,7 +162,7 @@ class RemoteHttpRuntime(BaseRuntime):
|
|
|
162
162
|
r"""Wait for the API Server to be ready.
|
|
163
163
|
|
|
164
164
|
Args:
|
|
165
|
-
timeout (int): The number of seconds to wait. (default: :obj
|
|
165
|
+
timeout (int): The number of seconds to wait. (default: :obj:`10`)
|
|
166
166
|
|
|
167
167
|
Returns:
|
|
168
168
|
bool: Whether the API Server is ready.
|
|
@@ -0,0 +1,380 @@
|
|
|
1
|
+
# ========= Copyright 2023-2024 @ CAMEL-AI.org. All Rights Reserved. =========
|
|
2
|
+
# Licensed under the Apache License, Version 2.0 (the "License");
|
|
3
|
+
# you may not use this file except in compliance with the License.
|
|
4
|
+
# You may obtain a copy of the License at
|
|
5
|
+
#
|
|
6
|
+
# http://www.apache.org/licenses/LICENSE-2.0
|
|
7
|
+
#
|
|
8
|
+
# Unless required by applicable law or agreed to in writing, software
|
|
9
|
+
# distributed under the License is distributed on an "AS IS" BASIS,
|
|
10
|
+
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
|
11
|
+
# See the License for the specific language governing permissions and
|
|
12
|
+
# limitations under the License.
|
|
13
|
+
# ========= Copyright 2023-2024 @ CAMEL-AI.org. All Rights Reserved. =========
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
from typing import Any, Dict, List, Optional, Type, Union
|
|
17
|
+
|
|
18
|
+
from fastapi import APIRouter, FastAPI, HTTPException
|
|
19
|
+
from pydantic import BaseModel
|
|
20
|
+
|
|
21
|
+
from camel.agents.chat_agent import ChatAgent
|
|
22
|
+
from camel.messages import BaseMessage
|
|
23
|
+
from camel.models import ModelFactory
|
|
24
|
+
from camel.toolkits import FunctionTool
|
|
25
|
+
from camel.types import RoleType
|
|
26
|
+
|
|
27
|
+
|
|
28
|
+
class InitRequest(BaseModel):
|
|
29
|
+
r"""Request schema for initializing a ChatAgent via the OpenAPI server.
|
|
30
|
+
|
|
31
|
+
Defines the configuration used to create a new agent, including the model,
|
|
32
|
+
system message, tool names, and generation parameters.
|
|
33
|
+
|
|
34
|
+
Args:
|
|
35
|
+
model_type (Optional[str]): The model type to use. Should match a key
|
|
36
|
+
supported by the model manager, e.g., "gpt-4o-mini".
|
|
37
|
+
(default: :obj:`"gpt-4o-mini"`)
|
|
38
|
+
model_platform (Optional[str]): The model platform to use.
|
|
39
|
+
(default: :obj:`"openai"`)
|
|
40
|
+
tools_names (Optional[List[str]]): A list of tool names to load from
|
|
41
|
+
the tool registry. These tools will be available to the agent.
|
|
42
|
+
(default: :obj:`None`)
|
|
43
|
+
external_tools (Optional[List[Dict[str, Any]]]): Tool definitions
|
|
44
|
+
provided directly as dictionaries, bypassing the registry.
|
|
45
|
+
Currently not supported. (default: :obj:`None`)
|
|
46
|
+
agent_id (str): The unique identifier for the agent. Must be provided
|
|
47
|
+
explicitly to support multi-agent routing and control.
|
|
48
|
+
system_message (Optional[str]): The system prompt for the agent,
|
|
49
|
+
describing its behavior or role. (default: :obj:`None`)
|
|
50
|
+
message_window_size (Optional[int]): The number of recent messages to
|
|
51
|
+
retain in memory for context. (default: :obj:`None`)
|
|
52
|
+
token_limit (Optional[int]): The token budget for contextual memory.
|
|
53
|
+
(default: :obj:`None`)
|
|
54
|
+
output_language (Optional[str]): Preferred output language for the
|
|
55
|
+
agent's replies. (default: :obj:`None`)
|
|
56
|
+
max_iteration (Optional[int]): Maximum number of model
|
|
57
|
+
calling iterations allowed per step. If `None` (default), there's
|
|
58
|
+
no explicit limit. If `1`, it performs a single model call. If `N
|
|
59
|
+
> 1`, it allows up to N model calls. (default: :obj:`None`)
|
|
60
|
+
"""
|
|
61
|
+
|
|
62
|
+
model_type: Optional[str] = "gpt-4o-mini"
|
|
63
|
+
model_platform: Optional[str] = "openai"
|
|
64
|
+
|
|
65
|
+
tools_names: Optional[List[str]] = None
|
|
66
|
+
external_tools: Optional[List[Dict[str, Any]]] = None
|
|
67
|
+
|
|
68
|
+
agent_id: str # Required: explicitly set agent_id to
|
|
69
|
+
# support future multi-agent and permission control
|
|
70
|
+
|
|
71
|
+
system_message: Optional[str] = None
|
|
72
|
+
message_window_size: Optional[int] = None
|
|
73
|
+
token_limit: Optional[int] = None
|
|
74
|
+
output_language: Optional[str] = None
|
|
75
|
+
max_iteration: Optional[int] = None # Changed from Optional[bool] = False
|
|
76
|
+
|
|
77
|
+
|
|
78
|
+
class StepRequest(BaseModel):
|
|
79
|
+
r"""Request schema for sending a user message to a ChatAgent.
|
|
80
|
+
|
|
81
|
+
Supports plain text input or structured message dictionaries, with an
|
|
82
|
+
optional response format for controlling output structure.
|
|
83
|
+
|
|
84
|
+
Args:
|
|
85
|
+
input_message (Union[str, Dict[str, Any]]): The user message to send.
|
|
86
|
+
Can be a plain string or a message dict with role, content, etc.
|
|
87
|
+
response_format (Optional[str]): Optional format name that maps to a
|
|
88
|
+
registered response schema. Not currently in use.
|
|
89
|
+
(default: :obj:`None`)
|
|
90
|
+
"""
|
|
91
|
+
|
|
92
|
+
input_message: Union[str, Dict[str, Any]]
|
|
93
|
+
response_format: Optional[str] = None # reserved, not used yet
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
class ChatAgentOpenAPIServer:
|
|
97
|
+
r"""A FastAPI server wrapper for managing ChatAgents via OpenAPI routes.
|
|
98
|
+
|
|
99
|
+
This server exposes a versioned REST API for interacting with CAMEL
|
|
100
|
+
agents, supporting initialization, message passing, memory inspection,
|
|
101
|
+
and optional tool usage. It supports multi-agent use cases by mapping
|
|
102
|
+
unique agent IDs to active ChatAgent instances.
|
|
103
|
+
|
|
104
|
+
Typical usage includes initializing agents with system prompts and tools,
|
|
105
|
+
exchanging messages using /step or /astep endpoints, and inspecting agent
|
|
106
|
+
memory with /history.
|
|
107
|
+
|
|
108
|
+
Supports pluggable tool and response format registries for customizing
|
|
109
|
+
agent behavior or output schemas.
|
|
110
|
+
"""
|
|
111
|
+
|
|
112
|
+
def __init__(
|
|
113
|
+
self,
|
|
114
|
+
tool_registry: Optional[Dict[str, List[FunctionTool]]] = None,
|
|
115
|
+
response_format_registry: Optional[Dict[str, Type[BaseModel]]] = None,
|
|
116
|
+
):
|
|
117
|
+
r"""Initializes the OpenAPI server for managing ChatAgents.
|
|
118
|
+
|
|
119
|
+
Sets up internal agent storage, tool and response format registries,
|
|
120
|
+
and prepares versioned API routes.
|
|
121
|
+
|
|
122
|
+
Args:
|
|
123
|
+
tool_registry (Optional[Dict[str, List[FunctionTool]]]): A mapping
|
|
124
|
+
from tool names to lists of FunctionTool instances available
|
|
125
|
+
to agents via the "tools_names" field. If not provided, an
|
|
126
|
+
empty registry is used. (default: :obj:`None`)
|
|
127
|
+
response_format_registry (Optional[Dict[str, Type[BaseModel]]]):
|
|
128
|
+
A mapping from format names to Pydantic output schemas for
|
|
129
|
+
structured response parsing. Used for controlling the format
|
|
130
|
+
of step results. (default: :obj:`None`)
|
|
131
|
+
"""
|
|
132
|
+
|
|
133
|
+
# Initialize FastAPI app and agent
|
|
134
|
+
self.app = FastAPI(title="CAMEL OpenAPI-compatible Server")
|
|
135
|
+
self.agents: Dict[str, ChatAgent] = {}
|
|
136
|
+
self.tool_registry = tool_registry or {}
|
|
137
|
+
self.response_format_registry = response_format_registry or {}
|
|
138
|
+
self._setup_routes()
|
|
139
|
+
|
|
140
|
+
def _parse_input_message_for_step(
|
|
141
|
+
self, raw: Union[str, dict]
|
|
142
|
+
) -> BaseMessage:
|
|
143
|
+
r"""Parses raw input into a BaseMessage object.
|
|
144
|
+
|
|
145
|
+
Args:
|
|
146
|
+
raw (str or dict): User input as plain text or dict.
|
|
147
|
+
|
|
148
|
+
Returns:
|
|
149
|
+
BaseMessage: Parsed input message.
|
|
150
|
+
"""
|
|
151
|
+
if isinstance(raw, str):
|
|
152
|
+
return BaseMessage.make_user_message(role_name="User", content=raw)
|
|
153
|
+
elif isinstance(raw, dict):
|
|
154
|
+
if isinstance(raw.get("role_type"), str):
|
|
155
|
+
raw["role_type"] = RoleType(raw["role_type"].lower())
|
|
156
|
+
return BaseMessage(**raw)
|
|
157
|
+
raise HTTPException(
|
|
158
|
+
status_code=400, detail="Unsupported input format."
|
|
159
|
+
)
|
|
160
|
+
|
|
161
|
+
def _resolve_response_format_for_step(
|
|
162
|
+
self, name: Optional[str]
|
|
163
|
+
) -> Optional[Type[BaseModel]]:
|
|
164
|
+
r"""Resolves the response format by name.
|
|
165
|
+
|
|
166
|
+
Args:
|
|
167
|
+
name (str or None): Optional format name.
|
|
168
|
+
|
|
169
|
+
Returns:
|
|
170
|
+
Optional[Type[BaseModel]]: Response schema class.
|
|
171
|
+
"""
|
|
172
|
+
if name is None:
|
|
173
|
+
return None
|
|
174
|
+
if name not in self.response_format_registry:
|
|
175
|
+
raise HTTPException(
|
|
176
|
+
status_code=400, detail=f"Unknown response_format: {name}"
|
|
177
|
+
)
|
|
178
|
+
return self.response_format_registry[name]
|
|
179
|
+
|
|
180
|
+
def _setup_routes(self):
|
|
181
|
+
r"""Registers OpenAPI endpoints for agent creation and interaction.
|
|
182
|
+
|
|
183
|
+
This includes routes for initializing agents (/init), sending
|
|
184
|
+
messages (/step and /astep), resetting agent memory (/reset), and
|
|
185
|
+
retrieving conversation history (/history). All routes are added
|
|
186
|
+
under the /v1/agents namespace.
|
|
187
|
+
"""
|
|
188
|
+
|
|
189
|
+
router = APIRouter(prefix="/v1/agents")
|
|
190
|
+
|
|
191
|
+
@router.post("/init")
|
|
192
|
+
def init_agent(request: InitRequest):
|
|
193
|
+
r"""Initializes a ChatAgent instance with a model,
|
|
194
|
+
system message, and optional tools.
|
|
195
|
+
|
|
196
|
+
Args:
|
|
197
|
+
request (InitRequest): The agent config including
|
|
198
|
+
model, tools, system message, and agent ID.
|
|
199
|
+
|
|
200
|
+
Returns:
|
|
201
|
+
dict: A message with the agent ID and status.
|
|
202
|
+
"""
|
|
203
|
+
|
|
204
|
+
agent_id = request.agent_id
|
|
205
|
+
if agent_id in self.agents:
|
|
206
|
+
return {
|
|
207
|
+
"agent_id": agent_id,
|
|
208
|
+
"message": "Agent already exists.",
|
|
209
|
+
}
|
|
210
|
+
|
|
211
|
+
model_type = request.model_type
|
|
212
|
+
model_platform = request.model_platform
|
|
213
|
+
|
|
214
|
+
model = ModelFactory.create(
|
|
215
|
+
model_platform=model_platform, # type: ignore[arg-type]
|
|
216
|
+
model_type=model_type, # type: ignore[arg-type]
|
|
217
|
+
)
|
|
218
|
+
|
|
219
|
+
# tools lookup
|
|
220
|
+
tools = []
|
|
221
|
+
if request.tools_names:
|
|
222
|
+
for name in request.tools_names:
|
|
223
|
+
if name in self.tool_registry:
|
|
224
|
+
tools.extend(self.tool_registry[name])
|
|
225
|
+
else:
|
|
226
|
+
raise HTTPException(
|
|
227
|
+
status_code=400,
|
|
228
|
+
detail=f"Tool '{name}' " f"not found in registry",
|
|
229
|
+
)
|
|
230
|
+
|
|
231
|
+
# system message
|
|
232
|
+
system_message = request.system_message
|
|
233
|
+
|
|
234
|
+
agent = ChatAgent(
|
|
235
|
+
model=model,
|
|
236
|
+
tools=tools, # type: ignore[arg-type]
|
|
237
|
+
external_tools=request.external_tools, # type: ignore[arg-type]
|
|
238
|
+
system_message=system_message,
|
|
239
|
+
message_window_size=request.message_window_size,
|
|
240
|
+
token_limit=request.token_limit,
|
|
241
|
+
output_language=request.output_language,
|
|
242
|
+
max_iteration=request.max_iteration,
|
|
243
|
+
agent_id=agent_id,
|
|
244
|
+
)
|
|
245
|
+
|
|
246
|
+
self.agents[agent_id] = agent
|
|
247
|
+
return {"agent_id": agent_id, "message": "Agent initialized."}
|
|
248
|
+
|
|
249
|
+
@router.post("/astep/{agent_id}")
|
|
250
|
+
async def astep_agent(agent_id: str, request: StepRequest):
|
|
251
|
+
r"""Runs one async step of agent response.
|
|
252
|
+
|
|
253
|
+
Args:
|
|
254
|
+
agent_id (str): The ID of the target agent.
|
|
255
|
+
request (StepRequest): The input message.
|
|
256
|
+
|
|
257
|
+
Returns:
|
|
258
|
+
dict: The model response in serialized form.
|
|
259
|
+
"""
|
|
260
|
+
|
|
261
|
+
if agent_id not in self.agents:
|
|
262
|
+
raise HTTPException(status_code=404, detail="Agent not found.")
|
|
263
|
+
|
|
264
|
+
agent = self.agents[agent_id]
|
|
265
|
+
input_message = self._parse_input_message_for_step(
|
|
266
|
+
request.input_message
|
|
267
|
+
)
|
|
268
|
+
format_cls = self._resolve_response_format_for_step(
|
|
269
|
+
request.response_format
|
|
270
|
+
)
|
|
271
|
+
|
|
272
|
+
try:
|
|
273
|
+
response = await agent.astep(
|
|
274
|
+
input_message=input_message, response_format=format_cls
|
|
275
|
+
)
|
|
276
|
+
return response.model_dump()
|
|
277
|
+
except Exception as e:
|
|
278
|
+
raise HTTPException(
|
|
279
|
+
status_code=500,
|
|
280
|
+
detail=f"Unexpected error during async step: {e!s}",
|
|
281
|
+
)
|
|
282
|
+
|
|
283
|
+
@router.get("/list_agent_ids")
|
|
284
|
+
def list_agent_ids():
|
|
285
|
+
r"""Returns a list of all active agent IDs.
|
|
286
|
+
|
|
287
|
+
Returns:
|
|
288
|
+
dict: A dictionary containing all registered agent IDs.
|
|
289
|
+
"""
|
|
290
|
+
return {"agent_ids": list(self.agents.keys())}
|
|
291
|
+
|
|
292
|
+
@router.post("/delete/{agent_id}")
|
|
293
|
+
def delete_agent(agent_id: str):
|
|
294
|
+
r"""Deletes an agent from the server.
|
|
295
|
+
|
|
296
|
+
Args:
|
|
297
|
+
agent_id (str): The ID of the agent to delete.
|
|
298
|
+
|
|
299
|
+
Returns:
|
|
300
|
+
dict: A confirmation message upon successful deletion.
|
|
301
|
+
"""
|
|
302
|
+
if agent_id not in self.agents:
|
|
303
|
+
raise HTTPException(status_code=404, detail="Agent not found.")
|
|
304
|
+
|
|
305
|
+
del self.agents[agent_id]
|
|
306
|
+
return {"message": f"Agent {agent_id} deleted."}
|
|
307
|
+
|
|
308
|
+
@router.post("/step/{agent_id}")
|
|
309
|
+
def step_agent(agent_id: str, request: StepRequest):
|
|
310
|
+
r"""Runs one step of synchronous agent response.
|
|
311
|
+
|
|
312
|
+
Args:
|
|
313
|
+
agent_id (str): The ID of the target agent.
|
|
314
|
+
request (StepRequest): The input message.
|
|
315
|
+
|
|
316
|
+
Returns:
|
|
317
|
+
dict: The model response in serialized form.
|
|
318
|
+
"""
|
|
319
|
+
if agent_id not in self.agents:
|
|
320
|
+
raise HTTPException(status_code=404, detail="Agent not found.")
|
|
321
|
+
|
|
322
|
+
agent = self.agents[agent_id]
|
|
323
|
+
input_message = self._parse_input_message_for_step(
|
|
324
|
+
request.input_message
|
|
325
|
+
)
|
|
326
|
+
format_cls = self._resolve_response_format_for_step(
|
|
327
|
+
request.response_format
|
|
328
|
+
)
|
|
329
|
+
try:
|
|
330
|
+
response = agent.step(
|
|
331
|
+
input_message=input_message, response_format=format_cls
|
|
332
|
+
)
|
|
333
|
+
return response.model_dump()
|
|
334
|
+
except Exception as e:
|
|
335
|
+
raise HTTPException(
|
|
336
|
+
status_code=500,
|
|
337
|
+
detail=f"Unexpected error during step: {e!s}",
|
|
338
|
+
)
|
|
339
|
+
|
|
340
|
+
@router.post("/reset/{agent_id}")
|
|
341
|
+
def reset_agent(agent_id: str):
|
|
342
|
+
r"""Clears memory for a specific agent.
|
|
343
|
+
|
|
344
|
+
Args:
|
|
345
|
+
agent_id (str): The ID of the agent to reset.
|
|
346
|
+
|
|
347
|
+
Returns:
|
|
348
|
+
dict: A message confirming reset success.
|
|
349
|
+
"""
|
|
350
|
+
if agent_id not in self.agents:
|
|
351
|
+
raise HTTPException(status_code=404, detail="Agent not found.")
|
|
352
|
+
self.agents[agent_id].reset()
|
|
353
|
+
return {"message": f"Agent {agent_id} reset."}
|
|
354
|
+
|
|
355
|
+
@router.get("/history/{agent_id}")
|
|
356
|
+
def get_agent_chat_history(agent_id: str):
|
|
357
|
+
r"""Returns the chat history of an agent.
|
|
358
|
+
|
|
359
|
+
Args:
|
|
360
|
+
agent_id (str): The ID of the agent to query.
|
|
361
|
+
|
|
362
|
+
Returns:
|
|
363
|
+
list: The list of conversation messages.
|
|
364
|
+
"""
|
|
365
|
+
if agent_id not in self.agents:
|
|
366
|
+
raise HTTPException(
|
|
367
|
+
status_code=404, detail=f"Agent {agent_id} not found."
|
|
368
|
+
)
|
|
369
|
+
return self.agents[agent_id].chat_history
|
|
370
|
+
|
|
371
|
+
# Register all routes to the main FastAPI app
|
|
372
|
+
self.app.include_router(router)
|
|
373
|
+
|
|
374
|
+
def get_app(self) -> FastAPI:
|
|
375
|
+
r"""Returns the FastAPI app instance.
|
|
376
|
+
|
|
377
|
+
Returns:
|
|
378
|
+
FastAPI: The wrapped application object.
|
|
379
|
+
"""
|
|
380
|
+
return self.app
|
camel/societies/__init__.py
CHANGED
|
@@ -13,8 +13,10 @@
|
|
|
13
13
|
# ========= Copyright 2023-2024 @ CAMEL-AI.org. All Rights Reserved. =========
|
|
14
14
|
from .babyagi_playing import BabyAGI
|
|
15
15
|
from .role_playing import RolePlaying
|
|
16
|
+
from .workforce import Workforce
|
|
16
17
|
|
|
17
18
|
__all__ = [
|
|
18
19
|
'RolePlaying',
|
|
19
20
|
'BabyAGI',
|
|
21
|
+
'Workforce',
|
|
20
22
|
]
|