Merge pull request #16 from iorisa/feature/bug-1113

fixbug: exceed length
This commit is contained in:
send18 2023-09-02 11:00:12 +08:00 committed by GitHub
commit 4a2d610e52
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 50 additions and 22 deletions

View file

@ -8,7 +8,7 @@
"""
from enum import Enum
from typing import List, Dict
from typing import Dict, List
import pydantic
@ -45,10 +45,20 @@ class BrainMemory(pydantic.BaseModel):
def history_text(self):
if len(self.history) == 0:
return ""
texts = [Message(**m).content for m in self.history[:-1]]
texts = []
for m in self.history[:-1]:
if isinstance(m, Dict):
t = Message(**m).content
elif isinstance(m, Message):
t = m.content
else:
continue
texts.append(t)
return "\n".join(texts)
def move_to_solution(self):
def move_to_solution(self, history_summary):
"""放入solution队列以备后续长程检索。目前还未加此功能先用history_summary顶替"""
if len(self.history) < 2:
return
msgs = self.history[:-1]
@ -58,6 +68,7 @@ class BrainMemory(pydantic.BaseModel):
self.history = []
else:
self.history = self.history[-1:]
self.history.insert(0, Message(content="RESOLVED: " + history_summary))
@property
def last_talk(self):

View file

@ -242,14 +242,18 @@ class OpenAIGPTAPI(BaseGPTAPI, RateLimiter):
"""Generate text title"""
max_response_token_count = 50
max_token_count = max_token_count_per_ask or CONFIG.MAX_TOKENS or DEFAULT_MAX_TOKENS
text_windows = self.split_texts(text, window_size=max_token_count - max_response_token_count)
while True:
text_windows = self.split_texts(text, window_size=max_token_count - max_response_token_count)
summaries = []
for ws in text_windows:
response = await self.get_summary(ws)
summaries.append(response)
if len(summaries) == 1:
return summaries[0]
summaries = []
for ws in text_windows:
response = await self.get_summary(ws, max_words=max_response_token_count)
summaries.append(response)
if len(summaries) == 1:
return summaries[0]
text = "\n".join(summaries)
if len(text) <= max_words * 2 and len(text) <= max_token_count:
break
language = CONFIG.language or DEFAULT_LANGUAGE
command = f"Translate the above summary into a {language} title of less than {max_words} words."

View file

@ -18,7 +18,7 @@ import asyncio
from pathlib import Path
from metagpt.actions import ActionOutput
from metagpt.actions.skill_action import SkillAction, ArgumentsParingAction
from metagpt.actions.skill_action import ArgumentsParingAction, SkillAction
from metagpt.actions.talk_action import TalkAction
from metagpt.config import CONFIG
from metagpt.learn.skill_loader import SkillLoader
@ -31,10 +31,19 @@ from metagpt.schema import Message
class Assistant(Role):
"""Assistant for solving common issues."""
def __init__(self, name="Lily", profile="An assistant", goal="Help to solve problem",
constraints="Talk in {language}", desc="", *args, **kwargs):
super(Assistant, self).__init__(name=name, profile=profile,
goal=goal, constraints=constraints, desc=desc, *args, **kwargs)
def __init__(
self,
name="Lily",
profile="An assistant",
goal="Help to solve problem",
constraints="Talk in {language}",
desc="",
*args,
**kwargs,
):
super(Assistant, self).__init__(
name=name, profile=profile, goal=goal, constraints=constraints, desc=desc, *args, **kwargs
)
brain_memory = CONFIG.BRAIN_MEMORY
self.memory = BrainMemory(**brain_memory) if brain_memory else BrainMemory()
skill_path = Path(CONFIG.SKILL_PATH) if CONFIG.SKILL_PATH else None
@ -65,8 +74,9 @@ class Assistant(Role):
msg = Message(content=result)
output = ActionOutput(content=result)
else:
msg = Message(content=result.content, instruct_content=result.instruct_content,
cause_by=type(self._rc.todo))
msg = Message(
content=result.content, instruct_content=result.instruct_content, cause_by=type(self._rc.todo)
)
output = result
self.memory.add_answer(msg)
return output
@ -85,8 +95,10 @@ class Assistant(Role):
return await handler(text, **kwargs)
async def talk_handler(self, text, **kwargs) -> bool:
action = TalkAction(talk=text, knowledge=self.memory.get_knowledge(), llm=self._llm,
**kwargs)
history = self.memory.history_text
action = TalkAction(
talk=text, knowledge=self.memory.get_knowledge(), history_summary=history, llm=self._llm, **kwargs
)
self.add_to_do(action)
return True
@ -111,17 +123,18 @@ class Assistant(Role):
return None
if history_text == "":
return last_talk
history_summary = await self._llm.get_context_title(history_text, max_words=20)
history_summary = await self._llm.get_context_title(history_text, max_token_count_per_ask=1000, max_words=500)
if last_talk and await self._llm.is_related(last_talk, history_summary): # Merge relevant content.
last_talk = await self._llm.rewrite(sentence=last_talk, context=history_text)
return last_talk
self.memory.move_to_solution() # Promptly clear memory after the issue is resolved.
self.memory.move_to_solution(history_summary) # Promptly clear memory after the issue is resolved.
return last_talk
@staticmethod
def extract_info(input_string):
from metagpt.provider.openai_api import OpenAIGPTAPI
return OpenAIGPTAPI.extract_info(input_string)
def get_memory(self) -> str:
@ -150,6 +163,6 @@ async def main():
await role.talk(talk)
if __name__ == '__main__':
if __name__ == "__main__":
CONFIG.language = "Chinese"
asyncio.run(main())