use context instead of FileRepo... done main process.

This commit is contained in:
geekan 2024-01-05 10:56:48 +08:00
parent 57581bbb36
commit 7cae857203
9 changed files with 53 additions and 35 deletions

View file

@ -9,25 +9,31 @@
from typing import Optional
from metagpt.actions import Action
from metagpt.config import CONFIG
from metagpt.const import DEFAULT_LANGUAGE
from metagpt.config2 import config
from metagpt.logs import logger
from metagpt.schema import Message
# TOTEST
class TalkAction(Action):
context: str
history_summary: str = ""
knowledge: str = ""
rsp: Optional[Message] = None
@property
def agent_description(self):
return self.g_context.kwargs["agent_description"]
@property
def language(self):
return self.g_context.kwargs["language"] or config.language
@property
def prompt(self):
prompt = ""
if CONFIG.agent_description:
if self.agent_description:
prompt = (
f"You are {CONFIG.agent_description}. Your responses should align with the role-play agreement, "
f"You are {self.agent_description}. Your responses should align with the role-play agreement, "
f"maintaining the character's persona and habits. When faced with unrelated questions, playfully "
f"decline to answer without revealing your AI nature to preserve the character's image.\n\n"
)
@ -36,7 +42,7 @@ class TalkAction(Action):
prompt += (
"If the information is insufficient, you can search in the historical conversation or knowledge above.\n"
)
language = CONFIG.language or DEFAULT_LANGUAGE
language = self.language
prompt += (
f"Answer the following questions strictly in {language}, and the answers must follow the Markdown format.\n "
f"{self.context}"
@ -47,10 +53,10 @@ class TalkAction(Action):
@property
def prompt_gpt4(self):
kvs = {
"{role}": CONFIG.agent_description or "",
"{role}": self.agent_description or "",
"{history}": self.history_summary or "",
"{knowledge}": self.knowledge or "",
"{language}": CONFIG.language or DEFAULT_LANGUAGE,
"{language}": self.language,
"{ask}": self.context,
}
prompt = TalkActionPrompt.FORMATION_LOOSE
@ -68,9 +74,9 @@ class TalkAction(Action):
@property
def aask_args(self):
language = CONFIG.language or DEFAULT_LANGUAGE
language = self.language
system_msgs = [
f"You are {CONFIG.agent_description}.",
f"You are {self.agent_description}.",
"Your responses should align with the role-play agreement, "
"maintaining the character's persona and habits. When faced with unrelated questions, playfully "
"decline to answer without revealing your AI nature to preserve the character's image.",

View file

@ -75,7 +75,7 @@ class WriteTeachingPlanPart(Action):
if "{" not in value:
return value
# FIXME: 从Context中获取参数
# FIXME: 从Context中获取参数而非从options
merged_opts = CONFIG.options or {}
try:
return value.format(**merged_opts)

View file

@ -80,7 +80,7 @@ class Config(metaclass=Singleton):
LLMType.OPEN_LLM: self._is_valid_llm_key(self.OPEN_LLM_API_BASE),
LLMType.GEMINI: self._is_valid_llm_key(self.GEMINI_API_KEY),
LLMType.METAGPT: bool(self._is_valid_llm_key(self.OPENAI_API_KEY) and self.OPENAI_API_TYPE == "metagpt"),
LLMType.AZURE_OPENAI: bool(
LLMType.AZURE: bool(
self._is_valid_llm_key(self.OPENAI_API_KEY)
and self.OPENAI_API_TYPE == "azure"
and self.DEPLOYMENT_NAME
@ -108,7 +108,7 @@ class Config(metaclass=Singleton):
provider = provider or self.get_default_llm_provider_enum()
model_mappings = {
LLMType.OPENAI: self.OPENAI_API_MODEL,
LLMType.AZURE_OPENAI: self.DEPLOYMENT_NAME,
LLMType.AZURE: self.DEPLOYMENT_NAME,
}
return model_mappings.get(provider, "")

View file

@ -64,6 +64,7 @@ class Config(CLIParams, YamlModel):
llm_for_researcher_summary: str = "gpt3"
llm_for_researcher_report: str = "gpt3"
METAGPT_TEXT_TO_IMAGE_MODEL_URL: str = ""
language: str = "English"
@classmethod
def default(cls):
@ -103,14 +104,24 @@ class Config(CLIParams, YamlModel):
raise ValueError(f"LLM {name} not found in config")
return self.llm[name]
def get_openai_llm(self, name: Optional[str] = None) -> LLMConfig:
def get_llm_configs_by_type(self, llm_type: LLMType) -> List[LLMConfig]:
"""Get LLM instance by type"""
return [v for k, v in self.llm.items() if v.api_type == llm_type]
def get_llm_config_by_type(self, llm_type: LLMType) -> Optional[LLMConfig]:
"""Get LLM instance by type"""
llm = self.get_llm_configs_by_type(llm_type)
if llm:
return llm[0]
return None
def get_openai_llm(self) -> Optional[LLMConfig]:
"""Get OpenAI LLMConfig by name. If no OpenAI, raise Exception"""
if name is None:
# Use the first OpenAI LLM as default
name = [k for k, v in self.llm.items() if v.api_type == LLMType.OPENAI][0]
if name not in self.llm:
raise ValueError(f"OpenAI LLM {name} not found in config")
return self.llm[name]
return self.get_llm_config_by_type(LLMType.OPENAI)
def get_azure_llm(self) -> Optional[LLMConfig]:
"""Get Azure LLMConfig by name. If no Azure, raise Exception"""
return self.get_llm_config_by_type(LLMType.AZURE)
def merge_dict(dicts: Iterable[Dict]) -> Dict:

View file

@ -22,7 +22,7 @@ class LLMType(Enum):
OPEN_LLM = "open_llm"
GEMINI = "gemini"
METAGPT = "metagpt"
AZURE_OPENAI = "azure"
AZURE = "azure"
OLLAMA = "ollama"

View file

@ -14,8 +14,8 @@ from typing import Dict, List, Optional
from pydantic import BaseModel, Field
from metagpt.config import CONFIG
from metagpt.const import DEFAULT_LANGUAGE, DEFAULT_MAX_TOKENS, DEFAULT_TOKEN_SIZE
from metagpt.config2 import config
from metagpt.const import DEFAULT_MAX_TOKENS, DEFAULT_TOKEN_SIZE
from metagpt.logs import logger
from metagpt.provider import MetaGPTLLM
from metagpt.provider.base_llm import BaseLLM
@ -83,7 +83,7 @@ class BrainMemory(BaseModel):
def to_redis_key(prefix: str, user_id: str, chat_id: str):
return f"{prefix}:{user_id}:{chat_id}"
async def set_history_summary(self, history_summary, redis_key, redis_conf):
async def set_history_summary(self, history_summary, redis_key):
if self.historical_summary == history_summary:
if self.is_dirty:
await self.dumps(redis_key=redis_key)
@ -140,7 +140,7 @@ class BrainMemory(BaseModel):
return text
summary = await self._summarize(text=text, max_words=max_words, keep_language=keep_language, limit=limit)
if summary:
await self.set_history_summary(history_summary=summary, redis_key=CONFIG.REDIS_KEY, redis_conf=CONFIG.REDIS)
await self.set_history_summary(history_summary=summary, redis_key=config.redis.key)
return summary
raise ValueError(f"text too long:{text_length}")
@ -164,7 +164,7 @@ class BrainMemory(BaseModel):
msgs.reverse()
self.history = msgs
self.is_dirty = True
await self.dumps(redis_key=CONFIG.REDIS_KEY)
await self.dumps(redis_key=config.redis.key)
self.is_dirty = False
return BrainMemory.to_metagpt_history_format(self.history)
@ -181,7 +181,7 @@ class BrainMemory(BaseModel):
summary = await self.summarize(llm=llm, max_words=500)
language = CONFIG.language or DEFAULT_LANGUAGE
language = config.language
command = f"Translate the above summary into a {language} title of less than {max_words} words."
summaries = [summary, command]
msg = "\n".join(summaries)

View file

@ -18,7 +18,7 @@ from metagpt.provider.llm_provider_registry import register_provider
from metagpt.provider.openai_api import OpenAILLM
@register_provider(LLMType.AZURE_OPENAI)
@register_provider(LLMType.AZURE)
class AzureOpenAILLM(OpenAILLM):
"""
Check https://platform.openai.com/examples for examples

View file

@ -13,20 +13,20 @@ from semantic_kernel.connectors.ai.open_ai.services.open_ai_chat_completion impo
OpenAIChatCompletion,
)
from metagpt.config import CONFIG
from metagpt.config2 import config
def make_sk_kernel():
kernel = sk.Kernel()
if CONFIG.OPENAI_API_TYPE == "azure":
if llm := config.get_openai_llm():
kernel.add_chat_service(
"chat_completion",
AzureChatCompletion(CONFIG.DEPLOYMENT_NAME, CONFIG.OPENAI_BASE_URL, CONFIG.OPENAI_API_KEY),
AzureChatCompletion(llm.model, llm.base_url, llm.api_key),
)
else:
kernel.add_chat_service(
"chat_completion",
OpenAIChatCompletion(CONFIG.OPENAI_API_MODEL, CONFIG.OPENAI_API_KEY),
OpenAIChatCompletion(llm.model, llm.api_key),
)
return kernel

View file

@ -9,7 +9,7 @@
import pytest
from metagpt.actions.talk_action import TalkAction
from metagpt.config import CONFIG
from metagpt.context import Context
from metagpt.schema import Message
@ -36,8 +36,9 @@ from metagpt.schema import Message
@pytest.mark.usefixtures("llm_mock")
async def test_prompt(agent_description, language, context, knowledge, history_summary):
# Prerequisites
CONFIG.agent_description = agent_description
CONFIG.language = language
g_context = Context()
g_context.kwargs["agent_description"] = agent_description
g_context.kwargs["language"] = language
action = TalkAction(context=context, knowledge=knowledge, history_summary=history_summary)
assert "{" not in action.prompt