feat: merge huggingface

This commit is contained in:
莘权 马 2023-12-13 19:18:38 +08:00
parent 4582f65cf8
commit 379b7b5820
9 changed files with 73 additions and 45 deletions

View file

@ -94,4 +94,8 @@ MODEL_FOR_RESEARCHER_REPORT: gpt-3.5-turbo-16k
### browser path for pyppeteer engine, support Chrome, Chromium,MS Edge
#PYPPETEER_EXECUTABLE_PATH: "/usr/bin/google-chrome-stable"
PROMPT_FORMAT: json #json or markdown
PROMPT_FORMAT: json #json or markdown
### Agent configurations
# RAISE_NOT_CONFIG_ERROR: true # "true" if the LLM key is not configured, throw a NotConfiguredException, else "false".
# WORKSPACE_PATH_WITH_UID: false # "true" if using `{workspace}/{uid}` as the workspace path; "false" use `{workspace}`.

View file

@ -27,8 +27,8 @@ class PrepareDocuments(Action):
# Create and initialize the workspace folder, initialize the Git environment.
project_name = CONFIG.project_name or FileRepository.new_filename()
workdir = CONFIG.project_path
if not workdir and CONFIG.workspace:
workdir = Path(CONFIG.workspace) / project_name
if not workdir and CONFIG.workspace_path:
workdir = Path(CONFIG.workspace_path) / project_name
workdir = Path(workdir or DEFAULT_WORKSPACE_ROOT / project_name)
if not CONFIG.inc and workdir.exists():
shutil.rmtree(workdir)

View file

@ -6,10 +6,12 @@ Provide configuration, singleton
1. According to Section 2.2.3.11 of RFC 135, add git repository support.
2. Add the parameter `src_workspace` for the old version project path.
"""
import datetime
import os
from copy import deepcopy
from pathlib import Path
from typing import Any
from uuid import uuid4
import yaml
@ -60,7 +62,11 @@ class Config(metaclass=Singleton):
and (not self.anthropic_api_key or "YOUR_API_KEY" == self.anthropic_api_key)
and (not self.zhipuai_api_key or "YOUR_API_KEY" == self.zhipuai_api_key)
):
raise NotConfiguredException("Set OPENAI_API_KEY or Anthropic_API_KEY or ZHIPUAI_API_KEY first")
val = self._get("RAISE_NOT_CONFIG_ERROR")
if val is None or val.lower() == "true":
raise NotConfiguredException("Set OPENAI_API_KEY or Anthropic_API_KEY or ZHIPUAI_API_KEY first")
else: # for agent
logger.warning("Set OPENAI_API_KEY or Anthropic_API_KEY or ZHIPUAI_API_KEY first")
self.openai_api_base = self._get("OPENAI_API_BASE")
self.openai_proxy = self._get("OPENAI_PROXY") or self.global_proxy
self.openai_api_type = self._get("OPENAI_API_TYPE")
@ -103,8 +109,15 @@ class Config(metaclass=Singleton):
self.pyppeteer_executable_path = self._get("PYPPETEER_EXECUTABLE_PATH", "")
self.prompt_format = self._get("PROMPT_FORMAT", "markdown")
workspace_uid = (
self._get("WORKSPACE_UID") or f"{datetime.datetime.now().strftime('%Y%m%d%H%M%S')}-{uuid4().hex[-8:]}"
)
self.workspace_path = Path(self._get("WORKSPACE_PATH", DEFAULT_WORKSPACE_ROOT))
val = self._get("WORKSPACE_PATH_WITH_UID")
if val and val.lower() == "true": # for agent
self.workspace_path = self.workspace_path / workspace_uid
self._ensure_workspace_exists()
self.max_auto_summarize_code = self.max_auto_summarize_code or self._get("MAX_AUTO_SUMMARIZE_CODE", 1)
def _ensure_workspace_exists(self):
self.workspace_path.mkdir(parents=True, exist_ok=True)

View file

@ -49,7 +49,7 @@ class Environment(BaseModel):
for role in roles:
self.add_role(role)
def publish_message(self, message: Message) -> bool:
def publish_message(self, message: Message, peekable: bool = True) -> bool:
"""
Distribute the message to the recipients.
In accordance with the Message routing structure design in Chapter 2.2.1 of RFC 116, as already planned

View file

