fix conflict

This commit is contained in:
seehi 2024-08-09 16:15:00 +08:00
commit d2bd9055f3
29 changed files with 708 additions and 45 deletions

View file

@ -17,7 +17,7 @@ from metagpt.tools.libs import (
deployer,
git,
)
from metagpt.tools.libs.env import get_env, set_get_env_entry, default_get_env, get_env_description
from metagpt.tools.libs.env import get_env, set_get_env_entry, default_get_env, get_env_description, get_env_default
_ = (
data_preprocess,
@ -32,6 +32,7 @@ _ = (
deployer,
git,
get_env,
get_env_default,
get_env_description,
set_get_env_entry,
default_get_env,

View file

@ -85,7 +85,7 @@ class CodeReview:
if pre:
patch_file_content = pre.text
else:
async with aiofiles.open(patch_path) as f:
async with aiofiles.open(patch_path, encoding="utf-8") as f:
patch_file_content = await f.read()
await EditorReporter().async_report(patch_path)

View file

@ -1,10 +1,17 @@
import base64
import os
import shutil
import subprocess
from pathlib import Path
from typing import List, Optional, Union
from pydantic import BaseModel, ConfigDict
from metagpt.logs import logger
from metagpt.tools.tool_registry import register_tool
from metagpt.utils import read_docx
from metagpt.utils.common import aread_bin, awrite_bin, run_coroutine_sync
from metagpt.utils.repo_to_markdown import is_text_file
from metagpt.utils.report import EditorReporter
@ -39,12 +46,26 @@ class Editor(BaseModel):
def read(self, path: str) -> FileBlock:
"""Read the whole content of a file. Using absolute paths as the argument for specifying the file location."""
with open(path, "r") as f:
self.resource.report(path, "path")
lines = f.readlines()
is_text, mime_type = run_coroutine_sync(is_text_file, path)
if is_text:
lines = self._read_text(path)
elif mime_type == "application/pdf":
lines = self._read_pdf(path)
elif mime_type in {
"application/msword",
"application/vnd.openxmlformats-officedocument.wordprocessingml.document",
"application/vnd.ms-word.document.macroEnabled.12",
"application/vnd.openxmlformats-officedocument.wordprocessingml.template",
"application/vnd.ms-word.template.macroEnabled.12",
}:
lines = self._read_docx(path)
else:
return FileBlock(file_path=str(path), block_content="")
self.resource.report(str(path), "path")
lines_with_num = [f"{i + 1:03}|{line}" for i, line in enumerate(lines)]
result = FileBlock(
file_path=path,
file_path=str(path),
block_content="".join(lines_with_num),
)
return result
@ -195,3 +216,63 @@ class Editor(BaseModel):
lint_passed = result.returncode == 0
lint_message = result.stdout
return lint_passed, lint_message
@staticmethod
def _read_text(path: Union[str, Path]) -> List[str]:
with open(str(path), "r") as f:
lines = f.readlines()
return lines
@staticmethod
def _read_pdf(path: Union[str, Path]) -> List[str]:
result = run_coroutine_sync(Editor._omniparse_read_file, path)
if result:
return result
from llama_index.readers.file import PDFReader
reader = PDFReader()
lines = reader.load_data(file=Path(path))
return [i.text for i in lines]
@staticmethod
def _read_docx(path: Union[str, Path]) -> List[str]:
result = run_coroutine_sync(Editor._omniparse_read_file, path)
if result:
return result
return read_docx(str(path))
@staticmethod
async def _omniparse_read_file(path: Union[str, Path]) -> Optional[List[str]]:
from metagpt.tools.libs import get_env_default
from metagpt.utils.omniparse_client import OmniParseClient
base_url = await get_env_default(key="base_url", app_name="OmniParse", default_value="")
if not base_url:
return None
api_key = await get_env_default(key="api_key", app_name="OmniParse", default_value="")
v = await get_env_default(key="timeout", app_name="OmniParse", default_value="120")
try:
timeout = int(v) or 120
except ValueError:
timeout = 120
try:
client = OmniParseClient(api_key=api_key, base_url=base_url, max_timeout=timeout)
file_data = await aread_bin(filename=path)
ret = await client.parse_document(file_input=file_data, bytes_filename=str(path))
except (ValueError, Exception) as e:
logger.exception(f"{path}: {e}")
return None
if not ret.images:
return [ret.text] if ret.text else None
result = [ret.text]
img_dir = Path(path).parent / (Path(path).name.replace(".", "_") + "_images")
img_dir.mkdir(parents=True, exist_ok=True)
for i in ret.images:
byte_data = base64.b64decode(i.image)
filename = img_dir / i.image_name
await awrite_bin(filename=filename, data=byte_data)
result.append(f"![{i.image_name}]({str(filename)})")
return result

View file

@ -7,7 +7,7 @@
@Desc: Implement `get_env`. RFC 216 2.4.2.4.2.
"""
import os
from typing import Dict
from typing import Dict, Optional
class EnvKeyNotFoundError(Exception):
@ -15,14 +15,26 @@ class EnvKeyNotFoundError(Exception):
super().__init__(info)
def to_app_key(key: str, app_name: str = None) -> str:
return f"{app_name}-{key}" if app_name else key
def split_app_key(app_key: str) -> (str, str):
if "-" not in app_key:
return "", app_key
app_name, key = app_key.split("-", 1)
return app_name, key
async def default_get_env(key: str, app_name: str = None) -> str:
if key in os.environ:
return os.environ[key]
app_key = to_app_key(key=key, app_name=app_name)
if app_key in os.environ:
return os.environ[app_key]
from metagpt.context import Context
context = Context()
val = context.kwargs.get(key, None)
val = context.kwargs.get(app_key, None)
if val is not None:
return val
@ -32,14 +44,16 @@ async def default_get_env(key: str, app_name: str = None) -> str:
async def default_get_env_description() -> Dict[str, str]:
result = {}
for k in os.environ.keys():
call = f'await get_env(key="{k}", app_name="")'
app_name, key = split_app_key(k)
call = f'await get_env(key="{key}", app_name="{app_name}")'
result[call] = f"Return the value of environment variable `{k}`."
from metagpt.context import Context
context = Context()
for k in context.kwargs.__dict__.keys():
call = f'await get_env(key="{k}", app_name="")'
app_name, key = split_app_key(k)
call = f'await get_env(key="{key}", app_name="{app_name}")'
result[call] = f"Get the value of environment variable `{k}`."
return result
@ -84,6 +98,37 @@ async def get_env(key: str, app_name: str = None) -> str:
return await default_get_env(key=key, app_name=app_name)
async def get_env_default(key: str, app_name: str = None, default_value: str = None) -> Optional[str]:
"""
Retrieves the value for the specified environment variable key. If the key is not found,
returns the default value.
Args:
key (str): The name of the environment variable to retrieve.
app_name (str, optional): The name of the application or component to associate with the environment variable.
default_value (str, optional): The default value to return if the environment variable is not found.
Returns:
str or None: The value of the environment variable if found, otherwise the default value.
Example:
>>> from metagpt.tools.libs.env import get_env
>>> api_key = await get_env_default(key="NOT_EXISTS_API_KEY", default_value="<API_KEY>")
>>> print(api_key)
<API_KEY>
>>> from metagpt.tools.libs.env import get_env
>>> api_key = await get_env_default(key="NOT_EXISTS_API_KEY", app_name="GITHUB", default_value="<API_KEY>")
>>> print(api_key)
<API_KEY>
"""
try:
return await get_env(key=key, app_name=app_name)
except EnvKeyNotFoundError:
return default_value
async def get_env_description() -> Dict[str, str]:
global _get_env_description_entry

View file

@ -1,4 +1,5 @@
import asyncio
import os
from asyncio import Queue
from asyncio.subprocess import PIPE, STDOUT
from typing import Optional
@ -28,7 +29,7 @@ class Terminal:
async def _start_process(self):
# Start a persistent shell process
self.process = await asyncio.create_subprocess_exec(
*self.shell_command, stdin=PIPE, stdout=PIPE, stderr=STDOUT, executable="bash"
*self.shell_command, stdin=PIPE, stdout=PIPE, stderr=STDOUT, executable="bash", env=os.environ.copy()
)
await self._check_state()
@ -150,6 +151,7 @@ class Bash(Terminal):
def __init__(self):
"""init"""
os.environ["SWE_CMD_WORK_DIR"] = str(DEFAULT_WORKSPACE_ROOT)
super().__init__()
self.start_flag = False

View file

@ -16,4 +16,4 @@ source $REPO_ROOT_DIR/metagpt/tools/swe_agent_commands/defaults.sh
source $REPO_ROOT_DIR/metagpt/tools/swe_agent_commands/search.sh
source $REPO_ROOT_DIR/metagpt/tools/swe_agent_commands/edit_linting.sh
export SWE_CMD_WORK_DIR="$REPO_ROOT_DIR/workspace/swe_agent_workdir"
echo "SWE_CMD_WORK_DIR: $SWE_CMD_WORK_DIR"