提交版本
This commit is contained in:
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
File diff suppressed because it is too large
Load Diff
180
AlgoriAgent/projects/algoriAgent/agent/score_agent.py
Normal file
180
AlgoriAgent/projects/algoriAgent/agent/score_agent.py
Normal file
@@ -0,0 +1,180 @@
|
|||||||
|
|
||||||
|
from typing import Any, Callable, Optional, Union, Sequence
|
||||||
|
|
||||||
|
from loguru import logger
|
||||||
|
from agent.flex_service_toolkit import FlexServiceToolkit
|
||||||
|
from agentscope.exception import ResponseParsingError, FunctionCallError
|
||||||
|
from agentscope.agents import AgentBase
|
||||||
|
from agentscope.memory.temporary_memory import TemporaryMemory
|
||||||
|
from agentscope.message import Msg
|
||||||
|
from agentscope.parsers import MarkdownJsonDictParser
|
||||||
|
from agentscope.service.service_toolkit import ServiceFunction
|
||||||
|
from agentscope.service import (
|
||||||
|
ServiceToolkit,
|
||||||
|
ServiceResponse,
|
||||||
|
ServiceExecStatus,
|
||||||
|
)
|
||||||
|
import json
|
||||||
|
|
||||||
|
|
||||||
|
INSTRUCTION_SCORE_PROMPT_CN = """
|
||||||
|
你是一名经验丰富的算法课程评分专家,你的任务是:基于学生对一个章节的学习日志、对话流,按照指定的评分标准进行评分。
|
||||||
|
但是不同于普通老师,为了提高得分的区分度,你需要作为一名非常挑剔的专家,根据评分标准仔细挑剔学生的学习日志,并给出评分报告。
|
||||||
|
|
||||||
|
重要的挑剔点:
|
||||||
|
1. 存在错误的概念理解
|
||||||
|
2. 存在矛盾的概念理解
|
||||||
|
3. 存在不清晰、不连贯的概念表达
|
||||||
|
4. 其他你认为可以挑剔的地方
|
||||||
|
|
||||||
|
下面是学生的整个学习日志和对话流:
|
||||||
|
"""
|
||||||
|
|
||||||
|
CHAPTER_HINT_CN ="""
|
||||||
|
上面就是学生的整个学习日志和对话流,请进行下面的各条章节评分标准进行挑剔与评分。
|
||||||
|
"""
|
||||||
|
|
||||||
|
RESPONSE_HINT_CN = """
|
||||||
|
你的返回必须包含:
|
||||||
|
对于每条章节评分标准,报告学生的得分以及挑剔的结果。
|
||||||
|
例如:
|
||||||
|
```
|
||||||
|
{'评分标准1': {'得分': 8, '挑剔报告': '答案正确,但对于xxx概念表述有误'}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
"""
|
||||||
|
|
||||||
|
INSTRUCTION_SCORE_PROMPT_EN = """
|
||||||
|
You are a experienced algorithm course scoring expert, your task is to: Based on the students' learning logs and dialogues, score them according to the specified scoring standard.
|
||||||
|
But unlike a normal teacher, to improve the distinction of the score, you need to be a very critical expert, carefully pick out the students' learning logs according to the scoring standard and give a score report.
|
||||||
|
|
||||||
|
The important points to pick out:
|
||||||
|
1. There are errors in the concept understanding
|
||||||
|
2. There are contradictions in the concept understanding
|
||||||
|
3. There are unclear, incoherent concept expressions
|
||||||
|
4. Other places you think can be picked out
|
||||||
|
Below is the students' entire learning log and dialogue:
|
||||||
|
"""
|
||||||
|
|
||||||
|
CHAPTER_HINT_EN = """
|
||||||
|
Above is the students' entire learning log and dialogue, please pick out according to the following chapter scoring standard and score them.
|
||||||
|
"""
|
||||||
|
|
||||||
|
RESPONSE_HINT_EN="""
|
||||||
|
Your response must contain:
|
||||||
|
For each chapter scoring standard, report the students' score and pick out the results.
|
||||||
|
For example:
|
||||||
|
```
|
||||||
|
{'Score standard 1': {'Score': 8, 'Pick out report': 'The answer is correct, but for the xxx concept expression is wrong'}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
class ScoreAgent(AgentBase):
|
||||||
|
"""
|
||||||
|
ScoreAgent is a agent that can score students' learning logs.
|
||||||
|
"""
|
||||||
|
def __init__(self, name: str, model_config_name: str, memory: TemporaryMemory,
|
||||||
|
chapter_score_prompt: str,
|
||||||
|
service_toolkit: ServiceToolkit,
|
||||||
|
sys_prompt: str = "You're a helpful assistant.",
|
||||||
|
max_iters: int = 5,
|
||||||
|
verbose: bool = True,
|
||||||
|
**kwargs):
|
||||||
|
self.service_toolkit = service_toolkit
|
||||||
|
super().__init__(
|
||||||
|
name=name,
|
||||||
|
sys_prompt=sys_prompt,
|
||||||
|
model_config_name=model_config_name,
|
||||||
|
)
|
||||||
|
self.max_iters = max_iters
|
||||||
|
self.verbose = verbose
|
||||||
|
if not sys_prompt.endswith("\n"):
|
||||||
|
sys_prompt = sys_prompt + "\n"
|
||||||
|
|
||||||
|
self.sys_prompt = "\n".join(
|
||||||
|
[
|
||||||
|
# The brief intro of the role and target
|
||||||
|
sys_prompt.format(name=self.name),
|
||||||
|
# The detailed instruction prompt for the agent
|
||||||
|
INSTRUCTION_SCORE_PROMPT_CN,
|
||||||
|
],
|
||||||
|
)
|
||||||
|
self.memory = TemporaryMemory()
|
||||||
|
self.memory.add(Msg("system", self.sys_prompt, role="system"))
|
||||||
|
|
||||||
|
self.memory.add(memory.get_memory())
|
||||||
|
|
||||||
|
self.memory.add(Msg("system", CHAPTER_HINT_CN, role="system"))
|
||||||
|
|
||||||
|
self.memory.add(Msg("system", chapter_score_prompt, role="system"))
|
||||||
|
|
||||||
|
self.memory.add(Msg("system", RESPONSE_HINT_CN, role="system"))
|
||||||
|
|
||||||
|
self.parser = MarkdownJsonDictParser(
|
||||||
|
content_hint={
|
||||||
|
"thought": "what you thought",
|
||||||
|
"speak": "actual response in correct format mentioned above",
|
||||||
|
},
|
||||||
|
required_keys=["thought", "speak"],
|
||||||
|
# Only print the speak field when verbose is False
|
||||||
|
keys_to_content=True if self.verbose else "speak",
|
||||||
|
)
|
||||||
|
|
||||||
|
def reply(self, x = None, user_backboard = ""):
|
||||||
|
for _ in range(self.max_iters):
|
||||||
|
if self.verbose:
|
||||||
|
self.speak(f" ITER {_+1} ".center(70, "#"))
|
||||||
|
try:
|
||||||
|
|
||||||
|
hint_msg = Msg(
|
||||||
|
"system",
|
||||||
|
self.parser.format_instruction+"\n",
|
||||||
|
role="system",
|
||||||
|
echo=self.verbose,
|
||||||
|
)
|
||||||
|
prompt = self.model.format(self.memory.get_memory(),hint_msg
|
||||||
|
)
|
||||||
|
if self.verbose:
|
||||||
|
self.speak(f"API Trigger".center(70, "#"))
|
||||||
|
self.speak(str(prompt))
|
||||||
|
res = self.model(
|
||||||
|
prompt,
|
||||||
|
parse_func=self.parser.parse,
|
||||||
|
max_retries=2,
|
||||||
|
######################
|
||||||
|
)
|
||||||
|
|
||||||
|
if self.verbose:
|
||||||
|
self.speak(f"Result Parsed".center(70, "#"))
|
||||||
|
self.speak(str(res.parsed))
|
||||||
|
print(res.parsed)
|
||||||
|
self.memory.add(
|
||||||
|
Msg(
|
||||||
|
self.name,
|
||||||
|
self.parser.to_memory(res.parsed),
|
||||||
|
"assistant",
|
||||||
|
),
|
||||||
|
)
|
||||||
|
msg_returned = Msg(
|
||||||
|
self.name,
|
||||||
|
self.parser.to_content(res.parsed),
|
||||||
|
"assistant",
|
||||||
|
)
|
||||||
|
return msg_returned
|
||||||
|
except ResponseParsingError as e:
|
||||||
|
# Print out raw response from models for developers to debug
|
||||||
|
response_msg = Msg(self.name, e.raw_response, "assistant")
|
||||||
|
self.speak(response_msg)
|
||||||
|
# Re-correct by model itself
|
||||||
|
error_msg = Msg("system", str(e), "system")
|
||||||
|
self.speak(error_msg)
|
||||||
|
self.memory.add([response_msg, error_msg])
|
||||||
|
except Exception as e:
|
||||||
|
self.speak(f"Error: {e}".center(70, "#"))
|
||||||
|
self.speak(f"Retrying".center(70, "#"))
|
||||||
|
continue
|
||||||
|
|
||||||
|
return Msg(self.name, "Error: Max iterations reached", "assistant")
|
||||||
|
|
||||||
152
AlgoriAgent/projects/algoriAgent/agent/total_score_agent.py
Normal file
152
AlgoriAgent/projects/algoriAgent/agent/total_score_agent.py
Normal file
@@ -0,0 +1,152 @@
|
|||||||
|
|
||||||
|
from typing import Any, Callable, Optional, Union, Sequence
|
||||||
|
|
||||||
|
from loguru import logger
|
||||||
|
from agent.flex_service_toolkit import FlexServiceToolkit
|
||||||
|
from agentscope.exception import ResponseParsingError, FunctionCallError
|
||||||
|
from agentscope.agents import AgentBase
|
||||||
|
from agentscope.memory.temporary_memory import TemporaryMemory
|
||||||
|
from agentscope.message import Msg
|
||||||
|
from agentscope.parsers import MarkdownJsonDictParser
|
||||||
|
from agentscope.service.service_toolkit import ServiceFunction
|
||||||
|
from agentscope.service import (
|
||||||
|
ServiceToolkit,
|
||||||
|
ServiceResponse,
|
||||||
|
ServiceExecStatus,
|
||||||
|
)
|
||||||
|
import json
|
||||||
|
|
||||||
|
|
||||||
|
INSTRUCTION_TOTAL_SCORE_PROMPT_CN = """
|
||||||
|
你是一名精通文件处理的专家,你的本次任务非常简单,给你一段由其他老师给出的评分评价,你需要从中提取每一条标准下的得分,并计算总分,返回总分即可。
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
RESPONSE_TOTAL_SCORE_HINT_CN = """
|
||||||
|
你的返回必须包含且仅包含一个整数,表示得分。
|
||||||
|
例如:
|
||||||
|
输入:
|
||||||
|
```
|
||||||
|
{'评分标准1': {'得分': 8, '挑剔报告': '答案正确,但对于xxx概念表述有误'},
|
||||||
|
'评分标准2': {'得分': 3, '挑剔报告': '答案错误,对于xxx概念理解完全错误,导致回答有误'}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
输出:
|
||||||
|
11
|
||||||
|
下面是真正的输入:
|
||||||
|
"""
|
||||||
|
|
||||||
|
INSTRUCTION_TOTAL_SCORE_PROMPT_EN = """
|
||||||
|
You are an expert in file processing. Your task is very simple. You will be given a segment of evaluation comments provided by another teacher. You need to extract the scores for each criterion and calculate the total score, returning only the total score.
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
RESPONSE_TOTAL_SCORE_HINT_EN="""
|
||||||
|
Your return must contain and only contain an integer representing the score. For example:
|
||||||
|
Input:
|
||||||
|
```
|
||||||
|
{'Criterion 1': {'Score': 8, 'Critical Report': 'The answer is correct, but there is a mistake in the explanation of the xxx concept'},
|
||||||
|
'Criterion 2': {'Score': 3, 'Critical Report': 'The answer is incorrect, with a complete misunderstanding of the xxx concept, leading to an incorrect response'}
|
||||||
|
}
|
||||||
|
```
|
||||||
|
Output:
|
||||||
|
```
|
||||||
|
{'output': 11}
|
||||||
|
```
|
||||||
|
Below is the actual input:
|
||||||
|
"""
|
||||||
|
|
||||||
|
|
||||||
|
class TotalScoreAgent(AgentBase):
|
||||||
|
"""
|
||||||
|
TotalScoreAgent is a agent that can gather students' all score.
|
||||||
|
"""
|
||||||
|
def __init__(self, name: str, model_config_name: str, input: str,
|
||||||
|
service_toolkit: ServiceToolkit,
|
||||||
|
sys_prompt: str = "You're a helpful assistant.",
|
||||||
|
max_iters: int = 5,
|
||||||
|
verbose: bool = True,
|
||||||
|
**kwargs):
|
||||||
|
self.service_toolkit = service_toolkit
|
||||||
|
super().__init__(
|
||||||
|
name=name,
|
||||||
|
sys_prompt=sys_prompt,
|
||||||
|
model_config_name=model_config_name,
|
||||||
|
)
|
||||||
|
self.max_iters = max_iters
|
||||||
|
self.verbose = verbose
|
||||||
|
if not sys_prompt.endswith("\n"):
|
||||||
|
sys_prompt = sys_prompt + "\n"
|
||||||
|
|
||||||
|
self.sys_prompt = "\n".join(
|
||||||
|
[
|
||||||
|
# The brief intro of the role and target
|
||||||
|
sys_prompt.format(name=self.name),
|
||||||
|
# The detailed instruction prompt for the agent
|
||||||
|
INSTRUCTION_TOTAL_SCORE_PROMPT_CN,
|
||||||
|
RESPONSE_TOTAL_SCORE_HINT_CN
|
||||||
|
],
|
||||||
|
)
|
||||||
|
self.memory = TemporaryMemory()
|
||||||
|
self.memory.add(Msg("system", self.sys_prompt, role="system"))
|
||||||
|
|
||||||
|
self.memory.add(Msg("User", input, role="system"))
|
||||||
|
self.parser = MarkdownJsonDictParser(
|
||||||
|
content_hint={
|
||||||
|
"output": "total score",
|
||||||
|
},
|
||||||
|
required_keys=["output"],
|
||||||
|
# Only print the speak field when verbose is False
|
||||||
|
keys_to_content=True if self.verbose else "speak",
|
||||||
|
)
|
||||||
|
|
||||||
|
def reply(self, x = None, user_backboard = ""):
|
||||||
|
for _ in range(self.max_iters):
|
||||||
|
if self.verbose:
|
||||||
|
self.speak(f" ITER {_+1} ".center(70, "#"))
|
||||||
|
try:
|
||||||
|
|
||||||
|
hint_msg = Msg(
|
||||||
|
"system",
|
||||||
|
self.parser.format_instruction+"\n",
|
||||||
|
role="system",
|
||||||
|
echo=self.verbose,
|
||||||
|
)
|
||||||
|
prompt = self.model.format(self.memory.get_memory(),hint_msg
|
||||||
|
)
|
||||||
|
if self.verbose:
|
||||||
|
self.speak(f"API Trigger".center(70, "#"))
|
||||||
|
self.speak(str(prompt))
|
||||||
|
res = self.model(
|
||||||
|
prompt,
|
||||||
|
parse_func=self.parser.parse,
|
||||||
|
max_retries=2,
|
||||||
|
######################
|
||||||
|
)
|
||||||
|
|
||||||
|
print('====-======-=====')
|
||||||
|
|
||||||
|
return res.parsed['output']
|
||||||
|
|
||||||
|
|
||||||
|
if self.verbose:
|
||||||
|
self.speak(f"Result Parsed".center(70, "#"))
|
||||||
|
self.speak(str(res))
|
||||||
|
print(res)
|
||||||
|
|
||||||
|
return res
|
||||||
|
except ResponseParsingError as e:
|
||||||
|
# Print out raw response from models for developers to debug
|
||||||
|
response_msg = Msg(self.name, e.raw_response, "assistant")
|
||||||
|
self.speak(response_msg)
|
||||||
|
# Re-correct by model itself
|
||||||
|
error_msg = Msg("system", str(e), "system")
|
||||||
|
self.speak(error_msg)
|
||||||
|
self.memory.add([response_msg, error_msg])
|
||||||
|
except Exception as e:
|
||||||
|
self.speak(f"Error: {e}".center(70, "#"))
|
||||||
|
self.speak(f"Retrying".center(70, "#"))
|
||||||
|
continue
|
||||||
|
|
||||||
|
return Msg(self.name, "Error: Max iterations reached", "assistant")
|
||||||
|
|
||||||
@@ -1,235 +1,329 @@
|
|||||||
import sys
|
import sys
|
||||||
import os
|
import os
|
||||||
current_directory = os.path.dirname(os.path.abspath(__file__))
|
current_directory = os.path.dirname(os.path.abspath(__file__))
|
||||||
sys.path.append(current_directory)
|
sys.path.append(current_directory)
|
||||||
|
from flask_socketio import SocketIO, join_room, emit, Namespace
|
||||||
import agentscope
|
import agentscope
|
||||||
from agentscope.message import Msg
|
from agentscope.message import Msg
|
||||||
import os
|
import os
|
||||||
import asyncio
|
import asyncio
|
||||||
import threading
|
import threading
|
||||||
import json
|
import json
|
||||||
|
|
||||||
from agent.flex_service_toolkit import *
|
from agent.flex_service_toolkit import *
|
||||||
from AlgoriAgent.projects.algoriAgent.agent.algori_agent import *
|
from AlgoriAgent.projects.algoriAgent.agent.algori_agent import *
|
||||||
|
|
||||||
from agentscope.service import (
|
from agentscope.service import (
|
||||||
ServiceToolkit,
|
ServiceToolkit,
|
||||||
ServiceResponse,
|
ServiceResponse,
|
||||||
ServiceExecStatus,
|
ServiceExecStatus,
|
||||||
)
|
)
|
||||||
import configparser
|
import configparser
|
||||||
|
|
||||||
config = configparser.ConfigParser()
|
config = configparser.ConfigParser()
|
||||||
config.read('config.ini')
|
config.read('config.ini')
|
||||||
openai_api_key = config['Global']['api_key']
|
openai_api_key = config['Global']['api_key']
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
OPENAI_CFG_DICT = {
|
OPENAI_CFG_DICT = {
|
||||||
"config_name": "openai_cfg", # 此配置的名称,必须保证唯一
|
"config_name": "openai_cfg", # 此配置的名称,必须保证唯一
|
||||||
"model_type": "openai_chat", # 模型类型
|
"model_type": "openai_chat", # 模型类型
|
||||||
"model_name": "gpt-4o-mini", # 模型名称
|
"model_name": "gpt-4o-mini", # 模型名称
|
||||||
#"model_name": "gpt-4", # 模型名称
|
#"model_name": "gpt-4", # 模型名称
|
||||||
#"model_name": "llama3",
|
#"model_name": "llama3",
|
||||||
|
"api_key": openai_api_key, # OpenAI API key. 如果没有设置,将使用环境变量中的 OPENAI_API_KEY
|
||||||
"api_key": openai_api_key, # OpenAI API key. 如果没有设置,将使用环境变量中的 OPENAI_API_KEY
|
|
||||||
|
"client_args": {
|
||||||
"client_args": {
|
"base_url": config['Global']['base_chat_url']
|
||||||
"base_url": config['Global']['base_chat_url']
|
},
|
||||||
},
|
|
||||||
|
}
|
||||||
}
|
|
||||||
|
import uuid
|
||||||
import uuid
|
from AlgoriAgent.projects.algoriAgent.tools.judge_tools import judge
|
||||||
from AlgoriAgent.projects.algoriAgent.tools.judge_tools import judge
|
EMPTY_CHAPTER_CHAIN = [ Chapter(1, CHAPTER_FOCUS, "本章是未打开某个具体章节时的默认章节。", "处于本章节时不会有任何章节跳转。请作为一名经验丰富的算法教师,回答用户的问题。") ]
|
||||||
EMPTY_CHAPTER_CHAIN = [ Chapter(1, CHAPTER_FOCUS, "本章是未打开某个具体章节时的默认章节。", "处于本章节时不会有任何章节跳转。请作为一名经验丰富的算法教师,回答用户的问题。") ]
|
|
||||||
|
def tool_name_to_tool(tool_name_list):
|
||||||
def tool_name_to_tool(tool_name_list):
|
tools = []
|
||||||
tools = []
|
for tool_name in tool_name_list:
|
||||||
for tool_name in tool_name_list:
|
if tool_name == "":
|
||||||
if tool_name == "":
|
continue
|
||||||
continue
|
if tool_name == "judge":
|
||||||
if tool_name == "judge":
|
tools.append(judge)
|
||||||
tools.append(judge)
|
|
||||||
|
return tools
|
||||||
return tools
|
|
||||||
|
def tool_name_to_tool_with_args(tool_name_list, tool_args_list) -> list[tuple[Callable, dict]]:
|
||||||
class AgentManager:
|
tools = []
|
||||||
def __init__(self):
|
for tool_name, tool_args in zip(tool_name_list, tool_args_list):
|
||||||
|
if tool_name == "":
|
||||||
agentscope.init(model_configs=[OPENAI_CFG_DICT])#, studio_url="http://0.0.0.0:5000")
|
continue
|
||||||
self.agents = {}
|
if tool_name == "judge":
|
||||||
|
tools.append((judge, {"course_id": tool_args[0], "lesson_id": tool_args[1], "name": tool_args[2]}))
|
||||||
def new_agent(self, markdown:str, markdown_prompt:str, score_prompt:str, id = None):
|
|
||||||
'''
|
return tools
|
||||||
markdown: 教案的markdown文件内容
|
class AgentManager:
|
||||||
markdown_prompt: 教案的prompt的markdown文件内容
|
def __init__(self,max_iter = 5, app=None, socketio=None):
|
||||||
score_prompt: 评分的prompt的markdown文件内容
|
|
||||||
根据3个教案的prompt,生成一个agent,返回agent的id与agent
|
agentscope.init(model_configs=[OPENAI_CFG_DICT])#, studio_url="http://0.0.0.0:5000")
|
||||||
'''
|
self.agents = {}
|
||||||
markdown_list = markdown.split("\n")
|
self.max_iter = max_iter
|
||||||
markdown_prompt_list = markdown_prompt.split("\n")
|
self.agent_to_id = {}
|
||||||
score_prompt_list = score_prompt.split("\n")
|
self.app = app
|
||||||
# 获取 H1 标题
|
self.socketio = socketio
|
||||||
title = ""
|
def new_agent(self, course_id, lesson_id, markdown:str, markdown_prompt:str, score_prompt:str, id = "Defult Assistant", root_path="."):
|
||||||
for line in markdown_list:
|
'''
|
||||||
if line.startswith("# "):
|
markdown: 教案的markdown文件内容
|
||||||
title = line[2:]
|
markdown_prompt: 教案的prompt的markdown文件内容
|
||||||
break
|
score_prompt: 评分的prompt的markdown文件内容
|
||||||
|
根据3个教案的prompt,生成一个agent,返回agent的id与agent
|
||||||
# 对于 H3 标题 构造每一个 Chapter
|
'''
|
||||||
# 首先找到所有的 H3 标题
|
markdown_list = markdown.split("\n")
|
||||||
chapter_dict = {}
|
markdown_prompt_list = markdown_prompt.split("\n")
|
||||||
chapter_sequence = []
|
score_prompt_list = score_prompt.split("\n")
|
||||||
for line in markdown_list:
|
# 获取 H1 标题
|
||||||
if line.startswith("### "):
|
title = ""
|
||||||
chapter_name = line[4:]
|
for line in markdown_list:
|
||||||
chapter_dict[chapter_name] = {}
|
if line.startswith("# "):
|
||||||
chapter_sequence.append(chapter_name)
|
title = line[2:]
|
||||||
# 将 H3 标题 和 其对应的内容 构造成一个 Chapter
|
break
|
||||||
|
|
||||||
h3_name = ""
|
# 对于 H3 标题 构造每一个 Chapter
|
||||||
content = ""
|
# 首先找到所有的 H3 标题
|
||||||
for i in range(len(markdown_list)):
|
chapter_dict = {}
|
||||||
if markdown_list[i].startswith("### "):
|
chapter_sequence = []
|
||||||
if(h3_name != ""):
|
for line in markdown_list:
|
||||||
chapter_dict[h3_name]["markdown"] = content
|
if line.startswith("### "):
|
||||||
h3_name = markdown_list[i][4:]
|
chapter_name = line[4:]
|
||||||
content = ""
|
chapter_dict[chapter_name] = {}
|
||||||
continue
|
chapter_sequence.append(chapter_name)
|
||||||
if h3_name != "":
|
# 将 H3 标题 和 其对应的内容 构造成一个 Chapter
|
||||||
content += markdown_list[i]+"\n"
|
|
||||||
if(h3_name != ""):
|
h3_name = ""
|
||||||
chapter_dict[h3_name]["markdown"] = content
|
content = ""
|
||||||
|
for i in range(len(markdown_list)):
|
||||||
|
if markdown_list[i].startswith("### "):
|
||||||
h3_name = ""
|
if(h3_name != ""):
|
||||||
content = ""
|
chapter_dict[h3_name]["markdown"] = content
|
||||||
require_tools = []
|
h3_name = markdown_list[i][4:]
|
||||||
for i in range(len(markdown_prompt_list)):
|
content = ""
|
||||||
if markdown_prompt_list[i].startswith("### "):
|
continue
|
||||||
if(h3_name != ""):
|
if h3_name != "":
|
||||||
chapter_dict[h3_name]["markdown_prompt"] = content
|
content += markdown_list[i]+"\n"
|
||||||
chapter_dict[h3_name]["require_tools"] = tool_name_to_tool(require_tools)
|
if(h3_name != ""):
|
||||||
h3_name = markdown_prompt_list[i][4:]
|
chapter_dict[h3_name]["markdown"] = content
|
||||||
content = ""
|
|
||||||
continue
|
|
||||||
|
h3_name = ""
|
||||||
if h3_name != "":
|
content = ""
|
||||||
if markdown_prompt_list[i].startswith("_require_tools"):
|
require_tools = []
|
||||||
require_tools.append(markdown_prompt_list[i].split("=")[1].strip())
|
require_tools_args = []
|
||||||
continue
|
for i in range(len(markdown_prompt_list)):
|
||||||
content += markdown_prompt_list[i]+"\n"
|
if markdown_prompt_list[i].startswith("### "):
|
||||||
if(h3_name != ""):
|
if(h3_name != ""):
|
||||||
chapter_dict[h3_name]["markdown_prompt"] = content
|
chapter_dict[h3_name]["markdown_prompt"] = content
|
||||||
chapter_dict[h3_name]["require_tools"] = tool_name_to_tool(require_tools)
|
chapter_dict[h3_name]["require_tools"] = tool_name_to_tool_with_args(require_tools, require_tools_args)
|
||||||
|
h3_name = markdown_prompt_list[i][4:]
|
||||||
|
content = ""
|
||||||
h3_name = ""
|
require_tools=[]
|
||||||
content = ""
|
require_tools_args = []
|
||||||
for i in range(len(score_prompt_list)):
|
continue
|
||||||
if score_prompt_list[i].startswith("### "):
|
|
||||||
if(h3_name != ""):
|
if h3_name != "":
|
||||||
chapter_dict[h3_name]["score_prompt"] = content
|
if markdown_prompt_list[i].startswith("_require_tools"):
|
||||||
h3_name = score_prompt_list[i][4:]
|
require_tools.append(markdown_prompt_list[i].split("=")[1].strip().split(",")[0])
|
||||||
content = ""
|
require_tools_args.append((markdown_prompt_list[i].split("=")[1].strip().split(",")[1:]))
|
||||||
continue
|
continue
|
||||||
|
content += markdown_prompt_list[i]+"\n"
|
||||||
if h3_name != "":
|
if(h3_name != ""):
|
||||||
content += score_prompt_list[i]+"\n"
|
chapter_dict[h3_name]["markdown_prompt"] = content
|
||||||
if(h3_name != ""):
|
chapter_dict[h3_name]["require_tools"] = tool_name_to_tool_with_args(require_tools, require_tools_args)
|
||||||
chapter_dict[h3_name]["score_prompt"] = content
|
|
||||||
|
|
||||||
|
h3_name = ""
|
||||||
chapter_chain = []
|
content = ""
|
||||||
No = 1
|
for i in range(len(score_prompt_list)):
|
||||||
print (chapter_dict)
|
if score_prompt_list[i].startswith("### "):
|
||||||
for chapter_name in chapter_sequence:
|
if(h3_name != ""):
|
||||||
chapter_chain.append(Chapter(No, CHAPTER_LATTER, title, chapter_dict[chapter_name]["markdown"], chapter_dict[chapter_name]["markdown_prompt"], chapter_dict[chapter_name]["score_prompt"],chapter_dict[chapter_name]["require_tools"]))
|
chapter_dict[h3_name]["score_prompt"] = content
|
||||||
No+=1
|
h3_name = score_prompt_list[i][4:]
|
||||||
chapter_chain[0].Focus()
|
content = ""
|
||||||
|
continue
|
||||||
|
|
||||||
# Prepare the tools for the agent
|
if h3_name != "":
|
||||||
service_toolkit = FlexServiceToolkit()
|
content += score_prompt_list[i]+"\n"
|
||||||
# for tool_function in unity_function_list:
|
if(h3_name != ""):
|
||||||
# service_toolkit.add(tool_function)
|
chapter_dict[h3_name]["score_prompt"] = content
|
||||||
agent = ChapterChainAgent(
|
|
||||||
name="assistant",
|
|
||||||
model_config_name="openai_cfg",
|
chapter_chain = []
|
||||||
verbose=True,
|
No = 1
|
||||||
service_toolkit=service_toolkit,
|
print (chapter_dict)
|
||||||
max_iters=5,
|
for chapter_name in chapter_sequence:
|
||||||
chapter_chain=chapter_chain
|
chapter_chain.append(Chapter(course_id, lesson_id, No, CHAPTER_LATTER, chapter_name, chapter_dict[chapter_name]["markdown"], chapter_dict[chapter_name]["markdown_prompt"], chapter_dict[chapter_name]["score_prompt"],chapter_dict[chapter_name]["require_tools"]))
|
||||||
)
|
No+=1
|
||||||
self.agents[id] = agent
|
chapter_chain[0].Focus()
|
||||||
return id, agent
|
|
||||||
|
|
||||||
|
# Prepare the tools for the agent
|
||||||
|
service_toolkit = FlexServiceToolkit()
|
||||||
def new_agent_with_chain(self, chapter_chain = None, id = None):
|
# for tool_function in unity_function_list:
|
||||||
'''
|
# service_toolkit.add(tool_function)
|
||||||
|
agent = ChapterChainAgent(
|
||||||
'''
|
name=id,
|
||||||
if chapter_chain is None:
|
model_config_name="openai_cfg",
|
||||||
chapter_chain = EMPTY_CHAPTER_CHAIN
|
verbose=True,
|
||||||
|
service_toolkit=service_toolkit,
|
||||||
# Prepare the tools for the agent
|
max_iters=5,
|
||||||
service_toolkit = FlexServiceToolkit()
|
chapter_chain=chapter_chain,
|
||||||
# for tool_function in unity_function_list:
|
root_path = root_path,
|
||||||
# service_toolkit.add(tool_function)
|
)
|
||||||
agent = ChapterChainAgent(
|
self.agents[id] = agent
|
||||||
name="assistant",
|
self.agent_to_id[agent] = id
|
||||||
model_config_name="openai_cfg",
|
agent.agent_manager = self
|
||||||
verbose=True,
|
return id, agent
|
||||||
service_toolkit=service_toolkit,
|
|
||||||
max_iters=5,
|
def message_pass(self, agent, messagetype, message):
|
||||||
chapter_chain=EMPTY_CHAPTER_CHAIN
|
id = self.agent_to_id[agent]
|
||||||
)
|
print("message_pass", id, messagetype, message)
|
||||||
if id is None: id = uuid.uuid4()
|
with self.app.app_context():
|
||||||
self.agents[id] = agent
|
try:
|
||||||
return id, agent
|
self.socketio.emit(messagetype, message, room=id, namespace='/agent')
|
||||||
|
except Exception as e:
|
||||||
|
print("message_pass",e)
|
||||||
def get_agent(self, id=None):
|
|
||||||
'''
|
def system_message(self, message):
|
||||||
如果在get agent之前没有new agent,并用id进行访问,就返回一个章节链为空的agent
|
with self.app.app_context():
|
||||||
'''
|
try:
|
||||||
if id:
|
self.socketio.emit('system_message', message, room=id, namespace='/agent')
|
||||||
if id in self.agents:
|
except Exception as e:
|
||||||
return self.agents[id]
|
print("ERROR: system_message",e)
|
||||||
self.agents[id] = self.new_agent(id)[1]
|
|
||||||
else:
|
|
||||||
id = str(uuid.uuid4())
|
def save_chapter_memory(self, agent,course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal):
|
||||||
self.agents[id] = self.new_agent()[1]
|
id = self.agent_to_id[agent]
|
||||||
return id, self.agents[id]
|
self.app.my_function.save_chapter_memory(id, course_id, lesson_id, subchapter_title, mem_list, score, is_rebuttal)
|
||||||
|
|
||||||
|
|
||||||
def invoke(self,id, query, user_backboard):
|
def new_agent_with_chain(self, chapter_chain = None, id = None):
|
||||||
msg = Msg("user", query, role="user")
|
if chapter_chain is None:
|
||||||
return self.agents[id](msg, user_backboard = user_backboard)
|
chapter_chain = EMPTY_CHAPTER_CHAIN
|
||||||
|
|
||||||
|
# Prepare the tools for the agent
|
||||||
import time
|
service_toolkit = FlexServiceToolkit()
|
||||||
if __name__ == '__main__':
|
# for tool_function in unity_function_list:
|
||||||
# tool_demo = ToolDemo("Lava")
|
# service_toolkit.add(tool_function)
|
||||||
# response = tool_demo.invoke("I want such a Gurouce, when use it, it will be thrown and fly towards the mouse position for a short time, and stop. And will damage Enemy who step on it. I call it Lava Gurouce.")
|
agent = ChapterChainAgent(
|
||||||
# print(response)
|
name="assistant",
|
||||||
# Start the WebSocket server in a separate thread
|
model_config_name="openai_cfg",
|
||||||
manager = AgentManager()
|
verbose=True,
|
||||||
id, agent = manager.new_agent()
|
service_toolkit=service_toolkit,
|
||||||
|
max_iters=5,
|
||||||
# Main thread logic
|
chapter_chain=EMPTY_CHAPTER_CHAIN
|
||||||
try:
|
)
|
||||||
# Your code that might be interrupted
|
if id is None: id = uuid.uuid4()
|
||||||
while True:
|
self.agents[id] = agent
|
||||||
input_data = input("用户:")
|
return id, agent
|
||||||
print(manager.invoke(id, input_data))
|
|
||||||
|
|
||||||
except KeyboardInterrupt:
|
def get_agent(self, id=None):
|
||||||
print("Process interrupted by user.")
|
'''
|
||||||
# You can add any cleanup code here if needed
|
如果在get agent之前没有new agent,并用id进行访问,就返回一个章节链为空的agent
|
||||||
finally:
|
'''
|
||||||
print("Exiting program.")
|
if id:
|
||||||
# Code to run before the program exits
|
if id in self.agents:
|
||||||
|
return self.agents[id]
|
||||||
|
self.agents[id] = self.new_agent(id)[1]
|
||||||
|
else:
|
||||||
|
id = str(uuid.uuid4())
|
||||||
|
self.agents[id] = self.new_agent()[1]
|
||||||
|
return id, self.agents[id]
|
||||||
|
|
||||||
|
|
||||||
|
def invoke(self,id, query, user_backboard, reset=False):
|
||||||
|
msg = Msg("user", query, role="user")
|
||||||
|
agent = self.agents[id]
|
||||||
|
res = agent(msg, user_backboard=user_backboard)
|
||||||
|
return res
|
||||||
|
# 暂时取消生成器的写法
|
||||||
|
# 假设 agent 是一个生成器
|
||||||
|
# if reset or not hasattr(agent, '_generator'):
|
||||||
|
# agent._generator = agent(msg, user_backboard=user_backboard)
|
||||||
|
|
||||||
|
# try:
|
||||||
|
# response = next(agent._generator)
|
||||||
|
# yield response
|
||||||
|
# except StopIteration:
|
||||||
|
# return
|
||||||
|
|
||||||
|
def function_call(self, id, arg_function):
|
||||||
|
agent = self.agents[id]
|
||||||
|
return agent.function_call(arg_function)
|
||||||
|
|
||||||
|
def change_language(self, id, language):
|
||||||
|
agent = self.agents[id]
|
||||||
|
agent.change_language(language)
|
||||||
|
|
||||||
|
def sample_judge(self, id, bb):
|
||||||
|
agent = self.agents[id]
|
||||||
|
|
||||||
|
with self.app.app_context():
|
||||||
|
try:
|
||||||
|
print(bb.get_active_file_reletive_path())
|
||||||
|
assert bb is not None and bb.active_file_path != "" , "no path specified"
|
||||||
|
if bb.get_active_file_reletive_path().endswith(".py"):
|
||||||
|
self.socketio.emit('terminal', {'data': f"python {bb.get_active_file_reletive_path()}"}, room=id, namespace='/vscode')
|
||||||
|
self.socketio.emit('system_message', "代码试运行尚在建设,推荐直接通过命令行执行!", room=id, namespace='/agent')
|
||||||
|
else:
|
||||||
|
self.socketio.emit('system_message', "代码试运行尚仅支持python文件", room=id, namespace='/agent')
|
||||||
|
except Exception as e:
|
||||||
|
print(e)
|
||||||
|
if (str(e) == "no path specified"):
|
||||||
|
self.socketio.emit("system_message", "未加载IDE文件同步,请尝试重新打开IDE文件或刷新页面,并确保插件已连接", room=id, namespace='/agent')
|
||||||
|
|
||||||
|
def judge(self, id, bb):
|
||||||
|
agent = self.agents[id]
|
||||||
|
with self.app.app_context():
|
||||||
|
try:
|
||||||
|
if (agent.chapter_chain[agent.chapter_chain_now].append_tools is not None and len(agent.chapter_chain[agent.chapter_chain_now].append_tools)):
|
||||||
|
for tool, tool_kwargs in agent.chapter_chain[agent.chapter_chain_now].append_tools:
|
||||||
|
if tool.__name__ == "judge":
|
||||||
|
print(bb.get_active_file_reletive_path())
|
||||||
|
assert bb is not None and bb.active_file_path != "" , "no path specified"
|
||||||
|
if bb.get_active_file_reletive_path().endswith(".py"):
|
||||||
|
# self.socketio.emit('terminal', {'data': f"python {bb.get_active_file_reletive_path()}"}, room=id, namespace='/vscode')
|
||||||
|
self.socketio.emit('system_message', "代码评测中,请稍后", room=id, namespace='/agent')
|
||||||
|
agent.function_call({'name':'judge','arguments':{'filepath': bb.get_active_file_reletive_path()}})
|
||||||
|
else:
|
||||||
|
self.socketio.emit('system_message', "代码评测尚仅支持python文件", room=id, namespace='/agent')
|
||||||
|
|
||||||
|
else:
|
||||||
|
with self.app.app_context():
|
||||||
|
self.socketio.emit("system_message", "本章学习无需评测", room=id, namespace='/agent')
|
||||||
|
else:
|
||||||
|
with self.app.app_context():
|
||||||
|
self.socketio.emit("system_message", "本章学习无需评测", room=id, namespace='/agent')
|
||||||
|
except Exception as e:
|
||||||
|
if (str(e) == "no path specified"):
|
||||||
|
self.socketio.emit("system_message", "未加载IDE文件同步,请尝试重新打开IDE文件或刷新页面,并确保插件已连接", room=id, namespace='/agent')
|
||||||
|
|
||||||
|
|
||||||
|
import time
|
||||||
|
if __name__ == '__main__':
|
||||||
|
manager = AgentManager()
|
||||||
|
id, agent = manager.new_agent()
|
||||||
|
|
||||||
|
# Main thread logic
|
||||||
|
try:
|
||||||
|
# Your code that might be interrupted
|
||||||
|
while True:
|
||||||
|
input_data = input("用户:")
|
||||||
|
print(manager.invoke(id, input_data))
|
||||||
|
|
||||||
|
except KeyboardInterrupt:
|
||||||
|
print("Process interrupted by user.")
|
||||||
|
# You can add any cleanup code here if needed
|
||||||
|
finally:
|
||||||
|
print("Exiting program.")
|
||||||
|
# Code to run before the program exits
|
||||||
|
|||||||
Binary file not shown.
Binary file not shown.
54
AlgoriAgent/projects/algoriAgent/tools/file_tools.py
Normal file
54
AlgoriAgent/projects/algoriAgent/tools/file_tools.py
Normal file
@@ -0,0 +1,54 @@
|
|||||||
|
from agentscope.service.service_toolkit import ServiceFunction
|
||||||
|
from agentscope.service import (
|
||||||
|
ServiceToolkit,
|
||||||
|
ServiceResponse,
|
||||||
|
ServiceExecStatus,
|
||||||
|
)
|
||||||
|
import os
|
||||||
|
def read_file(filepath:str, root_path:str):
|
||||||
|
"""Read the file and return the content. Remember use 'judge' function if you want to judge file, instead of this function.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
filepath (`str`): The path to the file.
|
||||||
|
root_path (`str`): The root path of now student's workspace.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
content (`str`): The content of the file.
|
||||||
|
"""
|
||||||
|
# 从books/code_tests/name/中获取所有.in文件
|
||||||
|
|
||||||
|
filepath = os.path.join('..', root_path, filepath)
|
||||||
|
try:
|
||||||
|
with open(filepath, 'r') as f:
|
||||||
|
content = f.read()
|
||||||
|
except Exception as e:
|
||||||
|
status = ServiceExecStatus.ERROR
|
||||||
|
content = str(e)
|
||||||
|
return ServiceResponse(status, (content))
|
||||||
|
|
||||||
|
status = ServiceExecStatus.SUCCESS
|
||||||
|
return ServiceResponse(status, ('```\n'+content+'```\n'))
|
||||||
|
|
||||||
|
|
||||||
|
def write_file(filepath:str, content:str, root_path:str):
|
||||||
|
"""Write content to the file.
|
||||||
|
|
||||||
|
Args:
|
||||||
|
filepath (`str`): The path to the file.
|
||||||
|
content (`str`): The content to be written to the file.
|
||||||
|
root_path (`str`): The root path of now student's workspace.
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
None.
|
||||||
|
"""
|
||||||
|
filepath = os.path.join('..', root_path, filepath)
|
||||||
|
try:
|
||||||
|
with open(filepath, 'w') as f:
|
||||||
|
f.write(content)
|
||||||
|
except Exception as e:
|
||||||
|
status = ServiceExecStatus.ERROR
|
||||||
|
return ServiceResponse(status, None)
|
||||||
|
status = ServiceExecStatus.SUCCESS
|
||||||
|
return ServiceResponse(status, None)
|
||||||
|
|
||||||
|
file_tools = [read_file, write_file]
|
||||||
@@ -1,64 +1,78 @@
|
|||||||
from agentscope.service.service_toolkit import ServiceFunction
|
from agentscope.service.service_toolkit import ServiceFunction
|
||||||
from agentscope.service import (
|
from agentscope.service import (
|
||||||
ServiceToolkit,
|
ServiceToolkit,
|
||||||
ServiceResponse,
|
ServiceResponse,
|
||||||
ServiceExecStatus,
|
ServiceExecStatus,
|
||||||
)
|
)
|
||||||
import os
|
import os
|
||||||
def judge(filepath:str, name: str):
|
def judge(filepath:str, name: str, course_id: str, lesson_id: str, root_path:str):
|
||||||
"""Call this method to judge the student's solution after they have completed the problem.
|
"""Call this method to judge the student's solution after they have completed the problem.
|
||||||
|
|
||||||
Args:
|
Args:
|
||||||
filepath (`str`): The path to the file containing the student's solution.
|
filepath (`str`): The path to the file containing the student's solution.
|
||||||
name (`str`): The name of the problem.
|
name (`str`): The name of the problem.
|
||||||
|
course_id (`str`): The id of the course.
|
||||||
Returns:
|
lesson_id (`str`): The id of the lesson.
|
||||||
Report `tuple(int,str)`: The report of the student's solution.
|
root_path (`str`): The root path of the user's workspace project.
|
||||||
"""
|
|
||||||
# 从books/code_tests/name/中获取所有.in文件
|
Returns:
|
||||||
|
Report `tuple(int,str)`: The report of the student's solution.
|
||||||
directory = 'books/code_tests/'+name
|
"""
|
||||||
# 如果目录不存在,报错
|
# 从books/code_tests/name/中获取所有.in文件
|
||||||
if not os.path.exists(directory):
|
|
||||||
status = ServiceExecStatus.FAILED
|
directory = 'books/code_tests/'+course_id+'/'+name
|
||||||
return ServiceResponse(status, f"The name {name} is not found.")
|
# 如果目录不存在,报错
|
||||||
files = os.listdir(directory)
|
if not os.path.exists(directory):
|
||||||
in_files = [file for file in files if file.endswith('.in')]
|
status = ServiceExecStatus.FAILED
|
||||||
save_dir = os.path.dirname(filepath)
|
return ServiceResponse(status, f"The name {name} is not found.")
|
||||||
Report = ""
|
files = os.listdir(directory)
|
||||||
passed_num=0
|
in_files = [file for file in files if file.endswith('.in')]
|
||||||
failed_num=0
|
save_dir = root_path
|
||||||
for file in in_files:
|
Report = ""
|
||||||
os.remove(os.path.join(save_dir, f"_{name}.out"))
|
passed_num=0
|
||||||
cmd = "cat " + os.path.join(directory, file) + " | " + "python " + filepath +" > " + os.path.join(save_dir, f"_{name}.out")
|
failed_num=0
|
||||||
os.system(cmd)
|
erroroutput = ""
|
||||||
# 比较结果
|
exceptoutput=""
|
||||||
re = ""
|
for file in in_files:
|
||||||
if compare_file(os.path.join(save_dir, f"_{name}.out"), os.path.join(directory, file.replace(".in", ".out"))):
|
file_path = os.path.join(save_dir, f"_{name}.out")
|
||||||
re = "Passed {file}"
|
if os.path.exists(file_path):
|
||||||
passed_num += 1
|
os.remove(file_path)
|
||||||
else:
|
with open(file_path, 'w') as ff:
|
||||||
re = "Failed {file}"
|
ff.write("")
|
||||||
failed_num += 1
|
|
||||||
Report = Report + re + "\n"
|
cmd = "cat " + os.path.join(directory, file) + " | " + "python " + os.path.join(root_path, filepath) +" > " + os.path.join(save_dir, f"_{name}.out")
|
||||||
os.remove(os.path.join(save_dir, f"_{name}.out"))
|
os.system(cmd)
|
||||||
score = int (100 * passed_num / (passed_num + failed_num))
|
# 比较结果
|
||||||
|
re = ""
|
||||||
|
if compare_file(os.path.join(save_dir, f"_{name}.out"), os.path.join(directory, file.replace(".in", ".out"))):
|
||||||
|
re = f"Passed {file}"
|
||||||
status = ServiceExecStatus.SUCCESS
|
passed_num += 1
|
||||||
return ServiceResponse(status, (Report, score))
|
else:
|
||||||
|
re = f"Failed {file}"
|
||||||
|
failed_num += 1
|
||||||
def compare_file(path1:str, path2:str):
|
with open(os.path.join(directory, file.replace(".in", ".out")),'r') as f: exceptoutput = f.read()
|
||||||
"""
|
with open(os.path.join(save_dir, f"_{name}.out"),'r') as f: erroroutput = f.read()
|
||||||
Compare two files and return true if they are the same.
|
Report = Report + re + "\n"
|
||||||
"""
|
os.remove(os.path.join(save_dir, f"_{name}.out"))
|
||||||
with open(path1, 'r') as f1, open(path2, 'r') as f2:
|
score = int (100 * passed_num / (passed_num + failed_num))
|
||||||
# 逐行比较
|
|
||||||
for line1, line2 in zip(f1, f2):
|
|
||||||
if line1.strip() != line2.strip():
|
|
||||||
return False
|
status = ServiceExecStatus.SUCCESS
|
||||||
return True
|
return ServiceResponse(status, (score, f"评测得分为 {score}, 在 {passed_num + failed_num} 个测试用例中通过了 {passed_num}个。最后一个错误样例期望输出:'{exceptoutput}',但你的输出:'{erroroutput}"))
|
||||||
|
|
||||||
|
|
||||||
|
def compare_file(path1:str, path2:str):
|
||||||
|
"""
|
||||||
|
Compare two files and return true if they are the same.
|
||||||
|
"""
|
||||||
|
with open(path1, 'r') as f1, open(path2, 'r') as f2:
|
||||||
|
# 逐行比较
|
||||||
|
print('-------------------COMPARE-------------------------')
|
||||||
|
for line1, line2 in zip(f1, f2):
|
||||||
|
print(line1.strip(), "||",line2.strip())
|
||||||
|
if line1.strip() != line2.strip():
|
||||||
|
return False
|
||||||
|
return True
|
||||||
|
|
||||||
judge_tools = [judge]
|
judge_tools = [judge]
|
||||||
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user