-
Notifications
You must be signed in to change notification settings - Fork 821
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
Merge pull request #133 from Mac0q/jiaxu_dev
append claude method
- Loading branch information
Showing
8 changed files
with
182 additions
and
2 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,29 @@ | ||
# Google Gemini | ||
|
||
## Step 1 | ||
To use the Claude API, you need to create an account on the [Claude website](https://www.anthropic.com/) and access the API key. | ||
|
||
## Step 2 | ||
You may need to install additional dependencies to use the Claude API. You can install the dependencies using the following command: | ||
|
||
```bash | ||
pip install -U anthropic==0.37.1 | ||
``` | ||
|
||
## Step 3 | ||
Configure the `HOST_AGENT` and `APP_AGENT` in the `config.yaml` file (rename the `config_template.yaml` file to `config.yaml`) to use the Claude API. The following is an example configuration for the Claude API: | ||
|
||
```yaml | ||
VISUAL_MODE: True, # Whether to use visual mode to understand screenshots and take actions | ||
API_TYPE: "Claude" , | ||
API_KEY: "YOUR_KEY", | ||
API_MODEL: "YOUR_MODEL" | ||
``` | ||
!!! tip | ||
If you set `VISUAL_MODE` to `True`, make sure the `API_MODEL` supports visual inputs. | ||
!!! tip | ||
`API_MODEL` is the model name of Claude LLM API. You can find the model name in the [Claude LLM model](https://www.anthropic.com/##anthropic-api) list. | ||
|
||
## Step 4 | ||
After configuring the `HOST_AGENT` and `APP_AGENT` with the Claude API, you can start using UFO to interact with the Claude API for various tasks on Windows OS. Please refer to the [Quick Start Guide](../getting_started/quick_start.md) for more details on how to get started with UFO. |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,127 @@ | ||
import re | ||
import time | ||
from typing import Any, Dict, List, Optional, Tuple | ||
|
||
import anthropic | ||
from PIL import Image | ||
|
||
from ufo.llm.base import BaseService | ||
from ufo.utils import print_with_color | ||
|
||
|
||
class ClaudeService(BaseService): | ||
""" | ||
A service class for Claude models. | ||
""" | ||
|
||
def __init__(self, config: Dict[str, Any], agent_type: str): | ||
""" | ||
Initialize the Gemini service. | ||
:param config: The configuration. | ||
:param agent_type: The agent type. | ||
""" | ||
self.config_llm = config[agent_type] | ||
self.config = config | ||
self.model = self.config_llm["API_MODEL"] | ||
self.prices = self.config["PRICES"] | ||
self.max_retry = self.config["MAX_RETRY"] | ||
self.api_type = self.config_llm["API_TYPE"].lower() | ||
self.client = anthropic.Anthropic(api_key=self.config_llm["API_KEY"]) | ||
|
||
def chat_completion( | ||
self, | ||
messages: List[Dict[str, str]], | ||
n: int = 1, | ||
temperature: Optional[float] = None, | ||
max_tokens: Optional[int] = None, | ||
top_p: Optional[float] = None, | ||
**kwargs: Any, | ||
) -> Any: | ||
""" | ||
Generates completions for a given list of messages. | ||
:param messages: The list of messages to generate completions for. | ||
:param n: The number of completions to generate for each message. | ||
:param temperature: Controls the randomness of the generated completions. Higher values (e.g., 0.8) make the completions more random, while lower values (e.g., 0.2) make the completions more focused and deterministic. If not provided, the default value from the model configuration will be used. | ||
:param max_tokens: The maximum number of tokens in the generated completions. If not provided, the default value from the model configuration will be used. | ||
:param top_p: Controls the diversity of the generated completions. Higher values (e.g., 0.8) make the completions more diverse, while lower values (e.g., 0.2) make the completions more focused. If not provided, the default value from the model configuration will be used. | ||
:param kwargs: Additional keyword arguments to be passed to the underlying completion method. | ||
:return: A list of generated completions for each message and the cost set to be None. | ||
""" | ||
|
||
temperature = ( | ||
temperature if temperature is not None else self.config["TEMPERATURE"] | ||
) | ||
top_p = top_p if top_p is not None else self.config["TOP_P"] | ||
max_tokens = max_tokens if max_tokens is not None else self.config["MAX_TOKENS"] | ||
|
||
responses = [] | ||
cost = 0.0 | ||
system_prompt, user_prompt = self.process_messages(messages) | ||
|
||
for _ in range(n): | ||
for _ in range(self.max_retry): | ||
try: | ||
response = self.client.messages.create( | ||
max_tokens=max_tokens, | ||
model=self.model, | ||
system=system_prompt, | ||
messages=user_prompt, | ||
) | ||
responses.append(response.content.text) | ||
prompt_tokens = response.usage.input_tokens | ||
completion_tokens = response.usage.output_tokens | ||
cost += self.get_cost_estimator( | ||
self.api_type, | ||
self.model, | ||
self.prices, | ||
prompt_tokens, | ||
completion_tokens, | ||
) | ||
except Exception as e: | ||
print_with_color(f"Error making API request: {e}", "red") | ||
try: | ||
print_with_color(response, "red") | ||
except: | ||
_ | ||
time.sleep(3) | ||
continue | ||
|
||
return responses, cost | ||
|
||
def process_messages(self, messages: List[Dict[str, str]]) -> Tuple[str, Dict]: | ||
""" | ||
Processes the messages to generate the system and user prompts. | ||
:param messages: A list of message dictionaries. | ||
:return: A tuple containing the system prompt (str) and the user prompt (dict). | ||
""" | ||
|
||
system_prompt = "" | ||
user_prompt = {"role": "user", "content": []} | ||
if isinstance(messages, dict): | ||
messages = [messages] | ||
for message in messages: | ||
if message["role"] == "system": | ||
system_prompt = message["content"] | ||
else: | ||
for content in message["content"]: | ||
if content["type"] == "text": | ||
user_prompt["content"].append(content) | ||
elif content["type"] == "image_url": | ||
data_url = content["image_url"]["url"] | ||
match = re.match(r"data:(.*?);base64,(.*)", data_url) | ||
if match: | ||
media_type = match.group(1) | ||
base64_data = match.group(2) | ||
user_prompt["content"].append( | ||
{ | ||
"type": "image", | ||
"source": { | ||
"type": "base64", | ||
"media_type": media_type, | ||
"base64_data": base64_data, | ||
}, | ||
} | ||
) | ||
else: | ||
raise ValueError("Invalid image URL") | ||
return system_prompt, user_prompt |