1+ #!/usr/bin/env python
2+ # -*- coding: utf-8 -*-
3+ """
4+ @Time : 2024/1/4 01:25
5+ @Author : alexanderwu
6+ @File : config2.py
7+ """
8+ import os
9+ from pathlib import Path
10+ from typing import Dict , Iterable , List , Literal , Optional
11+
12+ from pydantic import BaseModel , Field , model_validator
13+
14+ from metagpt .configs .embedding_config import EmbeddingConfig
15+ from metagpt .core .configs .llm_config import LLMConfig , LLMType
16+ from metagpt .configs .omniparse_config import OmniParseConfig
17+ from metagpt .configs .role_custom_config import RoleCustomConfig
18+ from metagpt .configs .workspace_config import WorkspaceConfig
19+ from metagpt .const import CONFIG_ROOT , METAGPT_ROOT
20+ from metagpt .core .utils .yaml_model import YamlModel
21+
22+
23+ class CLIParams (BaseModel ):
24+ """CLI parameters"""
25+
26+ project_path : str = ""
27+ project_name : str = ""
28+ inc : bool = False
29+ reqa_file : str = ""
30+ max_auto_summarize_code : int = 0
31+ git_reinit : bool = False
32+
33+ @model_validator (mode = "after" )
34+ def check_project_path (self ):
35+ """Check project_path and project_name"""
36+ if self .project_path :
37+ self .inc = True
38+ self .project_name = self .project_name or Path (self .project_path ).name
39+ return self
40+
41+
42+ class CoreConfig (CLIParams , YamlModel ):
43+ """Configurations for MetaGPT"""
44+
45+ # Key Parameters
46+ llm : LLMConfig
47+
48+ # Global Proxy. Will be used if llm.proxy is not set
49+ proxy : str = ""
50+
51+ # Misc Parameters
52+ repair_llm_output : bool = False
53+ prompt_schema : Literal ["json" , "markdown" , "raw" ] = "json"
54+ workspace : WorkspaceConfig = Field (default_factory = WorkspaceConfig )
55+
56+ @classmethod
57+ def from_home (cls , path ):
58+ """Load config from ~/.metagpt/config2.yaml"""
59+ pathname = CONFIG_ROOT / path
60+ if not pathname .exists ():
61+ return None
62+ return CoreConfig .from_yaml_file (pathname )
63+
64+ @classmethod
65+ def default (cls , reload : bool = False , ** kwargs ) -> "CoreConfig" :
66+ """Load default config
67+ - Priority: env < default_config_paths
68+ - Inside default_config_paths, the latter one overwrites the former one
69+ """
70+ default_config_paths = (
71+ METAGPT_ROOT / "config/config2.yaml" ,
72+ CONFIG_ROOT / "config2.yaml" ,
73+ )
74+ if reload or default_config_paths not in _CONFIG_CACHE :
75+ dicts = [dict (os .environ ), * (CoreConfig .read_yaml (path ) for path in default_config_paths ), kwargs ]
76+ final = merge_dict (dicts )
77+ _CONFIG_CACHE [default_config_paths ] = CoreConfig (** final )
78+ return _CONFIG_CACHE [default_config_paths ]
79+
80+ @classmethod
81+ def from_llm_config (cls , llm_config : dict ):
82+ """user config llm
83+ example:
84+ llm_config = {"api_type": "xxx", "api_key": "xxx", "model": "xxx"}
85+ gpt4 = CoreConfig.from_llm_config(llm_config)
86+ A = Role(name="A", profile="Democratic candidate", goal="Win the election", actions=[a1], watch=[a2], config=gpt4)
87+ """
88+ llm_config = LLMConfig .model_validate (llm_config )
89+ dicts = [dict (os .environ )]
90+ dicts += [{"llm" : llm_config }]
91+ final = merge_dict (dicts )
92+ return CoreConfig (** final )
93+
94+ def update_via_cli (self , project_path , project_name , inc , reqa_file , max_auto_summarize_code ):
95+ """update config via cli"""
96+
97+ # Use in the PrepareDocuments action according to Section 2.2.3.5.1 of RFC 135.
98+ if project_path :
99+ inc = True
100+ project_name = project_name or Path (project_path ).name
101+ self .project_path = project_path
102+ self .project_name = project_name
103+ self .inc = inc
104+ self .reqa_file = reqa_file
105+ self .max_auto_summarize_code = max_auto_summarize_code
106+
107+
108+ def merge_dict (dicts : Iterable [Dict ]) -> Dict :
109+ """Merge multiple dicts into one, with the latter dict overwriting the former"""
110+ result = {}
111+ for dictionary in dicts :
112+ result .update (dictionary )
113+ return result
114+
115+
116+ _CONFIG_CACHE = {}
0 commit comments