feat: merge Config class of send18:dev branch

This commit is contained in:
莘权 马 2023-11-27 21:20:46 +08:00
parent 726eadf1cc
commit 2cd7d266dd
3 changed files with 49 additions and 12 deletions

View file

@ -12,13 +12,15 @@
RunCodeResult to standardize and unify parameter passing between WriteCode, RunCode, and DebugError.
4. According to section 2.2.3.5.7 of RFC 135, change the method of transferring file content
(code files, unit test files, log files) from using the message to using the file name.
5. Merged the `Config` class of send18:dev branch to take over the set/get operations of the Environment
class.
"""
import os
import subprocess
import traceback
from typing import Tuple
from metagpt.actions.action import Action
from metagpt.config import CONFIG
from metagpt.logs import logger
from metagpt.schema import RunCodeResult
@ -92,7 +94,7 @@ class RunCode(Action):
additional_python_paths = [str(path) for path in additional_python_paths]
# Copy the current environment variables
env = os.environ.copy()
env = CONFIG.new_environ()
# Modify the PYTHONPATH environment variable
additional_python_paths = [working_directory] + additional_python_paths

View file

@ -7,11 +7,13 @@ Provide configuration, singleton
2. Add the parameter `src_workspace` for the old version project path.
"""
import os
from copy import deepcopy
from typing import Any
import openai
import yaml
from metagpt.const import PROJECT_ROOT
from metagpt.const import OPTIONS, PROJECT_ROOT
from metagpt.logs import logger
from metagpt.tools import SearchEngineType, WebBrowserEngineType
from metagpt.utils.singleton import Singleton
@ -42,9 +44,11 @@ class Config(metaclass=Singleton):
default_yaml_file = PROJECT_ROOT / "config/config.yaml"
def __init__(self, yaml_file=default_yaml_file):
self._configs = {}
self._init_with_config_files_and_env(self._configs, yaml_file)
self._init_with_config_files_and_env(yaml_file)
logger.info("Config loading done.")
self._update()
def _update(self):
self.global_proxy = self._get("GLOBAL_PROXY")
self.openai_api_key = self._get("OPENAI_API_KEY")
self.anthropic_api_key = self._get("Anthropic_API_KEY")
@ -96,12 +100,10 @@ class Config(metaclass=Singleton):
self.pyppeteer_executable_path = self._get("PYPPETEER_EXECUTABLE_PATH", "")
self.prompt_format = self._get("PROMPT_FORMAT", "markdown")
self.git_repo = None
self.src_workspace = None
def _init_with_config_files_and_env(self, configs: dict, yaml_file):
def _init_with_config_files_and_env(self, yaml_file):
"""Load from config/key.yaml, config/config.yaml, and env in decreasing order of priority"""
configs.update(os.environ)
configs = dict(os.environ)
for _yaml_file in [yaml_file, self.key_yaml_file]:
if not _yaml_file.exists():
@ -112,11 +114,13 @@ class Config(metaclass=Singleton):
yaml_data = yaml.safe_load(file)
if not yaml_data:
continue
os.environ.update({k: v for k, v in yaml_data.items() if isinstance(v, str)})
configs.update(yaml_data)
OPTIONS.set(configs)
def _get(self, *args, **kwargs):
return self._configs.get(*args, **kwargs)
@staticmethod
def _get(*args, **kwargs):
m = OPTIONS.get()
return m.get(*args, **kwargs)
def get(self, key, *args, **kwargs):
"""Search for a value in config/key.yaml, config/config.yaml, and env; raise an error if not found"""
@ -125,5 +129,33 @@ class Config(metaclass=Singleton):
raise ValueError(f"Key '{key}' not found in environment variables or in the YAML file")
return value
def __setattr__(self, name: str, value: Any) -> None:
OPTIONS.get()[name] = value
def __getattr__(self, name: str) -> Any:
m = OPTIONS.get()
return m.get(name)
def set_context(self, options: dict):
"""Update current config"""
if not options:
return
opts = deepcopy(OPTIONS.get())
opts.update(options)
OPTIONS.set(opts)
self._update()
@property
def options(self):
"""Return all key-values"""
return OPTIONS.get()
def new_environ(self):
"""Return a new os.environ object"""
env = os.environ.copy()
m = self.options
env.update({k: v for k, v in m.items() if isinstance(v, str)})
return env
CONFIG = Config()

View file

@ -8,6 +8,7 @@
common properties in the Message.
@Modified By: mashenquan, 2023-11-27. Defines file repository paths according to Section 2.2.3.4 of RFC 135.
"""
import contextvars
from pathlib import Path
@ -27,6 +28,8 @@ def get_project_root():
current_path = parent_path
OPTIONS = contextvars.ContextVar("OPTIONS")
PROJECT_ROOT = get_project_root()
DATA_PATH = PROJECT_ROOT / "data"
WORKSPACE_ROOT = PROJECT_ROOT / "workspace"