Merge branch 'mgx_ops' into 'data_analyst_ldy'

# Conflicts:
#   metagpt/roles/di/data_analyst.py
This commit is contained in:
李丹阳 2024-07-09 09:14:14 +00:00
commit cbe9c9f872
78 changed files with 5103 additions and 146 deletions

View file

@ -26,7 +26,7 @@ import sys
import traceback
from io import BytesIO
from pathlib import Path
from typing import Any, Callable, List, Literal, Optional, Tuple, Union
from typing import Any, Callable, Dict, List, Literal, Optional, Tuple, Union
from urllib.parse import quote, unquote
import aiofiles
@ -1013,3 +1013,34 @@ async def save_json_to_markdown(content: str, output_filename: str | Path):
logger.warning(f"An unexpected error occurred: {e}")
return
await awrite(filename=output_filename, data=json_to_markdown(m))
def tool2name(cls, methods: List[str], entry) -> Dict[str, Any]:
"""
Generates a mapping of class methods to a given entry with class name as a prefix.
Args:
cls: The class from which the methods are derived.
methods (List[str]): A list of method names as strings.
entry (Any): The entry to be mapped to each method.
Returns:
Dict[str, Any]: A dictionary where keys are method names prefixed with the class name and
values are the given entry. If the number of methods is less than 2,
the dictionary will contain a single entry with the class name as the key.
Example:
>>> class MyClass:
>>> pass
>>>
>>> tool2name(MyClass, ['method1', 'method2'], 'some_entry')
{'MyClass.method1': 'some_entry', 'MyClass.method2': 'some_entry'}
>>> tool2name(MyClass, ['method1'], 'some_entry')
{'MyClass': 'some_entry', 'MyClass.method1': 'some_entry'}
"""
class_name = cls.__name__
mappings = {f"{class_name}.{i}": entry for i in methods}
if len(mappings) < 2:
mappings[class_name] = entry
return mappings

View file

@ -23,8 +23,8 @@ from metagpt.utils.graph_repository import SPO, GraphRepository
class DiGraphRepository(GraphRepository):
"""Graph repository based on DiGraph."""
def __init__(self, name: str, **kwargs):
super().__init__(name=name, **kwargs)
def __init__(self, name: str | Path, **kwargs):
super().__init__(name=str(name), **kwargs)
self._repo = networkx.DiGraph()
async def insert(self, subject: str, predicate: str, object_: str):
@ -112,8 +112,14 @@ class DiGraphRepository(GraphRepository):
async def load(self, pathname: str | Path):
"""Load a directed graph repository from a JSON file."""
data = await aread(filename=pathname, encoding="utf-8")
m = json.loads(data)
self.load_json(data)
def load_json(self, val: str):
if not val:
return self
m = json.loads(val)
self._repo = networkx.node_link_graph(m)
return self
@staticmethod
async def load_from(pathname: str | Path) -> GraphRepository:
@ -126,9 +132,7 @@ class DiGraphRepository(GraphRepository):
GraphRepository: A new instance of the graph repository loaded from the specified JSON file.
"""
pathname = Path(pathname)
name = pathname.with_suffix("").name
root = pathname.parent
graph = DiGraphRepository(name=name, root=root)
graph = DiGraphRepository(name=pathname.stem, root=pathname.parent)
if pathname.exists():
await graph.load(pathname=pathname)
return graph

View file

@ -32,6 +32,8 @@ TOKEN_COSTS = {
"gpt-4-1106-preview": {"prompt": 0.01, "completion": 0.03},
"gpt-4-vision-preview": {"prompt": 0.01, "completion": 0.03}, # TODO add extra image price calculator
"gpt-4-1106-vision-preview": {"prompt": 0.01, "completion": 0.03},
"gpt-4o": {"prompt": 0.005, "completion": 0.015},
"gpt-4o-2024-05-13": {"prompt": 0.005, "completion": 0.015},
"text-embedding-ada-002": {"prompt": 0.0004, "completion": 0.0},
"glm-3-turbo": {"prompt": 0.0007, "completion": 0.0007}, # 128k version, prompt + completion tokens=0.005¥/k-tokens
"glm-4": {"prompt": 0.014, "completion": 0.014}, # 128k version, prompt + completion tokens=0.1¥/k-tokens
@ -207,6 +209,8 @@ def count_message_tokens(messages, model="gpt-3.5-turbo-0125"):
"gpt-4-1106-preview",
"gpt-4-vision-preview",
"gpt-4-1106-vision-preview",
"gpt-4o-2024-05-13",
"gpt-4o",
}:
tokens_per_message = 3 # # every reply is primed with <|start|>assistant<|message|>
tokens_per_name = 1