update README and format code
This commit is contained in:
parent
737abe4f90
commit
487b44fda8
@ -143,6 +143,9 @@ Join our networking group on Feishu and share your experience with other develop
|
||||
Thanks to [anthropic-computer-use](https://github.com/anthropics/anthropic-quickstarts/tree/main/computer-use-demo)
|
||||
and [browser-use](https://github.com/browser-use/browser-use) for providing basic support for this project!
|
||||
|
||||
Additionally, we are grateful to [AAAJ](https://github.com/metauto-ai/agent-as-a-judge)
|
||||
and [MetaGPT](https://github.com/mannaandpoem/MetaGPT).
|
||||
|
||||
OpenManus is built by contributors from MetaGPT. Huge thanks to this agent community!
|
||||
|
||||
## Cite
|
||||
|
@ -145,4 +145,7 @@ python run_flow.py
|
||||
特别感谢 [anthropic-computer-use](https://github.com/anthropics/anthropic-quickstarts/tree/main/computer-use-demo)
|
||||
和 [browser-use](https://github.com/browser-use/browser-use) 为本项目提供的基础支持!
|
||||
|
||||
此外,我们感谢 [AAAJ](https://github.com/metauto-ai/agent-as-a-judge)
|
||||
和 [MetaGPT](https://github.com/mannaandpoem/MetaGPT).
|
||||
|
||||
OpenManus 由 MetaGPT 社区的贡献者共同构建,感谢这个充满活力的智能体开发者社区!
|
||||
|
@ -1,6 +1,6 @@
|
||||
from typing import Dict, List, Literal, Optional, Union, Tuple, Any
|
||||
import os
|
||||
import base64
|
||||
import os
|
||||
from typing import Any, Dict, List, Literal, Optional, Tuple, Union
|
||||
|
||||
import litellm
|
||||
from litellm import completion, completion_cost
|
||||
@ -9,12 +9,17 @@ from litellm.exceptions import (
|
||||
RateLimitError,
|
||||
ServiceUnavailableError,
|
||||
)
|
||||
from tenacity import retry, stop_after_attempt, wait_random_exponential, retry_if_exception_type
|
||||
from tenacity import (
|
||||
retry,
|
||||
retry_if_exception_type,
|
||||
stop_after_attempt,
|
||||
wait_random_exponential,
|
||||
)
|
||||
|
||||
from app.config import LLMSettings, config
|
||||
from app.llm.cost import Cost
|
||||
from app.logger import logger
|
||||
from app.schema import Message
|
||||
from app.llm.cost import Cost
|
||||
|
||||
|
||||
class LLM:
|
||||
@ -32,7 +37,9 @@ class LLM:
|
||||
def __init__(
|
||||
self, config_name: str = "default", llm_config: Optional[LLMSettings] = None
|
||||
):
|
||||
if not hasattr(self, "initialized"): # Only initialize if not already initialized
|
||||
if not hasattr(
|
||||
self, "initialized"
|
||||
): # Only initialize if not already initialized
|
||||
llm_config = llm_config or config.llm
|
||||
llm_config = llm_config.get(config_name, llm_config["default"])
|
||||
|
||||
@ -41,7 +48,9 @@ class LLM:
|
||||
self.temperature = getattr(llm_config, "temperature", 0.7)
|
||||
self.top_p = getattr(llm_config, "top_p", 0.9)
|
||||
self.api_type = getattr(llm_config, "api_type", "openai")
|
||||
self.api_key = getattr(llm_config, "api_key", os.environ.get("OPENAI_API_KEY", ""))
|
||||
self.api_key = getattr(
|
||||
llm_config, "api_key", os.environ.get("OPENAI_API_KEY", "")
|
||||
)
|
||||
self.api_version = getattr(llm_config, "api_version", "")
|
||||
self.base_url = getattr(llm_config, "base_url", "https://api.openai.com/v1")
|
||||
self.timeout = getattr(llm_config, "timeout", 60)
|
||||
@ -183,7 +192,9 @@ class LLM:
|
||||
# Add the cost to our tracker
|
||||
if cost > 0:
|
||||
self.cost_tracker.add_cost(cost)
|
||||
logger.info(f"Added cost: ${cost:.6f}, Total: ${self.cost_tracker.accumulated_cost:.6f}")
|
||||
logger.info(
|
||||
f"Added cost: ${cost:.6f}, Total: ${self.cost_tracker.accumulated_cost:.6f}"
|
||||
)
|
||||
|
||||
return cost
|
||||
except Exception as e:
|
||||
@ -202,7 +213,9 @@ class LLM:
|
||||
substring in self.base_url
|
||||
for substring in ["localhost", "127.0.0.1", "0.0.0.0"]
|
||||
)
|
||||
if self.model and (self.model.startswith("ollama") or "local" in self.model.lower()):
|
||||
if self.model and (
|
||||
self.model.startswith("ollama") or "local" in self.model.lower()
|
||||
):
|
||||
return True
|
||||
return False
|
||||
|
||||
@ -234,7 +247,9 @@ class LLM:
|
||||
with open(image_path, "rb") as image_file:
|
||||
return base64.b64encode(image_file.read()).decode("utf-8")
|
||||
|
||||
def prepare_messages(self, text: str, image_path: Optional[str] = None) -> List[dict]:
|
||||
def prepare_messages(
|
||||
self, text: str, image_path: Optional[str] = None
|
||||
) -> List[dict]:
|
||||
"""
|
||||
Prepare messages for completion, including multimodal content if needed.
|
||||
|
||||
@ -257,7 +272,9 @@ class LLM:
|
||||
]
|
||||
return messages
|
||||
|
||||
def do_multimodal_completion(self, text: str, image_path: str) -> Tuple[Any, float, float]:
|
||||
def do_multimodal_completion(
|
||||
self, text: str, image_path: str
|
||||
) -> Tuple[Any, float, float]:
|
||||
"""
|
||||
Perform a multimodal completion with text and image.
|
||||
|
||||
@ -342,7 +359,7 @@ class LLM:
|
||||
print(chunk_message, end="", flush=True)
|
||||
|
||||
# For streaming responses, cost is calculated on the last chunk
|
||||
if hasattr(chunk, 'usage') and chunk.usage:
|
||||
if hasattr(chunk, "usage") and chunk.usage:
|
||||
self._calculate_and_track_cost(chunk)
|
||||
|
||||
print() # Newline after streaming
|
||||
@ -484,6 +501,7 @@ class LLM:
|
||||
if __name__ == "__main__":
|
||||
# Load environment variables if needed
|
||||
from dotenv import load_dotenv
|
||||
|
||||
load_dotenv()
|
||||
|
||||
# Create LLM instance
|
||||
@ -501,5 +519,7 @@ if __name__ == "__main__":
|
||||
multimodal_response, mm_cost, mm_total_cost = llm.do_multimodal_completion(
|
||||
"What's in this image?", image_path
|
||||
)
|
||||
print(f"Multimodal response: {multimodal_response['choices'][0]['message']['content']}")
|
||||
print(
|
||||
f"Multimodal response: {multimodal_response['choices'][0]['message']['content']}"
|
||||
)
|
||||
print(f"Cost: ${mm_cost:.6f}, Total cost: ${mm_total_cost:.6f}")
|
||||
|
@ -11,6 +11,7 @@ from pydantic_core.core_schema import ValidationInfo
|
||||
|
||||
from app.tool.base import BaseTool, ToolResult
|
||||
|
||||
|
||||
MAX_LENGTH = 2000
|
||||
|
||||
_BROWSER_DESCRIPTION = """
|
||||
@ -181,7 +182,9 @@ class BrowserUseTool(BaseTool):
|
||||
|
||||
elif action == "get_html":
|
||||
html = await context.get_page_html()
|
||||
truncated = html[:MAX_LENGTH] + "..." if len(html) > MAX_LENGTH else html
|
||||
truncated = (
|
||||
html[:MAX_LENGTH] + "..." if len(html) > MAX_LENGTH else html
|
||||
)
|
||||
return ToolResult(output=truncated)
|
||||
|
||||
elif action == "get_text":
|
||||
|
Loading…
x
Reference in New Issue
Block a user