@ -42,7 +42,7 @@ from metagpt.schema import (
Documents,
Message,
)
from metagpt.utils.common import any_to_str, any_to_str_set
from metagpt.utils.common import any_to_name, any_to_str, any_to_str_set
IS_PASS_PROMPT = """
{context}
@ -83,6 +83,7 @@ class Engineer(Role):
self.code_todos = []
self.summarize_todos = []
self.n_borg = n_borg
self._next_todo = any_to_name(WriteCode)
@staticmethod
def _parse_tasks(task_msg: Document) -> list[str]:
@ -124,8 +125,10 @@ class Engineer(Role):
if self._rc.todo is None:
return None
if isinstance(self._rc.todo, WriteCode):
self._next_todo = any_to_name(SummarizeCode)
return await self._act_write_code()
if isinstance(self._rc.todo, SummarizeCode):
self._next_todo = any_to_name(WriteCode)
return await self._act_summarize()
return None
@ -296,3 +299,7 @@ class Engineer(Role):
self.summarize_todos.append(SummarizeCode(context=ctx, llm=self._llm))
if self.summarize_todos:
self._rc.todo = self.summarize_todos[0]
@property
def todo(self) -> str:
return self._next_todo

View file

@ -11,6 +11,7 @@ from metagpt.actions import UserRequirement, WritePRD
from metagpt.actions.prepare_documents import PrepareDocuments
from metagpt.config import CONFIG
from metagpt.roles import Role
from metagpt.utils.common import any_to_name
class ProductManager(Role):
@ -55,3 +56,10 @@ class ProductManager(Role):
async def _observe(self, ignore_memory=False) -> int:
return await super(ProductManager, self)._observe(ignore_memory=True)
@property
def todo(self) -> str:
if self._rc.state == 0:
return any_to_name(WritePRD)
else:
return any_to_name(PrepareDocuments)

View file

@ -30,10 +30,8 @@ from metagpt.config import CONFIG
from metagpt.llm import LLM, HumanProvider
from metagpt.logs import logger
from metagpt.memory import Memory
# from metagpt.memory import LongTermMemory
from metagpt.schema import Message, MessageQueue
from metagpt.utils.common import any_to_str
from metagpt.utils.common import any_to_name, any_to_str
PREFIX_TEMPLATE = """You are a {profile}, named {name}, your goal is {goal}, and the constraint is {constraints}. """
@ -191,6 +189,9 @@ class Role:
# check RoleContext after adding watch actions
self._rc.check(self._role_id)
def is_watch(self, caused_by: str):
return caused_by in self._rc.watch
def subscribe(self, tags: Set[str]):
"""Used to receive Messages with certain tags from the environment. Message will be put into personal message
buffer to be further processed in _observe. By default, a Role subscribes Messages with a tag of its own name
@ -213,22 +214,6 @@ class Role:
if env:
env.set_subscription(self, self._subscription)
# # Replaced by FileRepository.set_file
# def set_doc(self, content: str, filename: str):
# return self._rc.env.set_doc(content, filename)
#
# # Replaced by FileRepository.get_file
# def get_doc(self, filename: str):
# return self._rc.env.get_doc(filename)
#
# # Replaced by CONFIG.xx
# def set(self, k, v):
# return self._rc.env.set(k, v)
#
# # Replaced by CONFIG.xx
# def get(self, k):
# return self._rc.env.get(k)
@property
def profile(self):
"""Get the role description (position)"""
@ -368,23 +353,6 @@ class Role:
self._set_state(state=-1) # current reaction is complete, reset state to -1 and todo back to None
return rsp
# # Replaced by run()
# def recv(self, message: Message) -> None:
# """add message to history."""
# # self._history += f"\n{message}"
# # self._context = self._history
# if message in self._rc.memory.get():
# return
# self._rc.memory.add(message)
# # Replaced by run()
# async def handle(self, message: Message) -> Message:
# """Receive information and reply with actions"""
# # logger.debug(f"{self.name=}, {self.profile=}, {message.role=}")
# self.recv(message)
#
# return await self._react()
def get_memories(self, k=0) -> list[Message]:
"""A wrapper to return the most recent k memories of this role, return all when k=0"""
return self._rc.memory.get(k=k)
@ -418,3 +386,19 @@ class Role:
def is_idle(self) -> bool:
"""If true, all actions have been executed."""
return not self._rc.news and not self._rc.todo and self._rc.msg_buffer.empty()
async def think(self) -> Action:
"""The exported `think` function"""
await self._think()
return self._rc.todo
async def act(self) -> ActionOutput:
"""The exported `act` function"""
msg = await self._act()
return ActionOutput(content=msg.content, instruct_content=msg.instruct_content)
@property
def todo(self) -> str:
if self._actions:
return any_to_name(self._actions[0])
return ""

View file

@ -52,13 +52,14 @@ class Team(BaseModel):
# Human requirement.
self.env.publish_message(
Message(role="Human", content=idea, cause_by=UserRequirement, send_to=send_to or MESSAGE_ROUTE_TO_ALL)
Message(role="Human", content=idea, cause_by=UserRequirement, send_to=send_to or MESSAGE_ROUTE_TO_ALL),
peekable=False,
)
def _save(self):
logger.info(self.json(ensure_ascii=False))
async def run(self, n_round=3):
async def run(self, n_round=3, auto_archive=True):
"""Run company until target round or no money"""
while n_round > 0:
# self._save()
@ -66,6 +67,6 @@ class Team(BaseModel):
logger.debug(f"{n_round=}")
self._check_balance()
await self.env.run()
if CONFIG.git_repo:
if auto_archive and CONFIG.git_repo:
CONFIG.git_repo.archive()
return self.env.history

View file

@ -358,3 +358,14 @@ def is_subscribed(message, tags):
if t in message.send_to:
return True
return False
def any_to_name(val):
"""
Convert a value to its name by extracting the last part of the dotted path.
:param val: The value to convert.
:return: The name of the value.
"""
return any_to_str(val).split(".")[-1]