Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
23 changes: 22 additions & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -336,6 +336,7 @@ You can set environment variables directly in your terminal:
```bash
export OPENAI_API_KEY="your-openai-api-key-here"
# Add other required API keys as needed
export ATLASCLOUD_API_KEY="your-atlascloud-api-key-here"
```

- **Windows (Command Prompt)**:
Expand Down Expand Up @@ -372,7 +373,27 @@ If you prefer using a `.env` file instead, you can:
2. **Configure Your API Keys**:
Open the `.env` file in your preferred text editor and insert your API keys in the corresponding fields.

AtlasCloud's OpenAI-compatible LLM endpoint requires the `/v1` suffix:

```bash
ATLASCLOUD_API_KEY="your-atlascloud-api-key-here"
ATLASCLOUD_API_BASE_URL="https://api.atlascloud.ai/v1"
ATLASCLOUD_MODEL_NAME="deepseek-ai/DeepSeek-V3-0324"
```

> **Note**: For the minimal example (`examples/run_mini.py`), you only need to configure the LLM API key (e.g., `OPENAI_API_KEY`).
> 🎁 **[Atlas Cloud](https://www.atlascloud.ai/?utm_source=github&utm_medium=link&utm_campaign=owl)** is a full-modal AI inference platform that gives developers a single AI API to access video generation, image generation, and LLM APIs. Instead of managing multiple vendor integrations, you connect once and get unified access to 300+ curated models across all modalities.
>
> Check out Atlas Cloud's new coding plan promotion for more budget-friendly API access: [https://www.atlascloud.ai/console/coding-plan](https://www.atlascloud.ai/console/coding-plan)

Validated Atlas chat model pool for `ATLASCLOUD_MODEL_NAME`:

- `deepseek-ai/DeepSeek-V3-0324`, `deepseek-ai/deepseek-r1-0528`, `moonshotai/Kimi-K2-Instruct`, `Qwen/Qwen3-Coder`, `Qwen/Qwen3-235B-A22B-Instruct-2507`, `deepseek-ai/DeepSeek-V3.1`, `moonshotai/Kimi-K2-Instruct-0905`, `Qwen/Qwen3-Next-80B-A3B-Instruct`, `Qwen/Qwen3-Next-80B-A3B-Thinking`, `Qwen/Qwen3-30B-A3B-Instruct-2507`
- `deepseek-ai/DeepSeek-V3.1-Terminus`, `deepseek-ai/DeepSeek-V3.2-Exp`, `zai-org/GLM-4.6`, `MiniMaxAI/MiniMax-M2`, `Qwen/Qwen3-VL-235B-A22B-Instruct`, `moonshotai/Kimi-K2-Thinking`, `google/gemini-2.5-flash`, `google/gemini-2.5-flash-lite`, `openai/gpt-5.1`, `openai/gpt-5.1-chat`
- `openai/gpt-4o`, `openai/gpt-4o-mini`, `openai/gpt-4.1`, `openai/gpt-4.1-mini`, `openai/gpt-4.1-nano`, `openai/o1`, `openai/o3`, `openai/o3-mini`, `openai/o4-mini`, `anthropic/claude-sonnet-4.5-20250929`
- `deepseek-ai/deepseek-v3.2`, `openai/gpt-5`, `openai/gpt-5-chat`, `openai/gpt-5-mini`, `openai/gpt-5-nano`, `openai/gpt-5.2`, `openai/gpt-5.2-chat`, `google/gemini-2.5-pro`, `anthropic/claude-opus-4.5-20251101`, `google/gemini-3-flash-preview`
- `zai-org/glm-4.7`, `minimaxai/minimax-m2.1`, `google/gemini-2.0-flash`, `qwen/qwen3-8b`, `qwen/qwen3-235b-a22b-thinking-2507`, `qwen/qwen3-vl-235b-a22b-thinking`, `qwen/qwen3-30b-a3b`, `qwen/qwen3-30b-a3b-thinking-2507`, `deepseek-ai/deepseek-ocr`, `xai/grok-4-0709`


### **MCP Desktop Commander Setup**

Expand Down Expand Up @@ -421,7 +442,7 @@ python examples/run_qwen_zh.py
python examples/run_deepseek_zh.py

# Run with other OpenAI-compatible models
python examples/run_openai_compatible_model.py
python examples/run_atlascloud.py

# Run with Gemini model
python examples/run_gemini.py
Expand Down
20 changes: 20 additions & 0 deletions README_ja.md
Original file line number Diff line number Diff line change
Expand Up @@ -262,6 +262,26 @@ OWLは、さまざまなサービスと対話するために複数のAPIキー

> **注意**:最小限の例(`examples/run_mini.py`)の場合、LLM APIキー(例:`OPENAI_API_KEY`)のみを設定する必要があります。

Atlas Cloud の OpenAI 互換 LLM エンドポイントでは `/v1` サフィックスが必要です:

```bash
ATLASCLOUD_API_KEY="your-atlascloud-api-key-here"
ATLASCLOUD_API_BASE_URL="https://api.atlascloud.ai/v1"
ATLASCLOUD_MODEL_NAME="deepseek-ai/DeepSeek-V3-0324"
```

> 🎁 **[Atlas Cloud](https://www.atlascloud.ai/?utm_source=github&utm_medium=link&utm_campaign=owl)** は、動画生成、画像生成、LLM API を単一の統合 API で利用できるフルモーダル AI 推論プラットフォームです。
>
> 最新のコーディングプラン特典はこちら:https://www.atlascloud.ai/console/coding-plan

`ATLASCLOUD_MODEL_NAME` 向けに検証済みの Atlas `50` モデルプール:

- `deepseek-ai/DeepSeek-V3-0324`, `deepseek-ai/deepseek-r1-0528`, `moonshotai/Kimi-K2-Instruct`, `Qwen/Qwen3-Coder`, `Qwen/Qwen3-235B-A22B-Instruct-2507`, `deepseek-ai/DeepSeek-V3.1`, `moonshotai/Kimi-K2-Instruct-0905`, `Qwen/Qwen3-Next-80B-A3B-Instruct`, `Qwen/Qwen3-Next-80B-A3B-Thinking`, `Qwen/Qwen3-30B-A3B-Instruct-2507`
- `deepseek-ai/DeepSeek-V3.1-Terminus`, `deepseek-ai/DeepSeek-V3.2-Exp`, `zai-org/GLM-4.6`, `MiniMaxAI/MiniMax-M2`, `Qwen/Qwen3-VL-235B-A22B-Instruct`, `moonshotai/Kimi-K2-Thinking`, `google/gemini-2.5-flash`, `google/gemini-2.5-flash-lite`, `openai/gpt-5.1`, `openai/gpt-5.1-chat`
- `openai/gpt-4o`, `openai/gpt-4o-mini`, `openai/gpt-4.1`, `openai/gpt-4.1-mini`, `openai/gpt-4.1-nano`, `openai/o1`, `openai/o3`, `openai/o3-mini`, `openai/o4-mini`, `anthropic/claude-sonnet-4.5-20250929`
- `deepseek-ai/deepseek-v3.2`, `openai/gpt-5`, `openai/gpt-5-chat`, `openai/gpt-5-mini`, `openai/gpt-5-nano`, `openai/gpt-5.2`, `openai/gpt-5.2-chat`, `google/gemini-2.5-pro`, `anthropic/claude-opus-4.5-20251101`, `google/gemini-3-flash-preview`
- `zai-org/glm-4.7`, `minimaxai/minimax-m2.1`, `google/gemini-2.0-flash`, `qwen/qwen3-8b`, `qwen/qwen3-235b-a22b-thinking-2507`, `qwen/qwen3-vl-235b-a22b-thinking`, `qwen/qwen3-30b-a3b`, `qwen/qwen3-30b-a3b-thinking-2507`, `deepseek-ai/deepseek-ocr`, `xai/grok-4-0709`

### オプション2:環境変数を直接設定

または、ターミナルで環境変数を直接設定することもできます:
Expand Down
20 changes: 20 additions & 0 deletions README_zh.md
Original file line number Diff line number Diff line change
Expand Up @@ -259,6 +259,26 @@ OWL 需要各种 API 密钥来与不同的服务进行交互。`owl/.env_templat

> **注意**:对于最小示例(`examples/run_mini.py`),你只需要配置 LLM API 密钥(例如,`OPENAI_API_KEY`)。

Atlas Cloud 的 OpenAI 兼容 LLM 端点需要保留 `/v1` 后缀:

```bash
ATLASCLOUD_API_KEY="your-atlascloud-api-key-here"
ATLASCLOUD_API_BASE_URL="https://api.atlascloud.ai/v1"
ATLASCLOUD_MODEL_NAME="deepseek-ai/DeepSeek-V3-0324"
```

> 🎁 **[Atlas Cloud](https://www.atlascloud.ai/?utm_source=github&utm_medium=link&utm_campaign=owl)** 是一个全模态 AI 推理平台,开发者通过一个统一 API 即可访问视频生成、图像生成和 LLM API,无需维护多家厂商接入。
>
> 可查看 Atlas Cloud 最新编程计划优惠活动:https://www.atlascloud.ai/console/coding-plan

`ATLASCLOUD_MODEL_NAME` 已验证可用的 Atlas `50` 个聊天模型池:

- `deepseek-ai/DeepSeek-V3-0324`, `deepseek-ai/deepseek-r1-0528`, `moonshotai/Kimi-K2-Instruct`, `Qwen/Qwen3-Coder`, `Qwen/Qwen3-235B-A22B-Instruct-2507`, `deepseek-ai/DeepSeek-V3.1`, `moonshotai/Kimi-K2-Instruct-0905`, `Qwen/Qwen3-Next-80B-A3B-Instruct`, `Qwen/Qwen3-Next-80B-A3B-Thinking`, `Qwen/Qwen3-30B-A3B-Instruct-2507`
- `deepseek-ai/DeepSeek-V3.1-Terminus`, `deepseek-ai/DeepSeek-V3.2-Exp`, `zai-org/GLM-4.6`, `MiniMaxAI/MiniMax-M2`, `Qwen/Qwen3-VL-235B-A22B-Instruct`, `moonshotai/Kimi-K2-Thinking`, `google/gemini-2.5-flash`, `google/gemini-2.5-flash-lite`, `openai/gpt-5.1`, `openai/gpt-5.1-chat`
- `openai/gpt-4o`, `openai/gpt-4o-mini`, `openai/gpt-4.1`, `openai/gpt-4.1-mini`, `openai/gpt-4.1-nano`, `openai/o1`, `openai/o3`, `openai/o3-mini`, `openai/o4-mini`, `anthropic/claude-sonnet-4.5-20250929`
- `deepseek-ai/deepseek-v3.2`, `openai/gpt-5`, `openai/gpt-5-chat`, `openai/gpt-5-mini`, `openai/gpt-5-nano`, `openai/gpt-5.2`, `openai/gpt-5.2-chat`, `google/gemini-2.5-pro`, `anthropic/claude-opus-4.5-20251101`, `google/gemini-3-flash-preview`
- `zai-org/glm-4.7`, `minimaxai/minimax-m2.1`, `google/gemini-2.0-flash`, `qwen/qwen3-8b`, `qwen/qwen3-235b-a22b-thinking-2507`, `qwen/qwen3-vl-235b-a22b-thinking`, `qwen/qwen3-30b-a3b`, `qwen/qwen3-30b-a3b-thinking-2507`, `deepseek-ai/deepseek-ocr`, `xai/grok-4-0709`

### 选项 2:直接设置环境变量

或者,你可以直接在终端中设置环境变量:
Expand Down
232 changes: 232 additions & 0 deletions examples/run_atlascloud.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,232 @@
#!/usr/bin/env python3
# ========= Copyright 2023-2024 @ CAMEL-AI.org. All Rights Reserved. =========
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# ========= Copyright 2023-2024 @ CAMEL-AI.org. All Rights Reserved. =========

"""
Workforce example using AtlasCloud's OpenAI-compatible LLM endpoint.

AtlasCloud exposes an OpenAI-compatible chat completions API at:
https://api.atlascloud.ai/v1

Configuration priority:
1. ATLASCLOUD_API_KEY environment variable

Optional environment variables:
- ATLASCLOUD_API_BASE_URL (default: https://api.atlascloud.ai/v1)
- ATLASCLOUD_MODEL_NAME (default: deepseek-ai/DeepSeek-V3-0324)

Run with:
python examples/run_atlascloud.py
python examples/run_atlascloud.py "Your task here"
"""

import os
import sys
import pathlib
from typing import Any, Dict, List

from dotenv import load_dotenv

from camel.agents import ChatAgent
from camel.logger import set_log_level
from camel.models import ModelFactory
from camel.societies import Workforce
from camel.tasks.task import Task
from camel.toolkits import (
BrowserToolkit,
CodeExecutionToolkit,
ExcelToolkit,
FileToolkit,
FunctionTool,
SearchToolkit,
)
from camel.types import ModelPlatformType

from owl.utils import DocumentProcessingToolkit

ATLAS_BASE_URL = "https://api.atlascloud.ai/v1"
ATLAS_MODEL_NAME = "deepseek-ai/DeepSeek-V3-0324"

BASE_DIR = pathlib.Path(__file__).parent.parent
ENV_PATH = BASE_DIR / "owl" / ".env"

load_dotenv(dotenv_path=str(ENV_PATH))
set_log_level(level="DEBUG")


def load_atlascloud_api_key() -> str | None:
"""Load AtlasCloud API key from environment variables."""
api_key = os.getenv("ATLASCLOUD_API_KEY")
if api_key:
return api_key.strip()

return None


def get_atlascloud_config() -> tuple[str, str, str]:
"""Return AtlasCloud base URL, API key, and model name."""
api_url = os.getenv("ATLASCLOUD_API_BASE_URL", ATLAS_BASE_URL).strip()
model_name = os.getenv("ATLASCLOUD_MODEL_NAME", ATLAS_MODEL_NAME).strip()
api_key = load_atlascloud_api_key()

if not api_key:
raise ValueError(
"Missing AtlasCloud API key. Set ATLASCLOUD_API_KEY in your "
"environment or owl/.env file."
)

return api_url, api_key, model_name


def create_atlas_model():
"""Create an OpenAI-compatible model backed by AtlasCloud."""
api_url, api_key, model_name = get_atlascloud_config()
return ModelFactory.create(
model_platform=ModelPlatformType.OPENAI_COMPATIBLE_MODEL,
model_type=model_name,
url=api_url,
api_key=api_key,
model_config_dict={"temperature": 0},
)


def construct_agent_list() -> List[Dict[str, Any]]:
"""Construct a list of agents with AtlasCloud-backed model instances."""
web_model = create_atlas_model()
document_processing_model = create_atlas_model()
reasoning_model = create_atlas_model()
browsing_model = create_atlas_model()
planning_model = create_atlas_model()

search_toolkit = SearchToolkit()
document_processing_toolkit = DocumentProcessingToolkit(
model=document_processing_model
)
code_runner_toolkit = CodeExecutionToolkit(sandbox="subprocess", verbose=True)
file_toolkit = FileToolkit()
excel_toolkit = ExcelToolkit()
browser_toolkit = BrowserToolkit(
headless=False,
web_agent_model=browsing_model,
planning_agent_model=planning_model,
)

web_agent = ChatAgent(
"""You are a helpful assistant that can search the web, extract webpage content, simulate browser actions, and provide relevant information to solve the given task.
Keep in mind that:
- Do not be overly confident in your own knowledge. Searching can provide a broader perspective and help validate existing knowledge.
- If one way fails to provide an answer, try other ways or methods. The answer does exist.
- If the search snippet is unhelpful but the URL comes from an authoritative source, try visit the website for more details.
- When looking for specific numerical values (e.g., dollar amounts), prioritize reliable sources and avoid relying only on search snippets.
- When solving tasks that require web searches, check Wikipedia first before exploring other websites.
- You can also simulate browser actions to get more information or verify the information you have found.
- Browser simulation is also helpful for finding target URLs. Browser simulation operations do not necessarily need to find specific answers, but can also help find web page URLs that contain answers (usually difficult to find through simple web searches). You can find the answer to the question by performing subsequent operations on the URL, such as extracting the content of the webpage.
- Do not solely rely on document tools or browser simulation to find the answer, you should combine document tools and browser simulation to comprehensively process web page information. Some content may need to do browser simulation to get, or some content is rendered by javascript.
- In your response, you should mention the urls you have visited and processed.

Here are some tips that help you perform web search:
- Never add too many keywords in your search query! Some detailed results need to perform browser interaction to get, not using search toolkit.
- If the question is complex, search results typically do not provide precise answers. It is not likely to find the answer directly using search toolkit only, the search query should be concise and focuses on finding official sources rather than direct answers.
- The results you return do not have to directly answer the original question, you only need to collect relevant information.
""",
model=web_model,
tools=[
FunctionTool(search_toolkit.search_duckduckgo),
FunctionTool(search_toolkit.search_wiki),
FunctionTool(document_processing_toolkit.extract_document_content),
*browser_toolkit.get_tools(),
],
)

document_processing_agent = ChatAgent(
"You are a helpful assistant that can process documents and multimodal data, and can interact with file system.",
document_processing_model,
tools=[
FunctionTool(document_processing_toolkit.extract_document_content),
FunctionTool(code_runner_toolkit.execute_code),
*file_toolkit.get_tools(),
],
)

reasoning_coding_agent = ChatAgent(
"You are a helpful assistant that specializes in reasoning and coding, and can think step by step to solve the task. When necessary, you can write python code to solve the task. If you have written code, do not forget to execute the code. Never generate codes like 'example code', your code should be able to fully solve the task. You can also leverage multiple libraries, such as requests, BeautifulSoup, re, pandas, etc, to solve the task. For processing excel files, you should write codes to process them.",
reasoning_model,
tools=[
FunctionTool(code_runner_toolkit.execute_code),
FunctionTool(excel_toolkit.extract_excel_content),
FunctionTool(document_processing_toolkit.extract_document_content),
],
)

return [
{
"name": "Web Agent",
"description": "A helpful assistant that can search the web, extract webpage content, and retrieve relevant information.",
"agent": web_agent,
},
{
"name": "Document Processing Agent",
"description": "A helpful assistant that can process a variety of local and remote documents, including pdf, docx, images, audio, and video, etc.",
"agent": document_processing_agent,
},
{
"name": "Reasoning Coding Agent",
"description": "A helpful assistant that specializes in reasoning, coding, and processing excel files. However, it cannot access the internet to search for information. If the task requires python execution, it should be informed to execute the code after writing it.",
"agent": reasoning_coding_agent,
},
]


def construct_workforce() -> Workforce:
"""Construct a workforce with coordinator and task agents."""
task_agent = ChatAgent(
"You are a helpful assistant that can decompose tasks and assign tasks to workers.",
model=create_atlas_model(),
)
coordinator_agent = ChatAgent(
"You are a helpful assistant that can assign tasks to workers.",
model=create_atlas_model(),
)

workforce = Workforce(
"Workforce",
task_agent=task_agent,
coordinator_agent=coordinator_agent,
)

for agent_dict in construct_agent_list():
workforce.add_single_agent_worker(
agent_dict["description"],
worker=agent_dict["agent"],
)

return workforce


def main():
r"""Main function to run OWL with AtlasCloud as the provider."""
default_task_prompt = (
"Summarize the github stars, fork counts, and recent activity of camel-ai "
"owl, then save the result as a local markdown file."
)
task_prompt = sys.argv[1] if len(sys.argv) > 1 else default_task_prompt

task = Task(content=task_prompt)
workforce = construct_workforce()
processed_task = workforce.process_task(task)
print(f"\033[94mAnswer: {processed_task.result}\033[0m")


if __name__ == "__main__":
main()
6 changes: 5 additions & 1 deletion owl/.env_template
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,10 @@
OPENAI_API_KEY="Your_Key"
# OPENAI_API_BASE_URL=""

# AtlasCloud API (https://www.atlascloud.ai/docs/get-started)
# ATLASCLOUD_API_KEY="Your_Key"
# ATLASCLOUD_API_BASE_URL="https://api.atlascloud.ai/v1"
# ATLASCLOUD_MODEL_NAME="deepseek-ai/DeepSeek-V3-0324"

# Qwen API (https://help.aliyun.com/zh/model-studio/developer-reference/get-api-key)
# QWEN_API_KEY="Your_Key"
Expand Down Expand Up @@ -48,4 +52,4 @@ CHUNKR_API_KEY="Your_Key"

# Firecrawl API (https://www.firecrawl.dev/)
FIRECRAWL_API_KEY="Your_Key"
#FIRECRAWL_API_URL="https://api.firecrawl.dev"
#FIRECRAWL_API_URL="https://api.firecrawl.dev"
Loading