From 7396fb3f4358ad2172160d719563a4ff4bca2ea0 Mon Sep 17 00:00:00 2001 From: KirbytroNic0528 <133230754+KirbytroNic0528@users.noreply.github.com> Date: Mon, 30 Sep 2024 18:02:08 +0800 Subject: [PATCH 01/94] workflow for MoonBit Test Agent Ospp 2024 --- .github/workflows/coverage_and_test.yml | 142 ++++++++++++++++++++++++ 1 file changed, 142 insertions(+) create mode 100644 .github/workflows/coverage_and_test.yml diff --git a/.github/workflows/coverage_and_test.yml b/.github/workflows/coverage_and_test.yml new file mode 100644 index 000000000..3d619b168 --- /dev/null +++ b/.github/workflows/coverage_and_test.yml @@ -0,0 +1,142 @@ +name: coverage_and_test + +on: + push: + branches: + - main + pull_request: + +jobs: + build: + strategy: + matrix: + os: [ ubuntu-latest ] + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v4 + + - name: install + run: | + curl -fsSL https://cli.moonbitlang.com/install/unix.sh | bash + echo "$HOME/.moon/bin" >> $GITHUB_PATH + - name: moon version + run: | + moon version --all + moonrun --version + + - name: moon check + run: moon check --deny-warn + + - name: moon info + run: | + moon info + git diff --exit-code + + - name: Set ulimit and run moon test + run: | + ulimit -s 8176 + moon test --target all + moon test --release --target all + + - name: moon bundle + run: moon bundle --all + + - name: check core size + run: find ./target -name '*.core' | xargs ls -lh + + - name: format diff + run: | + moon fmt + git diff --exit-code + + - name: Set up Python + uses: actions/checkout@v4 + with: + python-version: '3.9' + + - name: Install dependencies + run: | + sudo apt install python3-pip + pip install -r scripts/requirements.txt + + test: + runs-on: ubuntu-latest + continue-on-error: true + steps: + - uses: actions/checkout@v4 + + - name: initial moon test + run: moon test --enable-coverage + + - name: initial coverage report + run: | + moon coverage report -f summary summary > coverage_summary.txt + cat coverage_summary.txt >> "$GITHUB_STEP_SUMMARY" + + + - name: loop coverage improvement + id: loop-coverage + run: | + prev_coverage=$(cat coverage_summary.txt | grep 'Total Coverage' | awk '{print $NF}' | tr -d '%') + max_iterations=5 + iteration=0 + coverage_improved=true + + while [ "$coverage_improved" = true ] && [ $iteration -lt $max_iterations ]; do + python Agent.py --api_key ${{ secrets.API_KEY }} + + moon test --enable-coverage + + moon coverage report -f summary summary > coverage_summary.txt + + new_coverage=$(cat coverage_summary.txt | grep 'Total Coverage' | awk '{print $NF}' | tr -d '%') + + if [ $(echo "$new_coverage > $prev_coverage" | bc) -eq 1 ]; then + prev_coverage=$new_coverage + echo "Coverage improved to $new_coverage%" + else + coverage_improved=false + echo "Coverage did not improve. Stopping loop." + fi + iteration=$((iteration + 1)) + done + + echo "Final coverage: $new_coverage%" + echo "::set-output name=final_coverage::$new_coverage" + + - name: coverage report + run: | + cat coverage_summary.txt >> "$GITHUB_STEP_SUMMARY" + moon coverage report -f coveralls -o codecov_report.json --service-name github --service-job-id "$GITHUB_RUN_NUMBER" --service-pull-request "${{ github.event.number }}" --send-to coveralls + env: + COVERALLS_REPO_TOKEN: ${{ secrets.GITHUB_TOKEN }} + + typo-check: + runs-on: ubuntu-latest + timeout-minutes: 10 + env: + FORCE_COLOR: 1 + TYPOS_VERSION: v1.19.0 + steps: + - name: download typos + run: curl -LsSf https://github.com/crate-ci/typos/releases/download/$TYPOS_VERSION/typos-$TYPOS_VERSION-x86_64-unknown-linux-musl.tar.gz | tar zxf - -C ${CARGO_HOME:-~/.cargo}/bin + + - name: Checkout repository + uses: actions/checkout@v4 + with: + ref: ${{ github.event.pull_request.head.sha }} + + - name: check typos + run: typos + + license-header-check: + runs-on: ubuntu-latest + env: + HAWKEYE_VERSION: v5.5.1 + steps: + - uses: actions/checkout@v4 + - name: Download HawkEye + run: curl --proto '=https' --tlsv1.2 -LsSf https://github.com/korandoru/hawkeye/releases/download/$HAWKEYE_VERSION/hawkeye-installer.sh | sh + - name: Check License Header + run: hawkeye check \ No newline at end of file From 557f8515f0555812a5b0814b0efd91504444552f Mon Sep 17 00:00:00 2001 From: KirbytroNic0528 <133230754+KirbytroNic0528@users.noreply.github.com> Date: Mon, 30 Sep 2024 18:20:18 +0800 Subject: [PATCH 02/94] MoonBit Test Agent Code Ospp 2024 --- scripts/gettest.py | 36 ++++++++++++++++++++++++++++++++++++ scripts/readcoverage.py | 35 +++++++++++++++++++++++++++++++++++ scripts/requirement.txt | 5 +++++ scripts/testagent.py | 30 ++++++++++++++++++++++++++++++ scripts/writedown.py | 7 +++++++ 5 files changed, 113 insertions(+) create mode 100644 scripts/gettest.py create mode 100644 scripts/readcoverage.py create mode 100644 scripts/requirement.txt create mode 100644 scripts/testagent.py create mode 100644 scripts/writedown.py diff --git a/scripts/gettest.py b/scripts/gettest.py new file mode 100644 index 000000000..d07bcd4c7 --- /dev/null +++ b/scripts/gettest.py @@ -0,0 +1,36 @@ +from langchain_community.chat_models import ChatZhipuAI +from langchain_core.output_parsers import StrOutputParser +from langchain_core.prompts import ChatPromptTemplate + +def generate_test_code(moonbit_code,path,api_key): + test_prompt = ChatPromptTemplate.from_template( + """作为一名MoonBit语言工程师,你的任务是编写一系列测试用例来验证项目的正确性。 + 请根据以下提供的格式,结合文件名{path}理解函数的用途,对给出的MoonBit函数编写对应的测试用例, + 以下是你需要提供的测试用例格式参考: + test {{ + assert_eq!(f(x)) + assert_eq!(f(x)) + }} + 需要提供测试用例的MoonBit函数为{moonbit_code}。 + 注意,你的输出中只需要包含测试用例的代码,不需要包括分析过程以及任何其他语句。 + 同时,你生成的是moonbit语言的测试用例,请不要将moonbit语言与其他语言混淆 + """ + ) + + test_llm = ChatZhipuAI( + api_key=api_key, + model="glm-4-plus", + temperature=0.5, + max_tokens=2048 + ) + + test_retriever_chain = ( + test_prompt + | test_llm + | StrOutputParser() + ) + test_code = test_retriever_chain.invoke({ + "moonbit_code": moonbit_code, + "path":path + }) + return test_code \ No newline at end of file diff --git a/scripts/readcoverage.py b/scripts/readcoverage.py new file mode 100644 index 000000000..3ba3d3952 --- /dev/null +++ b/scripts/readcoverage.py @@ -0,0 +1,35 @@ +from langchain_community.chat_models import ChatZhipuAI +from langchain_core.output_parsers import StrOutputParser +from langchain_core.prompts import ChatPromptTemplate + +def read_coverage(moonbit_code, index, api_key): + read_prompt = ChatPromptTemplate.from_template( + """你是一位技术高超的moonbit工程师,现在你需要读入moonbit语言的代码以及测试未覆盖代码行数的索引 + 根据索引找出测试未覆盖的代码并返回该行代码所在函数的函数 + 需要读入的MoonBit代码:{moonbit_code},未覆盖代码行数的索引:{index} + 注意,你的输出中只需要包含未覆盖的函数,不需要包含分析过程和任何其他语句。 + """ + ) + + read_llm = ChatZhipuAI( + api_key=api_key, + model="glm-4-plus", + temperature=0.5, + max_tokens=2048 + ) + + read_retriever_chain = ( + read_prompt + | read_llm + | StrOutputParser() + ) + response = read_retriever_chain.invoke({ + "moonbit_code": moonbit_code, + "index": index + }) + return response + + + + + diff --git a/scripts/requirement.txt b/scripts/requirement.txt new file mode 100644 index 000000000..fe9ec93cf --- /dev/null +++ b/scripts/requirement.txt @@ -0,0 +1,5 @@ +langchain +argparse +langchain_community +glob +pyjwt \ No newline at end of file diff --git a/scripts/testagent.py b/scripts/testagent.py new file mode 100644 index 000000000..df0fdc18f --- /dev/null +++ b/scripts/testagent.py @@ -0,0 +1,30 @@ +import argparse +import json +from Agent.readcoverage import read_coverage +from Agent.gettest import generate_test_code +from Agent.writedown import writedown_test_files +def main(): + with open('coveralls.json', 'r') as file: + data = json.load(file) + + parser = argparse.ArgumentParser(description="用于加载API密钥。") + parser.add_argument('--api_key', default="4a478b99108ee30c1ae4aaa0aefe6632.X8sj7A6gaBgWh9AE", type=str, help='API密钥') + args = parser.parse_args() + zhipuai_api_key = args.api_key + + for source_file in data['source_files']: + with open(source_file['name'], "r") as codefile: + index = [index for index, value in enumerate(source_file['coverage']) if value == 0] + if index!=[]: + print(index) + moonbit_code = codefile.read() + response = read_coverage(moonbit_code,index, zhipuai_api_key) + print("未覆盖的函数声明为"+response) + response = generate_test_code(response,source_file['name'],zhipuai_api_key) + test_code = response.replace("```moonbit\n", "").rstrip("```") + writedown_test_files(source_file['name'], test_code) + print("测试用例为"+test_code) + + +if __name__ == "__main__": + main() \ No newline at end of file diff --git a/scripts/writedown.py b/scripts/writedown.py new file mode 100644 index 000000000..9dbee69b7 --- /dev/null +++ b/scripts/writedown.py @@ -0,0 +1,7 @@ +import os + +def writedown_test_files(path, test_code): + with open(path, 'a') as file: + file.write(test_code + '\n') + + print(f"test_code has been written to {path}") \ No newline at end of file From ce0bacc8976f8ca071cb6fc2be0f1cda9ef0a416 Mon Sep 17 00:00:00 2001 From: KirbytroNic0528 <133230754+KirbytroNic0528@users.noreply.github.com> Date: Wed, 9 Oct 2024 09:41:18 +0800 Subject: [PATCH 03/94] Update gettest.py --- scripts/gettest.py | 21 +++++++-------------- 1 file changed, 7 insertions(+), 14 deletions(-) diff --git a/scripts/gettest.py b/scripts/gettest.py index d07bcd4c7..1c24324da 100644 --- a/scripts/gettest.py +++ b/scripts/gettest.py @@ -2,7 +2,8 @@ from langchain_core.output_parsers import StrOutputParser from langchain_core.prompts import ChatPromptTemplate -def generate_test_code(moonbit_code,path,api_key): + +def generate_test_code(moonbit_code, path, api_key): test_prompt = ChatPromptTemplate.from_template( """作为一名MoonBit语言工程师,你的任务是编写一系列测试用例来验证项目的正确性。 请根据以下提供的格式,结合文件名{path}理解函数的用途,对给出的MoonBit函数编写对应的测试用例, @@ -18,19 +19,11 @@ def generate_test_code(moonbit_code,path,api_key): ) test_llm = ChatZhipuAI( - api_key=api_key, - model="glm-4-plus", - temperature=0.5, - max_tokens=2048 + api_key=api_key, model="glm-4-plus", temperature=0.5 ) - test_retriever_chain = ( - test_prompt - | test_llm - | StrOutputParser() + test_retriever_chain = test_prompt | test_llm | StrOutputParser() + test_code = test_retriever_chain.invoke( + {"moonbit_code": moonbit_code, "path": path} ) - test_code = test_retriever_chain.invoke({ - "moonbit_code": moonbit_code, - "path":path - }) - return test_code \ No newline at end of file + return test_code From 25c1f826acd60146b14febb84dd3803ac1e47d65 Mon Sep 17 00:00:00 2001 From: KirbytroNic0528 <133230754+KirbytroNic0528@users.noreply.github.com> Date: Wed, 9 Oct 2024 09:42:11 +0800 Subject: [PATCH 04/94] Update readcoverage.py --- scripts/readcoverage.py | 19 +++++-------------- 1 file changed, 5 insertions(+), 14 deletions(-) diff --git a/scripts/readcoverage.py b/scripts/readcoverage.py index 3ba3d3952..b15752b32 100644 --- a/scripts/readcoverage.py +++ b/scripts/readcoverage.py @@ -2,6 +2,7 @@ from langchain_core.output_parsers import StrOutputParser from langchain_core.prompts import ChatPromptTemplate + def read_coverage(moonbit_code, index, api_key): read_prompt = ChatPromptTemplate.from_template( """你是一位技术高超的moonbit工程师,现在你需要读入moonbit语言的代码以及测试未覆盖代码行数的索引 @@ -12,24 +13,14 @@ def read_coverage(moonbit_code, index, api_key): ) read_llm = ChatZhipuAI( - api_key=api_key, - model="glm-4-plus", - temperature=0.5, - max_tokens=2048 + api_key=api_key, model="glm-4-0520", temperature=0.5 ) - read_retriever_chain = ( - read_prompt - | read_llm - | StrOutputParser() + read_retriever_chain = read_prompt | read_llm | StrOutputParser() + response = read_retriever_chain.invoke( + {"moonbit_code": moonbit_code, "index": index} ) - response = read_retriever_chain.invoke({ - "moonbit_code": moonbit_code, - "index": index - }) return response - - From 8ac81239f648744eb9489914ff874f047170dea0 Mon Sep 17 00:00:00 2001 From: KirbytroNic0528 <133230754+KirbytroNic0528@users.noreply.github.com> Date: Wed, 9 Oct 2024 09:42:35 +0800 Subject: [PATCH 05/94] Update requirement.txt --- scripts/requirement.txt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/scripts/requirement.txt b/scripts/requirement.txt index fe9ec93cf..05916076e 100644 --- a/scripts/requirement.txt +++ b/scripts/requirement.txt @@ -1,5 +1,5 @@ -langchain -argparse -langchain_community -glob -pyjwt \ No newline at end of file +langchain 0.3.1 +argparse 1.4.0 +langchain_community 0.3.1 +pyjwt 2.9.0 +zhipuai 2.1.2 From 7ce6b71fe58aa2c9d38e724cfff87c79d4a28614 Mon Sep 17 00:00:00 2001 From: KirbytroNic0528 <133230754+KirbytroNic0528@users.noreply.github.com> Date: Wed, 9 Oct 2024 09:43:19 +0800 Subject: [PATCH 06/94] Update testagent.py --- scripts/testagent.py | 55 +++++++++++++++++++++++++++++--------------- 1 file changed, 36 insertions(+), 19 deletions(-) diff --git a/scripts/testagent.py b/scripts/testagent.py index df0fdc18f..2b79eaa53 100644 --- a/scripts/testagent.py +++ b/scripts/testagent.py @@ -1,30 +1,47 @@ import argparse import json -from Agent.readcoverage import read_coverage -from Agent.gettest import generate_test_code -from Agent.writedown import writedown_test_files +from scripts.readcoverage import read_coverage +from scripts.gettest import generate_test_code +from scripts.writedown import writedown_and_test + + def main(): - with open('coveralls.json', 'r') as file: + with open("coveralls.json", "r") as file: data = json.load(file) parser = argparse.ArgumentParser(description="用于加载API密钥。") - parser.add_argument('--api_key', default="4a478b99108ee30c1ae4aaa0aefe6632.X8sj7A6gaBgWh9AE", type=str, help='API密钥') + parser.add_argument( + "--api_key", + type=str, + help="API密钥", + ) args = parser.parse_args() zhipuai_api_key = args.api_key - for source_file in data['source_files']: - with open(source_file['name'], "r") as codefile: - index = [index for index, value in enumerate(source_file['coverage']) if value == 0] - if index!=[]: - print(index) - moonbit_code = codefile.read() - response = read_coverage(moonbit_code,index, zhipuai_api_key) - print("未覆盖的函数声明为"+response) - response = generate_test_code(response,source_file['name'],zhipuai_api_key) - test_code = response.replace("```moonbit\n", "").rstrip("```") - writedown_test_files(source_file['name'], test_code) - print("测试用例为"+test_code) - + for source_file in data["source_files"]: + with open(source_file["name"], "r") as codefile: + indexs = [ + indexs + for indexs, value in enumerate(source_file["coverage"]) + if value == 0 + ] + if indexs: + print(indexs) + moonbit_code = codefile.read() + for index in indexs: + for attempt in range(3): + response = read_coverage(moonbit_code, index, zhipuai_api_key) + print("未覆盖的函数声明为" + response) + response = generate_test_code( + response, source_file["name"], zhipuai_api_key + ) + test_code = response.replace("```moonbit\n", "").rstrip("```") + print("测试用例为" + test_code) + result = writedown_and_test(response, source_file["name"]) + + if result == 0: + break + if __name__ == "__main__": - main() \ No newline at end of file + main() From 3d4b2af2d00431c0b8d74efce44a8e064d8fdaa5 Mon Sep 17 00:00:00 2001 From: KirbytroNic0528 <133230754+KirbytroNic0528@users.noreply.github.com> Date: Wed, 9 Oct 2024 09:43:49 +0800 Subject: [PATCH 07/94] Update writedown.py --- scripts/writedown.py | 29 +++++++++++++++++++++++++---- 1 file changed, 25 insertions(+), 4 deletions(-) diff --git a/scripts/writedown.py b/scripts/writedown.py index 9dbee69b7..e2f88218d 100644 --- a/scripts/writedown.py +++ b/scripts/writedown.py @@ -1,7 +1,28 @@ +import subprocess import os +def writedown_test_files(file_path, test_code): + with open(file_path, "a") as file: + file.write(test_code + "\n") -def writedown_test_files(path, test_code): - with open(path, 'a') as file: - file.write(test_code + '\n') + print(f"test_code has been written to {file_path}") - print(f"test_code has been written to {path}") \ No newline at end of file + +def writedown_and_test(response, file_path): + folder_path = os.path.dirname(file_path) + testcode_path = os.path.join(folder_path, "testcode.mbt") + with open(testcode_path, "w", encoding="utf-8") as file: + file.write(response) + try: + result = subprocess.run( + ["moon", "test", "-f", file_path], capture_output=True, text=True + ) + if result.returncode != 0: + os.remove(testcode_path) + return 1 + else: + os.remove(testcode_path) + writedown_test_files(file_path, response) + return 0 + except Exception as e: + os.remove(testcode_path) + return 1 From fb1510cee784efb15557deaa62237c64fac7840b Mon Sep 17 00:00:00 2001 From: KirbytroNic0528 <133230754+KirbytroNic0528@users.noreply.github.com> Date: Wed, 9 Oct 2024 10:48:39 +0800 Subject: [PATCH 08/94] rename requirement.txt to requirements.txt --- scripts/{requirement.txt => requirements.txt} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename scripts/{requirement.txt => requirements.txt} (100%) diff --git a/scripts/requirement.txt b/scripts/requirements.txt similarity index 100% rename from scripts/requirement.txt rename to scripts/requirements.txt From 8fd37516e6cda738ff368f808ff207139da44524 Mon Sep 17 00:00:00 2001 From: KirbytroNic0528 <133230754+KirbytroNic0528@users.noreply.github.com> Date: Thu, 10 Oct 2024 23:19:30 +0800 Subject: [PATCH 09/94] Update requirements.txt --- scripts/requirements.txt | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/scripts/requirements.txt b/scripts/requirements.txt index 05916076e..fe73c180f 100644 --- a/scripts/requirements.txt +++ b/scripts/requirements.txt @@ -1,5 +1,5 @@ -langchain 0.3.1 -argparse 1.4.0 -langchain_community 0.3.1 -pyjwt 2.9.0 -zhipuai 2.1.2 +langchain==0.3.1 +argparse==1.4.0 +langchain_community==0.3.1 +pyjwt==2.9.0 +zhipuai==2.1.2 From 2022af8f81a21df58cece95ad579aa6c91f6a86b Mon Sep 17 00:00:00 2001 From: KirbytroNic0528 <133230754+KirbytroNic0528@users.noreply.github.com> Date: Fri, 11 Oct 2024 08:18:21 +0800 Subject: [PATCH 10/94] Update coverage_and_test.yml --- .github/workflows/coverage_and_test.yml | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/.github/workflows/coverage_and_test.yml b/.github/workflows/coverage_and_test.yml index 3d619b168..7c6aa73ec 100644 --- a/.github/workflows/coverage_and_test.yml +++ b/.github/workflows/coverage_and_test.yml @@ -57,7 +57,6 @@ jobs: - name: Install dependencies run: | - sudo apt install python3-pip pip install -r scripts/requirements.txt test: @@ -65,7 +64,12 @@ jobs: continue-on-error: true steps: - uses: actions/checkout@v4 - + + - name: install + run: | + curl -fsSL https://cli.moonbitlang.com/install/unix.sh | bash + echo "$HOME/.moon/bin" >> $GITHUB_PATH + - name: initial moon test run: moon test --enable-coverage @@ -139,4 +143,4 @@ jobs: - name: Download HawkEye run: curl --proto '=https' --tlsv1.2 -LsSf https://github.com/korandoru/hawkeye/releases/download/$HAWKEYE_VERSION/hawkeye-installer.sh | sh - name: Check License Header - run: hawkeye check \ No newline at end of file + run: hawkeye check From 2d4f6ef3ac16321d9be067f78a328928561f759b Mon Sep 17 00:00:00 2001 From: KirbytroNic0528 <133230754+KirbytroNic0528@users.noreply.github.com> Date: Fri, 11 Oct 2024 08:21:09 +0800 Subject: [PATCH 11/94] Update requirements.txt --- scripts/requirements.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/scripts/requirements.txt b/scripts/requirements.txt index fe73c180f..3d5ca123d 100644 --- a/scripts/requirements.txt +++ b/scripts/requirements.txt @@ -2,4 +2,3 @@ langchain==0.3.1 argparse==1.4.0 langchain_community==0.3.1 pyjwt==2.9.0 -zhipuai==2.1.2 From 7f340c88ee103595f2dd6dbe96ddd0ccbb764927 Mon Sep 17 00:00:00 2001 From: KirbytroNic0528 <133230754+KirbytroNic0528@users.noreply.github.com> Date: Fri, 11 Oct 2024 08:36:20 +0800 Subject: [PATCH 12/94] Update coverage_and_test.yml --- .github/workflows/coverage_and_test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/coverage_and_test.yml b/.github/workflows/coverage_and_test.yml index 7c6aa73ec..ba9b14bc7 100644 --- a/.github/workflows/coverage_and_test.yml +++ b/.github/workflows/coverage_and_test.yml @@ -75,7 +75,7 @@ jobs: - name: initial coverage report run: | - moon coverage report -f summary summary > coverage_summary.txt + moon coverage report -f summary > coverage_summary.txt cat coverage_summary.txt >> "$GITHUB_STEP_SUMMARY" From d01f5d122bfbbe9af7c6e28800867a3fe83137fe Mon Sep 17 00:00:00 2001 From: KirbytroNic0528 <133230754+KirbytroNic0528@users.noreply.github.com> Date: Fri, 11 Oct 2024 08:39:07 +0800 Subject: [PATCH 13/94] Update coverage_and_test.yml --- .github/workflows/coverage_and_test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/coverage_and_test.yml b/.github/workflows/coverage_and_test.yml index ba9b14bc7..1b8618b2c 100644 --- a/.github/workflows/coverage_and_test.yml +++ b/.github/workflows/coverage_and_test.yml @@ -88,7 +88,7 @@ jobs: coverage_improved=true while [ "$coverage_improved" = true ] && [ $iteration -lt $max_iterations ]; do - python Agent.py --api_key ${{ secrets.API_KEY }} + python scripts/testagent.py --api_key ${{ secrets.API_KEY }} moon test --enable-coverage From 6a92863c396f31b32a49cc99dea8955d245a30fd Mon Sep 17 00:00:00 2001 From: KirbytroNic0528 <133230754+KirbytroNic0528@users.noreply.github.com> Date: Fri, 11 Oct 2024 15:46:04 +0800 Subject: [PATCH 14/94] Update testagent.py --- scripts/testagent.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/testagent.py b/scripts/testagent.py index 2b79eaa53..f8adfdf5d 100644 --- a/scripts/testagent.py +++ b/scripts/testagent.py @@ -1,8 +1,8 @@ import argparse import json -from scripts.readcoverage import read_coverage -from scripts.gettest import generate_test_code -from scripts.writedown import writedown_and_test +from readcoverage import read_coverage +from gettest import generate_test_code +from writedown import writedown_and_test def main(): From f768ad9f6ab08a082e9acd1564e8fd55d28b2595 Mon Sep 17 00:00:00 2001 From: KirbytroNic0528 <133230754+KirbytroNic0528@users.noreply.github.com> Date: Fri, 11 Oct 2024 15:48:40 +0800 Subject: [PATCH 15/94] Update coverage_and_test.yml --- .github/workflows/coverage_and_test.yml | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/.github/workflows/coverage_and_test.yml b/.github/workflows/coverage_and_test.yml index 1b8618b2c..1facaf4af 100644 --- a/.github/workflows/coverage_and_test.yml +++ b/.github/workflows/coverage_and_test.yml @@ -64,7 +64,9 @@ jobs: continue-on-error: true steps: - uses: actions/checkout@v4 - + with: + python-version: '3.9' + - name: install run: | curl -fsSL https://cli.moonbitlang.com/install/unix.sh | bash @@ -78,7 +80,10 @@ jobs: moon coverage report -f summary > coverage_summary.txt cat coverage_summary.txt >> "$GITHUB_STEP_SUMMARY" - + - name: Install dependencies + run: | + pip install -r scripts/requirements.txt + - name: loop coverage improvement id: loop-coverage run: | From 88853dad1962a723497d52eab98a710b61976fb7 Mon Sep 17 00:00:00 2001 From: KirbytroNic0528 <133230754+KirbytroNic0528@users.noreply.github.com> Date: Fri, 11 Oct 2024 16:04:19 +0800 Subject: [PATCH 16/94] Update coverage_and_test.yml --- .github/workflows/coverage_and_test.yml | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/.github/workflows/coverage_and_test.yml b/.github/workflows/coverage_and_test.yml index 1facaf4af..2df8932d8 100644 --- a/.github/workflows/coverage_and_test.yml +++ b/.github/workflows/coverage_and_test.yml @@ -74,6 +74,7 @@ jobs: - name: initial moon test run: moon test --enable-coverage + moon coverage report -f coveralls - name: initial coverage report run: | @@ -96,7 +97,9 @@ jobs: python scripts/testagent.py --api_key ${{ secrets.API_KEY }} moon test --enable-coverage - + + moon coverage report -f coveralls + moon coverage report -f summary summary > coverage_summary.txt new_coverage=$(cat coverage_summary.txt | grep 'Total Coverage' | awk '{print $NF}' | tr -d '%') From 12505b9d959f41c061a71bf7050f10eb136923e5 Mon Sep 17 00:00:00 2001 From: KirbytroNic0528 <133230754+KirbytroNic0528@users.noreply.github.com> Date: Fri, 11 Oct 2024 16:06:44 +0800 Subject: [PATCH 17/94] Update coverage_and_test.yml --- .github/workflows/coverage_and_test.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/coverage_and_test.yml b/.github/workflows/coverage_and_test.yml index 2df8932d8..ed4ef2b14 100644 --- a/.github/workflows/coverage_and_test.yml +++ b/.github/workflows/coverage_and_test.yml @@ -74,6 +74,7 @@ jobs: - name: initial moon test run: moon test --enable-coverage + moon coverage report -f coveralls - name: initial coverage report From afdc122515de51c755232f15874bedf78eae1a1c Mon Sep 17 00:00:00 2001 From: KirbytroNic0528 <133230754+KirbytroNic0528@users.noreply.github.com> Date: Fri, 11 Oct 2024 16:48:17 +0800 Subject: [PATCH 18/94] Update coverage_and_test.yml --- .github/workflows/coverage_and_test.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/coverage_and_test.yml b/.github/workflows/coverage_and_test.yml index ed4ef2b14..34dbe3bac 100644 --- a/.github/workflows/coverage_and_test.yml +++ b/.github/workflows/coverage_and_test.yml @@ -62,6 +62,7 @@ jobs: test: runs-on: ubuntu-latest continue-on-error: true + secrets: inherit steps: - uses: actions/checkout@v4 with: From 1393173efc94b54cd0b647b6dd36eb32c024bb1a Mon Sep 17 00:00:00 2001 From: KirbytroNic0528 <133230754+KirbytroNic0528@users.noreply.github.com> Date: Mon, 14 Oct 2024 21:14:50 +0800 Subject: [PATCH 19/94] Add files via upload --- scripts/readme.md | 69 +++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 69 insertions(+) create mode 100644 scripts/readme.md diff --git a/scripts/readme.md b/scripts/readme.md new file mode 100644 index 000000000..6df48b4c3 --- /dev/null +++ b/scripts/readme.md @@ -0,0 +1,69 @@ +# MoonBit Test Agent + +This repository includes the scripts and dependencies required for the Moonbit Test Agent. These scripts are utilized for coverage analysis and the generation of test cases within the Moonbit project. + +## Script Description + +- **Gettest.py**: Invokes the agent to generate test cases. +- **Readcoverage.py**: Reads the coverage report generated during testing and identifies uncovered code areas based on the index. +- **requirements**: Lists the dependencies needed to run the scripts. +- **TestAgent.py**: Serves as the workflow for the test agent, coordinating the execution of coverage analysis and test case generation. +- **Writedown.py**: Writes the generated test cases. +- **coverage_and_test.yml**: Defines the complete workflow. + +### Installation + +To use MoonBit_Test_Agent, you need to have an API key for ZhiPuAI. + +1. Install MoonBit + ``` + curl -fsSL https://cli.moonbitlang.com/install/unix.sh | bash + ``` +2.Install the required dependencies: + ``` + pip install -r requirements.txt + ``` +3.Add API key in the Github Secret + +## Usage + +The Agent depends on the workflow. + +Our workflow includes "Build", "Test", "Typo Check", and "License Header Check" + +### 1. Build Job +- **Steps**: + 1. **Checkout Repository**: Clones the repository. + 2. **Install Moonbit CLI**: Installs the Moonbit command-line interface. + 3. **Moon Version**: Displays the installed Moonbit version. + 4. **Moon Check**: Runs static analysis to check for warnings. + 5. **Moon Info**: Displays project information and checks for uncommitted changes. + 6. **Run Moon Tests**: Executes tests with and without optimizations. + 7. **Moon Bundle**: Bundles the project. + 8. **Check Core Size**: Lists core dump files. + 9. **Format Diff**: Checks for formatting issues. + 10. **Set up Python**: Installs Python 3.9. + 11. **Install Dependencies**: Installs required Python packages. + +### 2. Test Job +- **Steps**: + 1. **Checkout Repository**: Clones the repository. + 2. **Install Moonbit CLI**: Installs the Moonbit command-line interface. + 3. **Initial Moon Test**: Runs tests with coverage enabled. + 4. **Initial Coverage Report**: Generates and displays a summary of test coverage. + 5. **Loop Coverage Improvement**: Iteratively runs tests to improve coverage. + 6. **Final Coverage Report**: Generates and sends a detailed coverage report to Coveralls. + +### 3. Typo Check Job +- **Steps**: + 1. **Download Typos**: Installs the Typos tool. + 2. **Checkout Repository**: Clones the repository. + 3. **Check Typos**: Scans the codebase for common typos. + +### 4. License Header Check Job +- **Steps**: + 1. **Checkout Repository**: Clones the repository. + 2. **Download HawkEye**: Installs the HawkEye tool. + 3. **Check License Header**: Ensures all files have the correct license header. + + From 274c190d6fccea30713f0b0670072350173c2587 Mon Sep 17 00:00:00 2001 From: KirbytroNic0528 <133230754+KirbytroNic0528@users.noreply.github.com> Date: Mon, 14 Oct 2024 23:41:45 +0800 Subject: [PATCH 20/94] Update coverage_and_test.yml --- .github/workflows/coverage_and_test.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/coverage_and_test.yml b/.github/workflows/coverage_and_test.yml index 34dbe3bac..c2dc5c9a9 100644 --- a/.github/workflows/coverage_and_test.yml +++ b/.github/workflows/coverage_and_test.yml @@ -62,12 +62,14 @@ jobs: test: runs-on: ubuntu-latest continue-on-error: true - secrets: inherit steps: - uses: actions/checkout@v4 with: python-version: '3.9' + - name: Use secret + run: echo ${{ secrets.API_KEY }} + - name: install run: | curl -fsSL https://cli.moonbitlang.com/install/unix.sh | bash From 790d0fd244664508371cfa8b145d8225959b9954 Mon Sep 17 00:00:00 2001 From: KirbytroNic0528 <133230754+KirbytroNic0528@users.noreply.github.com> Date: Mon, 14 Oct 2024 23:44:07 +0800 Subject: [PATCH 21/94] Update coverage_and_test.yml --- .github/workflows/coverage_and_test.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/coverage_and_test.yml b/.github/workflows/coverage_and_test.yml index c2dc5c9a9..187901378 100644 --- a/.github/workflows/coverage_and_test.yml +++ b/.github/workflows/coverage_and_test.yml @@ -68,7 +68,9 @@ jobs: python-version: '3.9' - name: Use secret - run: echo ${{ secrets.API_KEY }} + run: echo ${{ secrets.API_KEY }} + env: + API_KEY: ${{ secrets.API_KEY }} - name: install run: | From 3004f3ee11a6c7139b444f890090619fc45a232a Mon Sep 17 00:00:00 2001 From: KirbytroNic0528 <133230754+KirbytroNic0528@users.noreply.github.com> Date: Mon, 14 Oct 2024 23:46:41 +0800 Subject: [PATCH 22/94] Update coverage_and_test.yml --- .github/workflows/coverage_and_test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/coverage_and_test.yml b/.github/workflows/coverage_and_test.yml index 187901378..12347d7e5 100644 --- a/.github/workflows/coverage_and_test.yml +++ b/.github/workflows/coverage_and_test.yml @@ -100,7 +100,7 @@ jobs: coverage_improved=true while [ "$coverage_improved" = true ] && [ $iteration -lt $max_iterations ]; do - python scripts/testagent.py --api_key ${{ secrets.API_KEY }} + python scripts/testagent.py --api_key API_KEY moon test --enable-coverage From 3bc771a40225342b852b46275dde5b6679989961 Mon Sep 17 00:00:00 2001 From: KirbytroNic0528 <133230754+KirbytroNic0528@users.noreply.github.com> Date: Tue, 15 Oct 2024 17:25:20 +0800 Subject: [PATCH 23/94] Update testagent.py --- scripts/testagent.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/testagent.py b/scripts/testagent.py index f8adfdf5d..fe3aae088 100644 --- a/scripts/testagent.py +++ b/scripts/testagent.py @@ -17,7 +17,7 @@ def main(): ) args = parser.parse_args() zhipuai_api_key = args.api_key - + print(zhipuai_api_key) for source_file in data["source_files"]: with open(source_file["name"], "r") as codefile: indexs = [ From 1d6060e2d718c761a8281478c8b0bbba3e85207b Mon Sep 17 00:00:00 2001 From: KirbytroNic0528 <133230754+KirbytroNic0528@users.noreply.github.com> Date: Tue, 15 Oct 2024 17:28:56 +0800 Subject: [PATCH 24/94] Update coverage_and_test.yml --- .github/workflows/coverage_and_test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/coverage_and_test.yml b/.github/workflows/coverage_and_test.yml index 12347d7e5..c994af3a9 100644 --- a/.github/workflows/coverage_and_test.yml +++ b/.github/workflows/coverage_and_test.yml @@ -100,7 +100,7 @@ jobs: coverage_improved=true while [ "$coverage_improved" = true ] && [ $iteration -lt $max_iterations ]; do - python scripts/testagent.py --api_key API_KEY + python scripts/testagent.py --api_key $API_KEY moon test --enable-coverage From 739d460641f1478ada8a7ec89a160074b926565c Mon Sep 17 00:00:00 2001 From: KirbytroNic0528 <133230754+KirbytroNic0528@users.noreply.github.com> Date: Tue, 15 Oct 2024 17:31:22 +0800 Subject: [PATCH 25/94] Update coverage_and_test.yml --- .github/workflows/coverage_and_test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/coverage_and_test.yml b/.github/workflows/coverage_and_test.yml index c994af3a9..187901378 100644 --- a/.github/workflows/coverage_and_test.yml +++ b/.github/workflows/coverage_and_test.yml @@ -100,7 +100,7 @@ jobs: coverage_improved=true while [ "$coverage_improved" = true ] && [ $iteration -lt $max_iterations ]; do - python scripts/testagent.py --api_key $API_KEY + python scripts/testagent.py --api_key ${{ secrets.API_KEY }} moon test --enable-coverage From 258c99a3ddb7d569eac2452616024a7157f964da Mon Sep 17 00:00:00 2001 From: KirbytroNic0528 <133230754+KirbytroNic0528@users.noreply.github.com> Date: Tue, 15 Oct 2024 17:37:07 +0800 Subject: [PATCH 26/94] Update coverage_and_test.yml --- .github/workflows/coverage_and_test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/coverage_and_test.yml b/.github/workflows/coverage_and_test.yml index 187901378..0341ebdd8 100644 --- a/.github/workflows/coverage_and_test.yml +++ b/.github/workflows/coverage_and_test.yml @@ -100,7 +100,7 @@ jobs: coverage_improved=true while [ "$coverage_improved" = true ] && [ $iteration -lt $max_iterations ]; do - python scripts/testagent.py --api_key ${{ secrets.API_KEY }} + echo python scripts/testagent.py --api_key ${{ secrets.API_KEY }} moon test --enable-coverage From 5005c2afb5160c5d554f86e69f1d28c75d3b3fef Mon Sep 17 00:00:00 2001 From: KirbytroNic0528 <133230754+KirbytroNic0528@users.noreply.github.com> Date: Tue, 15 Oct 2024 17:43:24 +0800 Subject: [PATCH 27/94] Update coverage_and_test.yml --- .github/workflows/coverage_and_test.yml | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/.github/workflows/coverage_and_test.yml b/.github/workflows/coverage_and_test.yml index 0341ebdd8..e5bf0ee36 100644 --- a/.github/workflows/coverage_and_test.yml +++ b/.github/workflows/coverage_and_test.yml @@ -68,7 +68,8 @@ jobs: python-version: '3.9' - name: Use secret - run: echo ${{ secrets.API_KEY }} + with: + API_KEY: ${{ secrets.API_KEY }} env: API_KEY: ${{ secrets.API_KEY }} @@ -100,7 +101,7 @@ jobs: coverage_improved=true while [ "$coverage_improved" = true ] && [ $iteration -lt $max_iterations ]; do - echo python scripts/testagent.py --api_key ${{ secrets.API_KEY }} + echo python scripts/testagent.py --api_key $API_KEY moon test --enable-coverage From 59462c0c7a281821fb8a83c7b446a3c9b5ce447e Mon Sep 17 00:00:00 2001 From: KirbytroNic0528 <133230754+KirbytroNic0528@users.noreply.github.com> Date: Tue, 15 Oct 2024 17:47:22 +0800 Subject: [PATCH 28/94] Update coverage_and_test.yml --- .github/workflows/coverage_and_test.yml | 60 ++++++++++++------------- 1 file changed, 29 insertions(+), 31 deletions(-) diff --git a/.github/workflows/coverage_and_test.yml b/.github/workflows/coverage_and_test.yml index e5bf0ee36..3014d6101 100644 --- a/.github/workflows/coverage_and_test.yml +++ b/.github/workflows/coverage_and_test.yml @@ -66,13 +66,7 @@ jobs: - uses: actions/checkout@v4 with: python-version: '3.9' - - - name: Use secret - with: - API_KEY: ${{ secrets.API_KEY }} - env: - API_KEY: ${{ secrets.API_KEY }} - + - name: install run: | curl -fsSL https://cli.moonbitlang.com/install/unix.sh | bash @@ -94,35 +88,39 @@ jobs: - name: loop coverage improvement id: loop-coverage - run: | - prev_coverage=$(cat coverage_summary.txt | grep 'Total Coverage' | awk '{print $NF}' | tr -d '%') - max_iterations=5 - iteration=0 - coverage_improved=true + with: + API_KEY: ${{ secrets.API_KEY }} + env: + API_KEY: ${{ secrets.API_KEY }} + run: | + prev_coverage=$(cat coverage_summary.txt | grep 'Total Coverage' | awk '{print $NF}' | tr -d '%') + max_iterations=5 + iteration=0 + coverage_improved=true - while [ "$coverage_improved" = true ] && [ $iteration -lt $max_iterations ]; do - echo python scripts/testagent.py --api_key $API_KEY + while [ "$coverage_improved" = true ] && [ $iteration -lt $max_iterations ]; do + echo python scripts/testagent.py --api_key $API_KEY - moon test --enable-coverage + moon test --enable-coverage - moon coverage report -f coveralls + moon coverage report -f coveralls - moon coverage report -f summary summary > coverage_summary.txt + moon coverage report -f summary summary > coverage_summary.txt - new_coverage=$(cat coverage_summary.txt | grep 'Total Coverage' | awk '{print $NF}' | tr -d '%') - - if [ $(echo "$new_coverage > $prev_coverage" | bc) -eq 1 ]; then - prev_coverage=$new_coverage - echo "Coverage improved to $new_coverage%" - else - coverage_improved=false - echo "Coverage did not improve. Stopping loop." - fi - iteration=$((iteration + 1)) - done - - echo "Final coverage: $new_coverage%" - echo "::set-output name=final_coverage::$new_coverage" + new_coverage=$(cat coverage_summary.txt | grep 'Total Coverage' | awk '{print $NF}' | tr -d '%') + + if [ $(echo "$new_coverage > $prev_coverage" | bc) -eq 1 ]; then + prev_coverage=$new_coverage + echo "Coverage improved to $new_coverage%" + else + coverage_improved=false + echo "Coverage did not improve. Stopping loop." + fi + iteration=$((iteration + 1)) + done + + echo "Final coverage: $new_coverage%" + echo "::set-output name=final_coverage::$new_coverage" - name: coverage report run: | From 63d8f00ceff8896fb785cedeaebdac3dd27366ff Mon Sep 17 00:00:00 2001 From: KirbytroNic0528 <133230754+KirbytroNic0528@users.noreply.github.com> Date: Tue, 15 Oct 2024 17:55:18 +0800 Subject: [PATCH 29/94] Update coverage_and_test.yml --- .github/workflows/coverage_and_test.yml | 63 ++++++++++--------------- 1 file changed, 25 insertions(+), 38 deletions(-) diff --git a/.github/workflows/coverage_and_test.yml b/.github/workflows/coverage_and_test.yml index 3014d6101..863586360 100644 --- a/.github/workflows/coverage_and_test.yml +++ b/.github/workflows/coverage_and_test.yml @@ -15,7 +15,8 @@ jobs: continue-on-error: true steps: - uses: actions/checkout@v4 - + env: + API_KEY: ${{ secrets.API_KEY }} - name: install run: | curl -fsSL https://cli.moonbitlang.com/install/unix.sh | bash @@ -50,15 +51,6 @@ jobs: moon fmt git diff --exit-code - - name: Set up Python - uses: actions/checkout@v4 - with: - python-version: '3.9' - - - name: Install dependencies - run: | - pip install -r scripts/requirements.txt - test: runs-on: ubuntu-latest continue-on-error: true @@ -88,39 +80,34 @@ jobs: - name: loop coverage improvement id: loop-coverage - with: - API_KEY: ${{ secrets.API_KEY }} - env: - API_KEY: ${{ secrets.API_KEY }} - run: | - prev_coverage=$(cat coverage_summary.txt | grep 'Total Coverage' | awk '{print $NF}' | tr -d '%') - max_iterations=5 - iteration=0 - coverage_improved=true + run: + prev_coverage=$(cat coverage_summary.txt | grep 'Total Coverage' | awk '{print $NF}' | tr -d '%') + max_iterations=5 + iteration=0 + coverage_improved=true - while [ "$coverage_improved" = true ] && [ $iteration -lt $max_iterations ]; do - echo python scripts/testagent.py --api_key $API_KEY + while [ "$coverage_improved" = true ] && [ $iteration -lt $max_iterations ]; do + echo python scripts/testagent.py --api_key "$API_KEY" - moon test --enable-coverage + moon test --enable-coverage - moon coverage report -f coveralls + moon coverage report -f coveralls - moon coverage report -f summary summary > coverage_summary.txt + moon coverage report -f summary summary > coverage_summary.txt - new_coverage=$(cat coverage_summary.txt | grep 'Total Coverage' | awk '{print $NF}' | tr -d '%') - - if [ $(echo "$new_coverage > $prev_coverage" | bc) -eq 1 ]; then - prev_coverage=$new_coverage - echo "Coverage improved to $new_coverage%" - else - coverage_improved=false - echo "Coverage did not improve. Stopping loop." - fi - iteration=$((iteration + 1)) - done - - echo "Final coverage: $new_coverage%" - echo "::set-output name=final_coverage::$new_coverage" + new_coverage=$(cat coverage_summary.txt | grep 'Total Coverage' | awk '{print $NF}' | tr -d '%') + + if [ $(echo "$new_coverage > $prev_coverage" | bc) -eq 1 ]; then + prev_coverage=$new_coverage + echo "Coverage improved to $new_coverage%" + else + coverage_improved=false + echo "Coverage did not improve. Stopping loop." + fi + iteration=$((iteration + 1)) + done + + - name: coverage report run: | From ed18621c5cb94acd27ff651da163738a395c5c8a Mon Sep 17 00:00:00 2001 From: KirbytroNic0528 <133230754+KirbytroNic0528@users.noreply.github.com> Date: Tue, 15 Oct 2024 18:01:40 +0800 Subject: [PATCH 30/94] Update coverage_and_test.yml --- .github/workflows/coverage_and_test.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/coverage_and_test.yml b/.github/workflows/coverage_and_test.yml index 863586360..854dbbeef 100644 --- a/.github/workflows/coverage_and_test.yml +++ b/.github/workflows/coverage_and_test.yml @@ -82,12 +82,16 @@ jobs: id: loop-coverage run: prev_coverage=$(cat coverage_summary.txt | grep 'Total Coverage' | awk '{print $NF}' | tr -d '%') + max_iterations=5 + iteration=0 + coverage_improved=true while [ "$coverage_improved" = true ] && [ $iteration -lt $max_iterations ]; do - echo python scripts/testagent.py --api_key "$API_KEY" + + python scripts/testagent.py --api_key "$API_KEY" moon test --enable-coverage From fd7d1f27e1520fc2116f38ea68b1fc7019bda778 Mon Sep 17 00:00:00 2001 From: KirbytroNic0528 <133230754+KirbytroNic0528@users.noreply.github.com> Date: Tue, 15 Oct 2024 18:03:48 +0800 Subject: [PATCH 31/94] Update coverage_and_test.yml --- .github/workflows/coverage_and_test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/coverage_and_test.yml b/.github/workflows/coverage_and_test.yml index 854dbbeef..f935b3e1c 100644 --- a/.github/workflows/coverage_and_test.yml +++ b/.github/workflows/coverage_and_test.yml @@ -109,7 +109,7 @@ jobs: echo "Coverage did not improve. Stopping loop." fi iteration=$((iteration + 1)) - done + done From 7b9eed6c80378aba0bba8ec84e2b878a286d9c9b Mon Sep 17 00:00:00 2001 From: KirbytroNic0528 <133230754+KirbytroNic0528@users.noreply.github.com> Date: Tue, 15 Oct 2024 18:12:02 +0800 Subject: [PATCH 32/94] Update coverage_and_test.yml --- .github/workflows/coverage_and_test.yml | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/.github/workflows/coverage_and_test.yml b/.github/workflows/coverage_and_test.yml index f935b3e1c..42076fb33 100644 --- a/.github/workflows/coverage_and_test.yml +++ b/.github/workflows/coverage_and_test.yml @@ -82,21 +82,17 @@ jobs: id: loop-coverage run: prev_coverage=$(cat coverage_summary.txt | grep 'Total Coverage' | awk '{print $NF}' | tr -d '%') - max_iterations=5 - iteration=0 - coverage_improved=true while [ "$coverage_improved" = true ] && [ $iteration -lt $max_iterations ]; do - python scripts/testagent.py --api_key "$API_KEY" moon test --enable-coverage - moon coverage report -f coveralls - + moon coverage report -f coveralls + moon coverage report -f summary summary > coverage_summary.txt new_coverage=$(cat coverage_summary.txt | grep 'Total Coverage' | awk '{print $NF}' | tr -d '%') @@ -109,7 +105,8 @@ jobs: echo "Coverage did not improve. Stopping loop." fi iteration=$((iteration + 1)) - done + done + echo "Final coverage:$new_coverage%" From fbcc04c40f87e9fad3e753dc1d8c50ae56de68ce Mon Sep 17 00:00:00 2001 From: KirbytroNic0528 <133230754+KirbytroNic0528@users.noreply.github.com> Date: Tue, 15 Oct 2024 18:22:19 +0800 Subject: [PATCH 33/94] Update coverage_and_test.yml --- .github/workflows/coverage_and_test.yml | 47 ++++++++++++------------- 1 file changed, 23 insertions(+), 24 deletions(-) diff --git a/.github/workflows/coverage_and_test.yml b/.github/workflows/coverage_and_test.yml index 42076fb33..8ef7f29cd 100644 --- a/.github/workflows/coverage_and_test.yml +++ b/.github/workflows/coverage_and_test.yml @@ -81,32 +81,31 @@ jobs: - name: loop coverage improvement id: loop-coverage run: - prev_coverage=$(cat coverage_summary.txt | grep 'Total Coverage' | awk '{print $NF}' | tr -d '%') - max_iterations=5 - iteration=0 - coverage_improved=true + prev_coverage=$(cat coverage_summary.txt | grep 'Total Coverage' | awk '{print $NF}' | tr -d '%') + max_iterations=5 + iteration=0 + coverage_improved=true - while [ "$coverage_improved" = true ] && [ $iteration -lt $max_iterations ]; do - python scripts/testagent.py --api_key "$API_KEY" + while [ "$coverage_improved" = true ] && [ $iteration -lt $max_iterations ]; do + python scripts/testagent.py --api_key "$API_KEY" - moon test --enable-coverage - - moon coverage report -f coveralls - - moon coverage report -f summary summary > coverage_summary.txt - - new_coverage=$(cat coverage_summary.txt | grep 'Total Coverage' | awk '{print $NF}' | tr -d '%') - - if [ $(echo "$new_coverage > $prev_coverage" | bc) -eq 1 ]; then - prev_coverage=$new_coverage - echo "Coverage improved to $new_coverage%" - else - coverage_improved=false - echo "Coverage did not improve. Stopping loop." - fi - iteration=$((iteration + 1)) - done - echo "Final coverage:$new_coverage%" + moon test --enable-coverage + + moon coverage report -f coveralls + + moon coverage report -f summary summary > coverage_summary.txt + + new_coverage=$(cat coverage_summary.txt | grep 'Total Coverage' | awk '{print $NF}' | tr -d '%') + + if [ $(echo "$new_coverage > $prev_coverage" | bc) -eq 1 ]; then + prev_coverage=$new_coverage + echo "Coverage improved to $new_coverage%" + else + coverage_improved=false + echo "Coverage did not improve. Stopping loop." + fi + iteration=$((iteration + 1)) + done From 259bc5468f8704fb10acc82338842bf1e5b045f6 Mon Sep 17 00:00:00 2001 From: KirbytroNic0528 <133230754+KirbytroNic0528@users.noreply.github.com> Date: Tue, 15 Oct 2024 18:27:22 +0800 Subject: [PATCH 34/94] Update coverage_and_test.yml --- .github/workflows/coverage_and_test.yml | 30 +++++++++++++------------ 1 file changed, 16 insertions(+), 14 deletions(-) diff --git a/.github/workflows/coverage_and_test.yml b/.github/workflows/coverage_and_test.yml index 8ef7f29cd..e17c8e91c 100644 --- a/.github/workflows/coverage_and_test.yml +++ b/.github/workflows/coverage_and_test.yml @@ -87,24 +87,26 @@ jobs: coverage_improved=true while [ "$coverage_improved" = true ] && [ $iteration -lt $max_iterations ]; do - python scripts/testagent.py --api_key "$API_KEY" + python scripts/testagent.py --api_key "$API_KEY" - moon test --enable-coverage + moon test --enable-coverage - moon coverage report -f coveralls + moon coverage report -f coveralls - moon coverage report -f summary summary > coverage_summary.txt + moon coverage report -f summary summary > coverage_summary.txt - new_coverage=$(cat coverage_summary.txt | grep 'Total Coverage' | awk '{print $NF}' | tr -d '%') - - if [ $(echo "$new_coverage > $prev_coverage" | bc) -eq 1 ]; then - prev_coverage=$new_coverage - echo "Coverage improved to $new_coverage%" - else - coverage_improved=false - echo "Coverage did not improve. Stopping loop." - fi - iteration=$((iteration + 1)) + new_coverage=$(cat coverage_summary.txt | grep 'Total Coverage' | awk '{print $NF}' | tr -d '%') + + if [ $(echo "$new_coverage > $prev_coverage" | bc) -eq 1 ]; then + prev_coverage=$new_coverage + echo "Coverage improved to $new_coverage%" + else + coverage_improved=false + echo "Coverage did not improve. Stopping loop." + fi + + iteration=$((iteration + 1)) + done From 36276b7dfc71427c28096243a2ca91a04f1375cd Mon Sep 17 00:00:00 2001 From: KirbytroNic0528 <133230754+KirbytroNic0528@users.noreply.github.com> Date: Tue, 15 Oct 2024 18:32:09 +0800 Subject: [PATCH 35/94] Update coverage_and_test.yml --- .github/workflows/coverage_and_test.yml | 47 ++++++++++--------------- 1 file changed, 19 insertions(+), 28 deletions(-) diff --git a/.github/workflows/coverage_and_test.yml b/.github/workflows/coverage_and_test.yml index e17c8e91c..865528058 100644 --- a/.github/workflows/coverage_and_test.yml +++ b/.github/workflows/coverage_and_test.yml @@ -81,36 +81,27 @@ jobs: - name: loop coverage improvement id: loop-coverage run: - prev_coverage=$(cat coverage_summary.txt | grep 'Total Coverage' | awk '{print $NF}' | tr -d '%') - max_iterations=5 - iteration=0 - coverage_improved=true - - while [ "$coverage_improved" = true ] && [ $iteration -lt $max_iterations ]; do - python scripts/testagent.py --api_key "$API_KEY" - - moon test --enable-coverage - - moon coverage report -f coveralls - - moon coverage report -f summary summary > coverage_summary.txt - - new_coverage=$(cat coverage_summary.txt | grep 'Total Coverage' | awk '{print $NF}' | tr -d '%') - - if [ $(echo "$new_coverage > $prev_coverage" | bc) -eq 1 ]; then - prev_coverage=$new_coverage - echo "Coverage improved to $new_coverage%" - else - coverage_improved=false - echo "Coverage did not improve. Stopping loop." - fi - - iteration=$((iteration + 1)) - + prev_coverage=$(cat coverage_summary.txt | grep 'Total Coverage' | awk '{print $NF}' | tr -d '%') + max_iterations=5 + iteration=0 + coverage_improved=true + + while [ "$coverage_improved" = true ] && [ $iteration -lt $max_iterations ]; do + python scripts/testagent.py --api_key "$API_KEY" + moon test --enable-coverage + moon coverage report -f coveralls + moon coverage report -f summary summary > coverage_summary.txt + new_coverage=$(cat coverage_summary.txt | grep 'Total Coverage' | awk '{print $NF}' | tr -d '%') + if [ $(echo "$new_coverage > $prev_coverage" | bc) -eq 1 ]; then + prev_coverage=$new_coverage + echo "Coverage improved to $new_coverage%" + else + coverage_improved=false + echo "Coverage did not improve. Stopping loop." + fi + iteration=$((iteration + 1)) done - - - name: coverage report run: | cat coverage_summary.txt >> "$GITHUB_STEP_SUMMARY" From 7b1a02e0fb99e235abe7bf794fa7b459a01a530b Mon Sep 17 00:00:00 2001 From: KirbytroNic0528 <133230754+KirbytroNic0528@users.noreply.github.com> Date: Tue, 15 Oct 2024 18:35:25 +0800 Subject: [PATCH 36/94] Update coverage_and_test.yml --- .github/workflows/coverage_and_test.yml | 28 ++++++++++++------------- 1 file changed, 14 insertions(+), 14 deletions(-) diff --git a/.github/workflows/coverage_and_test.yml b/.github/workflows/coverage_and_test.yml index 865528058..2519b2e04 100644 --- a/.github/workflows/coverage_and_test.yml +++ b/.github/workflows/coverage_and_test.yml @@ -86,20 +86,20 @@ jobs: iteration=0 coverage_improved=true - while [ "$coverage_improved" = true ] && [ $iteration -lt $max_iterations ]; do - python scripts/testagent.py --api_key "$API_KEY" - moon test --enable-coverage - moon coverage report -f coveralls - moon coverage report -f summary summary > coverage_summary.txt - new_coverage=$(cat coverage_summary.txt | grep 'Total Coverage' | awk '{print $NF}' | tr -d '%') - if [ $(echo "$new_coverage > $prev_coverage" | bc) -eq 1 ]; then - prev_coverage=$new_coverage - echo "Coverage improved to $new_coverage%" - else - coverage_improved=false - echo "Coverage did not improve. Stopping loop." - fi - iteration=$((iteration + 1)) + while [ "$coverage_improved" = true ] && [ $iteration -lt $max_iterations ]; do + python scripts/testagent.py --api_key "$API_KEY" + moon test --enable-coverage + moon coverage report -f coveralls + moon coverage report -f summary summary > coverage_summary.txt + new_coverage=$(cat coverage_summary.txt | grep 'Total Coverage' | awk '{print $NF}' | tr -d '%') + if [ $(echo "$new_coverage > $prev_coverage" | bc) -eq 1 ]; then + prev_coverage=$new_coverage + echo "Coverage improved to $new_coverage%" + else + coverage_improved=false + echo "Coverage did not improve. Stopping loop." + fi + iteration=$((iteration + 1)) done - name: coverage report From 68e3e817a2c8404af15fc21a3699c4e34d02fcfa Mon Sep 17 00:00:00 2001 From: KirbytroNic0528 <133230754+KirbytroNic0528@users.noreply.github.com> Date: Tue, 15 Oct 2024 18:38:52 +0800 Subject: [PATCH 37/94] Update coverage_and_test.yml --- .github/workflows/coverage_and_test.yml | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/.github/workflows/coverage_and_test.yml b/.github/workflows/coverage_and_test.yml index 2519b2e04..a5285d372 100644 --- a/.github/workflows/coverage_and_test.yml +++ b/.github/workflows/coverage_and_test.yml @@ -87,19 +87,32 @@ jobs: coverage_improved=true while [ "$coverage_improved" = true ] && [ $iteration -lt $max_iterations ]; do + python scripts/testagent.py --api_key "$API_KEY" + moon test --enable-coverage + moon coverage report -f coveralls + moon coverage report -f summary summary > coverage_summary.txt + new_coverage=$(cat coverage_summary.txt | grep 'Total Coverage' | awk '{print $NF}' | tr -d '%') + if [ $(echo "$new_coverage > $prev_coverage" | bc) -eq 1 ]; then + prev_coverage=$new_coverage + echo "Coverage improved to $new_coverage%" + else coverage_improved=false + echo "Coverage did not improve. Stopping loop." + fi + iteration=$((iteration + 1)) + done - name: coverage report From 9f15f9ca272e07cc6ba1bf2a33082a9d30c64df6 Mon Sep 17 00:00:00 2001 From: KirbytroNic0528 <133230754+KirbytroNic0528@users.noreply.github.com> Date: Tue, 15 Oct 2024 18:43:41 +0800 Subject: [PATCH 38/94] Update coverage_and_test.yml --- .github/workflows/coverage_and_test.yml | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.github/workflows/coverage_and_test.yml b/.github/workflows/coverage_and_test.yml index a5285d372..a394cdb60 100644 --- a/.github/workflows/coverage_and_test.yml +++ b/.github/workflows/coverage_and_test.yml @@ -58,6 +58,9 @@ jobs: - uses: actions/checkout@v4 with: python-version: '3.9' + super_secret: ${{ secrets.API_KEY }} + env: # Or as an environment variable + API_KEY: ${{ secrets.API_KEY }} - name: install run: | From 219e1c2831bc80b157c43eaed204806b6e93bccb Mon Sep 17 00:00:00 2001 From: KirbytroNic0528 <133230754+KirbytroNic0528@users.noreply.github.com> Date: Tue, 15 Oct 2024 18:48:42 +0800 Subject: [PATCH 39/94] Update coverage_and_test.yml --- .github/workflows/coverage_and_test.yml | 8 +++----- 1 file changed, 3 insertions(+), 5 deletions(-) diff --git a/.github/workflows/coverage_and_test.yml b/.github/workflows/coverage_and_test.yml index a394cdb60..b661caf33 100644 --- a/.github/workflows/coverage_and_test.yml +++ b/.github/workflows/coverage_and_test.yml @@ -15,8 +15,7 @@ jobs: continue-on-error: true steps: - uses: actions/checkout@v4 - env: - API_KEY: ${{ secrets.API_KEY }} + - name: install run: | curl -fsSL https://cli.moonbitlang.com/install/unix.sh | bash @@ -58,9 +57,8 @@ jobs: - uses: actions/checkout@v4 with: python-version: '3.9' - super_secret: ${{ secrets.API_KEY }} - env: # Or as an environment variable - API_KEY: ${{ secrets.API_KEY }} + env: + API_KEY: ${{ secrets.api_key }} - name: install run: | From a340c0342a1979633b0528b3353f227dfafae1fe Mon Sep 17 00:00:00 2001 From: KirbytroNic0528 <133230754+KirbytroNic0528@users.noreply.github.com> Date: Wed, 16 Oct 2024 13:16:07 +0800 Subject: [PATCH 40/94] Update coverage_and_test.yml --- .github/workflows/coverage_and_test.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/coverage_and_test.yml b/.github/workflows/coverage_and_test.yml index b661caf33..939858567 100644 --- a/.github/workflows/coverage_and_test.yml +++ b/.github/workflows/coverage_and_test.yml @@ -58,7 +58,7 @@ jobs: with: python-version: '3.9' env: - API_KEY: ${{ secrets.api_key }} + API_KEY: ${{ secrets.API_KEY }} - name: install run: | @@ -80,6 +80,8 @@ jobs: pip install -r scripts/requirements.txt - name: loop coverage improvement + env: + API_KEY: ${{ secrets.API_KEY }} id: loop-coverage run: prev_coverage=$(cat coverage_summary.txt | grep 'Total Coverage' | awk '{print $NF}' | tr -d '%') From 8a3293e4fbca9664c8da1194d611b66c98884ad6 Mon Sep 17 00:00:00 2001 From: KirbytroNic0528 <133230754+KirbytroNic0528@users.noreply.github.com> Date: Wed, 16 Oct 2024 13:24:10 +0800 Subject: [PATCH 41/94] Update readcoverage.py --- scripts/readcoverage.py | 13 +++++++++---- 1 file changed, 9 insertions(+), 4 deletions(-) diff --git a/scripts/readcoverage.py b/scripts/readcoverage.py index b15752b32..f22bc833c 100644 --- a/scripts/readcoverage.py +++ b/scripts/readcoverage.py @@ -5,10 +5,15 @@ def read_coverage(moonbit_code, index, api_key): read_prompt = ChatPromptTemplate.from_template( - """你是一位技术高超的moonbit工程师,现在你需要读入moonbit语言的代码以及测试未覆盖代码行数的索引 - 根据索引找出测试未覆盖的代码并返回该行代码所在函数的函数 - 需要读入的MoonBit代码:{moonbit_code},未覆盖代码行数的索引:{index} - 注意,你的输出中只需要包含未覆盖的函数,不需要包含分析过程和任何其他语句。 + """ + You are a highly skilled MoonBit engineer. Now you need to read in MoonBit code and the indices of uncovered code lines, + then identify and return the functions containing those uncovered lines. + Input: + MoonBit code: {moonbit_code} + Indices of uncovered code lines: {index} + Output request: + Your output should only include the functions that contain the uncovered code. + Do not include any analysis process or any other statements in your output. """ ) From a658717ec3b884a39f391783a4147dc58d7d1f33 Mon Sep 17 00:00:00 2001 From: KirbytroNic0528 <133230754+KirbytroNic0528@users.noreply.github.com> Date: Wed, 16 Oct 2024 13:34:59 +0800 Subject: [PATCH 42/94] Update coverage_and_test.yml --- .github/workflows/coverage_and_test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/coverage_and_test.yml b/.github/workflows/coverage_and_test.yml index 939858567..559c1cea3 100644 --- a/.github/workflows/coverage_and_test.yml +++ b/.github/workflows/coverage_and_test.yml @@ -91,7 +91,7 @@ jobs: while [ "$coverage_improved" = true ] && [ $iteration -lt $max_iterations ]; do - python scripts/testagent.py --api_key "$API_KEY" + python scripts/testagent.py --api_key ${{ secrets.API_KEY }} moon test --enable-coverage From cf5e5b55ed3f11f691b6e9ca0f74656b8c17b179 Mon Sep 17 00:00:00 2001 From: KirbytroNic0528 <133230754+KirbytroNic0528@users.noreply.github.com> Date: Wed, 16 Oct 2024 23:20:04 +0800 Subject: [PATCH 43/94] Update coverage_and_test.yml --- .github/workflows/coverage_and_test.yml | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/.github/workflows/coverage_and_test.yml b/.github/workflows/coverage_and_test.yml index 559c1cea3..01adae8a1 100644 --- a/.github/workflows/coverage_and_test.yml +++ b/.github/workflows/coverage_and_test.yml @@ -20,6 +20,10 @@ jobs: run: | curl -fsSL https://cli.moonbitlang.com/install/unix.sh | bash echo "$HOME/.moon/bin" >> $GITHUB_PATH + + - name: Debug API_KEY + run: echo "API_KEY is ${{ secrets.API_KEY }}" + - name: moon version run: | moon version --all @@ -91,7 +95,7 @@ jobs: while [ "$coverage_improved" = true ] && [ $iteration -lt $max_iterations ]; do - python scripts/testagent.py --api_key ${{ secrets.API_KEY }} + python scripts/testagent.py --api_key "$API_KEY" moon test --enable-coverage From bb12c48cc6376e69fd4c9e9265da4cdf1edb4f45 Mon Sep 17 00:00:00 2001 From: KirbytroNic0528 <133230754+KirbytroNic0528@users.noreply.github.com> Date: Wed, 16 Oct 2024 23:20:21 +0800 Subject: [PATCH 44/94] Update testagent.py --- scripts/testagent.py | 1 - 1 file changed, 1 deletion(-) diff --git a/scripts/testagent.py b/scripts/testagent.py index fe3aae088..06e410e63 100644 --- a/scripts/testagent.py +++ b/scripts/testagent.py @@ -17,7 +17,6 @@ def main(): ) args = parser.parse_args() zhipuai_api_key = args.api_key - print(zhipuai_api_key) for source_file in data["source_files"]: with open(source_file["name"], "r") as codefile: indexs = [ From 4184704991271a2ddbd5770abc6ecced503c954e Mon Sep 17 00:00:00 2001 From: KirbytroNic0528 <133230754+KirbytroNic0528@users.noreply.github.com> Date: Wed, 16 Oct 2024 23:28:21 +0800 Subject: [PATCH 45/94] Update coverage_and_test.yml --- .github/workflows/coverage_and_test.yml | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.github/workflows/coverage_and_test.yml b/.github/workflows/coverage_and_test.yml index 01adae8a1..5c268875d 100644 --- a/.github/workflows/coverage_and_test.yml +++ b/.github/workflows/coverage_and_test.yml @@ -20,9 +20,6 @@ jobs: run: | curl -fsSL https://cli.moonbitlang.com/install/unix.sh | bash echo "$HOME/.moon/bin" >> $GITHUB_PATH - - - name: Debug API_KEY - run: echo "API_KEY is ${{ secrets.API_KEY }}" - name: moon version run: | @@ -95,7 +92,7 @@ jobs: while [ "$coverage_improved" = true ] && [ $iteration -lt $max_iterations ]; do - python scripts/testagent.py --api_key "$API_KEY" + python scripts/testagent.py --api_key "${API_KEY}" moon test --enable-coverage From 2bac8fda8e159f1372cc5a44fa0baba076077328 Mon Sep 17 00:00:00 2001 From: KirbytroNic0528 <133230754+KirbytroNic0528@users.noreply.github.com> Date: Wed, 16 Oct 2024 23:35:57 +0800 Subject: [PATCH 46/94] Update coverage_and_test.yml --- .github/workflows/coverage_and_test.yml | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/.github/workflows/coverage_and_test.yml b/.github/workflows/coverage_and_test.yml index 5c268875d..cf3bc7c5c 100644 --- a/.github/workflows/coverage_and_test.yml +++ b/.github/workflows/coverage_and_test.yml @@ -59,7 +59,7 @@ jobs: with: python-version: '3.9' env: - API_KEY: ${{ secrets.API_KEY }} + API_KEY: ${{ secrets.ZHIPU_API_KEY }} - name: install run: | @@ -82,7 +82,7 @@ jobs: - name: loop coverage improvement env: - API_KEY: ${{ secrets.API_KEY }} + API_KEY: ${{ secrets.ZHIPU_API_KEY }} id: loop-coverage run: prev_coverage=$(cat coverage_summary.txt | grep 'Total Coverage' | awk '{print $NF}' | tr -d '%') From 3a3be8544a72ba52eef70f4e31420e09348e1fb5 Mon Sep 17 00:00:00 2001 From: KirbytroNic0528 <133230754+KirbytroNic0528@users.noreply.github.com> Date: Thu, 17 Oct 2024 17:12:49 +0800 Subject: [PATCH 47/94] Update coverage_and_test.yml --- .github/workflows/coverage_and_test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/coverage_and_test.yml b/.github/workflows/coverage_and_test.yml index cf3bc7c5c..6dd55aac1 100644 --- a/.github/workflows/coverage_and_test.yml +++ b/.github/workflows/coverage_and_test.yml @@ -4,7 +4,7 @@ on: push: branches: - main - pull_request: + pull_request_target: jobs: build: From 8590315d85095d1715a0f53edc9f7ba2f1694e79 Mon Sep 17 00:00:00 2001 From: KirbytroNic0528 <133230754+KirbytroNic0528@users.noreply.github.com> Date: Thu, 17 Oct 2024 17:14:40 +0800 Subject: [PATCH 48/94] Update coverage_and_test.yml --- .github/workflows/coverage_and_test.yml | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/.github/workflows/coverage_and_test.yml b/.github/workflows/coverage_and_test.yml index 6dd55aac1..f59f56b34 100644 --- a/.github/workflows/coverage_and_test.yml +++ b/.github/workflows/coverage_and_test.yml @@ -1,10 +1,9 @@ name: coverage_and_test on: - push: - branches: - - main - pull_request_target: + pull_request_target: + branches: + - main jobs: build: From d31dd70a4a3803596f1cc078483d6fb8909868ae Mon Sep 17 00:00:00 2001 From: KirbytroNic0528 <133230754+KirbytroNic0528@users.noreply.github.com> Date: Mon, 21 Oct 2024 10:39:17 +0800 Subject: [PATCH 49/94] Update coverage_and_test.yml --- .github/workflows/coverage_and_test.yml | 1 + 1 file changed, 1 insertion(+) diff --git a/.github/workflows/coverage_and_test.yml b/.github/workflows/coverage_and_test.yml index f59f56b34..246bd3124 100644 --- a/.github/workflows/coverage_and_test.yml +++ b/.github/workflows/coverage_and_test.yml @@ -2,6 +2,7 @@ name: coverage_and_test on: pull_request_target: + types: [opened, edited, synchronize] branches: - main From b1777a1043fd0e801ea328f58241003849dc3e92 Mon Sep 17 00:00:00 2001 From: KirbytroNic0528 <133230754+KirbytroNic0528@users.noreply.github.com> Date: Mon, 28 Oct 2024 09:56:10 +0800 Subject: [PATCH 50/94] Add files via upload --- scripts/zhipuai.py | 874 +++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 874 insertions(+) create mode 100644 scripts/zhipuai.py diff --git a/scripts/zhipuai.py b/scripts/zhipuai.py new file mode 100644 index 000000000..4136ac3e0 --- /dev/null +++ b/scripts/zhipuai.py @@ -0,0 +1,874 @@ +"""ZhipuAI chat models wrapper.""" + +from __future__ import annotations + +import json +import logging +import time +from collections.abc import AsyncIterator, Iterator +from contextlib import asynccontextmanager, contextmanager +from operator import itemgetter +from typing import ( + Any, + Callable, + Dict, + List, + Literal, + Optional, + Sequence, + Tuple, + Type, + Union, +) + +from langchain_core.callbacks import ( + AsyncCallbackManagerForLLMRun, + CallbackManagerForLLMRun, +) +from langchain_core.language_models import LanguageModelInput +from langchain_core.language_models.chat_models import ( + BaseChatModel, + agenerate_from_stream, + generate_from_stream, +) +from langchain_core.messages import ( + AIMessage, + AIMessageChunk, + BaseMessage, + BaseMessageChunk, + ChatMessage, + ChatMessageChunk, + HumanMessage, + HumanMessageChunk, + SystemMessage, + SystemMessageChunk, + ToolMessage, +) +from langchain_core.output_parsers.base import OutputParserLike +from langchain_core.output_parsers.openai_tools import ( + JsonOutputKeyToolsParser, + PydanticToolsParser, +) +from langchain_core.outputs import ChatGeneration, ChatGenerationChunk, ChatResult +from langchain_core.runnables import Runnable, RunnableMap, RunnablePassthrough +from langchain_core.tools import BaseTool +from langchain_core.utils import get_from_dict_or_env +from langchain_core.utils.function_calling import convert_to_openai_tool +from pydantic import BaseModel, ConfigDict, Field, model_validator + +logger = logging.getLogger(__name__) + +API_TOKEN_TTL_SECONDS = 3 * 60 +ZHIPUAI_API_BASE = "https://open.bigmodel.cn/api/paas/v4/chat/completions" + + +def _is_pydantic_class(obj: Any) -> bool: + return isinstance(obj, type) and issubclass(obj, BaseModel) + + +@contextmanager +def connect_sse(client: Any, method: str, url: str, **kwargs: Any) -> Iterator: + """Context manager for connecting to an SSE stream. + + Args: + client: The HTTP client. + method: The HTTP method. + url: The URL. + kwargs: Additional keyword arguments. + + Yields: + The event source. + """ + from httpx_sse import EventSource + + with client.stream(method, url, **kwargs) as response: + yield EventSource(response) + + +@asynccontextmanager +async def aconnect_sse( + client: Any, method: str, url: str, **kwargs: Any +) -> AsyncIterator: + """Async context manager for connecting to an SSE stream. + + Args: + client: The HTTP client. + method: The HTTP method. + url: The URL. + kwargs: Additional keyword arguments. + + Yields: + The event source. + """ + from httpx_sse import EventSource + + async with client.stream(method, url, **kwargs) as response: + yield EventSource(response) + + +def _get_jwt_token(api_key: str) -> str: + """Gets JWT token for ZhipuAI API. + + See 'https://open.bigmodel.cn/dev/api#nosdk'. + + Args: + api_key: The API key for ZhipuAI API. + + Returns: + The JWT token. + """ + try: + import jwt + except ImportError: + raise ImportError( + "jwt package not found, please install it with" "`pip install pyjwt`" + ) + + try: + id, secret = api_key.split(".") + except ValueError as err: + raise ValueError(f"Invalid API key: {api_key}") from err + + payload = { + "api_key": id, + "exp": int(round(time.time() * 1000)) + API_TOKEN_TTL_SECONDS * 1000, + "timestamp": int(round(time.time() * 1000)), + } + + return jwt.encode( + payload, + secret, + algorithm="HS256", + headers={"alg": "HS256", "sign_type": "SIGN"}, + ) + + +def _convert_dict_to_message(dct: Dict[str, Any]) -> BaseMessage: + role = dct.get("role") + content = dct.get("content", "") + if role == "system": + return SystemMessage(content=content) + if role == "user": + return HumanMessage(content=content) + if role == "assistant": + additional_kwargs = {} + tool_calls = dct.get("tool_calls", None) + if tool_calls is not None: + additional_kwargs["tool_calls"] = tool_calls + return AIMessage(content=content, additional_kwargs=additional_kwargs) + if role == "tool": + additional_kwargs = {} + if "name" in dct: + additional_kwargs["name"] = dct["name"] + return ToolMessage( + content=content, + tool_call_id=dct.get("tool_call_id"), # type: ignore[arg-type] + additional_kwargs=additional_kwargs, + ) + return ChatMessage(role=role, content=content) # type: ignore[arg-type] + + +def _convert_message_to_dict(message: BaseMessage) -> Dict[str, Any]: + """Convert a LangChain message to a dictionary. + + Args: + message: The LangChain message. + + Returns: + The dictionary. + """ + message_dict: Dict[str, Any] + if isinstance(message, ChatMessage): + message_dict = {"role": message.role, "content": message.content} + elif isinstance(message, SystemMessage): + message_dict = {"role": "system", "content": message.content} + elif isinstance(message, HumanMessage): + message_dict = {"role": "user", "content": message.content} + elif isinstance(message, AIMessage): + message_dict = {"role": "assistant", "content": message.content} + elif isinstance(message, ToolMessage): + message_dict = { + "role": "tool", + "content": message.content, + "tool_call_id": message.tool_call_id, + "name": message.name or message.additional_kwargs.get("name"), + } + else: + raise TypeError(f"Got unknown type '{message.__class__.__name__}'.") + return message_dict + + +def _convert_delta_to_message_chunk( + dct: Dict[str, Any], default_class: Type[BaseMessageChunk] +) -> BaseMessageChunk: + role = dct.get("role") + content = dct.get("content", "") + additional_kwargs = {} + tool_calls = dct.get("tool_call", None) + if tool_calls is not None: + additional_kwargs["tool_calls"] = tool_calls + + if role == "system" or default_class == SystemMessageChunk: + return SystemMessageChunk(content=content) + if role == "user" or default_class == HumanMessageChunk: + return HumanMessageChunk(content=content) + if role == "assistant" or default_class == AIMessageChunk: + return AIMessageChunk(content=content, additional_kwargs=additional_kwargs) + if role or default_class == ChatMessageChunk: + return ChatMessageChunk(content=content, role=role) # type: ignore[arg-type] + return default_class(content=content) # type: ignore[call-arg] + + +def _truncate_params(payload: Dict[str, Any]) -> None: + """Truncate temperature and top_p parameters between [0.01, 0.99]. + + ZhipuAI only support temperature / top_p between (0, 1) open interval, + so we truncate them to [0.01, 0.99]. + """ + temperature = payload.get("temperature") + top_p = payload.get("top_p") + if temperature is not None: + payload["temperature"] = max(0.01, min(0.99, temperature)) + if top_p is not None: + payload["top_p"] = max(0.01, min(0.99, top_p)) + + +class ChatZhipuAI(BaseChatModel): + """ZhipuAI chat model integration. + + Setup: + Install ``PyJWT`` and set environment variable ``ZHIPUAI_API_KEY`` + + .. code-block:: bash + + pip install pyjwt + export ZHIPUAI_API_KEY="your-api-key" + + Key init args — completion params: + model: Optional[str] + Name of ZhipuAI model to use. + temperature: float + Sampling temperature. + max_tokens: Optional[int] + Max number of tokens to generate. + + Key init args — client params: + api_key: Optional[str] + ZhipuAI API key. If not passed in will be read from env var ZHIPUAI_API_KEY. + api_base: Optional[str] + Base URL for API requests. + + See full list of supported init args and their descriptions in the params section. + + Instantiate: + .. code-block:: python + + from langchain_community.chat_models import ChatZhipuAI + + zhipuai_chat = ChatZhipuAI( + temperature=0.5, + api_key="your-api-key", + model="glm-4", + # api_base="...", + # other params... + ) + + Invoke: + .. code-block:: python + + messages = [ + ("system", "你是一名专业的翻译家,可以将用户的中文翻译为英文。"), + ("human", "我喜欢编程。"), + ] + zhipuai_chat.invoke(messages) + + .. code-block:: python + + AIMessage(content='I enjoy programming.', response_metadata={'token_usage': {'completion_tokens': 6, 'prompt_tokens': 23, 'total_tokens': 29}, 'model_name': 'glm-4', 'finish_reason': 'stop'}, id='run-c5d9af91-55c6-470e-9545-02b2fa0d7f9d-0') + + Stream: + .. code-block:: python + + for chunk in zhipuai_chat.stream(messages): + print(chunk) + + .. code-block:: python + + content='I' id='run-4df71729-618f-4e2b-a4ff-884682723082' + content=' enjoy' id='run-4df71729-618f-4e2b-a4ff-884682723082' + content=' programming' id='run-4df71729-618f-4e2b-a4ff-884682723082' + content='.' id='run-4df71729-618f-4e2b-a4ff-884682723082' + content='' response_metadata={'finish_reason': 'stop'} id='run-4df71729-618f-4e2b-a4ff-884682723082' + + .. code-block:: python + + stream = zhipuai_chat.stream(messages) + full = next(stream) + for chunk in stream: + full += chunk + full + + .. code-block:: + + AIMessageChunk(content='I enjoy programming.', response_metadata={'finish_reason': 'stop'}, id='run-20b05040-a0b4-4715-8fdc-b39dba9bfb53') + + Async: + .. code-block:: python + + await zhipuai_chat.ainvoke(messages) + + # stream: + # async for chunk in zhipuai_chat.astream(messages): + # print(chunk) + + # batch: + # await zhipuai_chat.abatch([messages]) + + .. code-block:: python + + [AIMessage(content='I enjoy programming.', response_metadata={'token_usage': {'completion_tokens': 6, 'prompt_tokens': 23, 'total_tokens': 29}, 'model_name': 'glm-4', 'finish_reason': 'stop'}, id='run-ba06af9d-4baa-40b2-9298-be9c62aa0849-0')] + + Tool calling: + .. code-block:: python + + from pydantic import BaseModel, Field + + + class GetWeather(BaseModel): + '''Get the current weather in a given location''' + + location: str = Field( + ..., description="The city and state, e.g. San Francisco, CA" + ) + + + class GetPopulation(BaseModel): + '''Get the current population in a given location''' + + location: str = Field( + ..., description="The city and state, e.g. San Francisco, CA" + ) + + chat_with_tools = zhipuai_chat.bind_tools([GetWeather, GetPopulation]) + ai_msg = chat_with_tools.invoke( + "Which city is hotter today and which is bigger: LA or NY?" + ) + ai_msg.tool_calls + + .. code-block:: python + + [ + { + 'name': 'GetWeather', + 'args': {'location': 'Los Angeles, CA'}, + 'id': 'call_202408222146464ea49ec8731145a9', + 'type': 'tool_call' + } + ] + + Structured output: + .. code-block:: python + + from typing import Optional + + from pydantic import BaseModel, Field + + + class Joke(BaseModel): + '''Joke to tell user.''' + + setup: str = Field(description="The setup of the joke") + punchline: str = Field(description="The punchline to the joke") + rating: Optional[int] = Field(description="How funny the joke is, from 1 to 10") + + + structured_chat = zhipuai_chat.with_structured_output(Joke) + structured_chat.invoke("Tell me a joke about cats") + + .. code-block:: python + + Joke(setup='What do cats like to eat for breakfast?', punchline='Mice Krispies!', rating=None) + + Response metadata + .. code-block:: python + + ai_msg = zhipuai_chat.invoke(messages) + ai_msg.response_metadata + + .. code-block:: python + + {'token_usage': {'completion_tokens': 6, + 'prompt_tokens': 23, + 'total_tokens': 29}, + 'model_name': 'glm-4', + 'finish_reason': 'stop'} + + """ # noqa: E501 + + @property + def lc_secrets(self) -> Dict[str, str]: + return {"zhipuai_api_key": "ZHIPUAI_API_KEY"} + + @classmethod + def get_lc_namespace(cls) -> List[str]: + """Get the namespace of the langchain object.""" + return ["langchain", "chat_models", "zhipuai"] + + @property + def lc_attributes(self) -> Dict[str, Any]: + attributes: Dict[str, Any] = {} + + if self.zhipuai_api_base: + attributes["zhipuai_api_base"] = self.zhipuai_api_base + + return attributes + + @property + def _llm_type(self) -> str: + """Return the type of chat model.""" + return "zhipuai-chat" + + @property + def _default_params(self) -> Dict[str, Any]: + """Get the default parameters for calling OpenAI API.""" + params = { + "model": self.model_name, + "stream": self.streaming, + "temperature": self.temperature, + } + if self.max_tokens is not None: + params["max_tokens"] = self.max_tokens + return params + + # client: + zhipuai_api_key: Optional[str] = Field(default=None, alias="api_key") + """Automatically inferred from env var `ZHIPUAI_API_KEY` if not provided.""" + zhipuai_api_base: Optional[str] = Field(default=None, alias="api_base") + """Base URL path for API requests, leave blank if not using a proxy or service + emulator. + """ + + model_name: Optional[str] = Field(default="glm-4", alias="model") + """ + Model name to use, see 'https://open.bigmodel.cn/dev/api#language'. + Alternatively, you can use any fine-tuned model from the GLM series. + """ + + temperature: float = 0.95 + """ + What sampling temperature to use. The value ranges from 0.0 to 1.0 and cannot + be equal to 0. + The larger the value, the more random and creative the output; The smaller + the value, the more stable or certain the output will be. + You are advised to adjust top_p or temperature parameters based on application + scenarios, but do not adjust the two parameters at the same time. + """ + + top_p: float = 0.7 + """ + Another method of sampling temperature is called nuclear sampling. The value + ranges from 0.0 to 1.0 and cannot be equal to 0 or 1. + The model considers the results with top_p probability quality tokens. + For example, 0.1 means that the model decoder only considers tokens from the + top 10% probability of the candidate set. + You are advised to adjust top_p or temperature parameters based on application + scenarios, but do not adjust the two parameters at the same time. + """ + + streaming: bool = False + """Whether to stream the results or not.""" + max_tokens: Optional[int] = None + """Maximum number of tokens to generate.""" + + model_config = ConfigDict( + populate_by_name=True, + ) + + @model_validator(mode="before") + @classmethod + def validate_environment(cls, values: Dict[str, Any]) -> Any: + values["zhipuai_api_key"] = get_from_dict_or_env( + values, ["zhipuai_api_key", "api_key"], "ZHIPUAI_API_KEY" + ) + values["zhipuai_api_base"] = get_from_dict_or_env( + values, "zhipuai_api_base", "ZHIPUAI_API_BASE", default=ZHIPUAI_API_BASE + ) + + return values + + def _create_message_dicts( + self, messages: List[BaseMessage], stop: Optional[List[str]] + ) -> Tuple[List[Dict[str, Any]], Dict[str, Any]]: + params = self._default_params + if stop is not None: + params["stop"] = stop + message_dicts = [_convert_message_to_dict(m) for m in messages] + return message_dicts, params + + def _create_chat_result(self, response: Union[dict, BaseModel]) -> ChatResult: + generations = [] + if not isinstance(response, dict): + response = response.dict() + for res in response["choices"]: + message = _convert_dict_to_message(res["message"]) + generation_info = dict(finish_reason=res.get("finish_reason")) + generations.append( + ChatGeneration(message=message, generation_info=generation_info) + ) + token_usage = response.get("usage", {}) + llm_output = { + "token_usage": token_usage, + "model_name": self.model_name, + } + return ChatResult(generations=generations, llm_output=llm_output) + + def _generate( + self, + messages: List[BaseMessage], + stop: Optional[List[str]] = None, + run_manager: Optional[CallbackManagerForLLMRun] = None, + stream: Optional[bool] = None, + **kwargs: Any, + ) -> ChatResult: + """Generate a chat response.""" + should_stream = stream if stream is not None else self.streaming + if should_stream: + stream_iter = self._stream( + messages, stop=stop, run_manager=run_manager, **kwargs + ) + return generate_from_stream(stream_iter) + + if self.zhipuai_api_key is None: + raise ValueError("Did not find zhipuai_api_key.") + message_dicts, params = self._create_message_dicts(messages, stop) + payload = { + **params, + **kwargs, + "messages": message_dicts, + "stream": False, + } + _truncate_params(payload) + headers = { + "Authorization": _get_jwt_token(self.zhipuai_api_key), + "Accept": "application/json", + } + import httpx + + with httpx.Client(headers=headers, timeout=60) as client: + response = client.post(self.zhipuai_api_base, json=payload) # type: ignore[arg-type] + response.raise_for_status() + return self._create_chat_result(response.json()) + + def _stream( + self, + messages: List[BaseMessage], + stop: Optional[List[str]] = None, + run_manager: Optional[CallbackManagerForLLMRun] = None, + **kwargs: Any, + ) -> Iterator[ChatGenerationChunk]: + """Stream the chat response in chunks.""" + if self.zhipuai_api_key is None: + raise ValueError("Did not find zhipuai_api_key.") + if self.zhipuai_api_base is None: + raise ValueError("Did not find zhipu_api_base.") + message_dicts, params = self._create_message_dicts(messages, stop) + payload = {**params, **kwargs, "messages": message_dicts, "stream": True} + _truncate_params(payload) + headers = { + "Authorization": _get_jwt_token(self.zhipuai_api_key), + "Accept": "application/json", + } + + default_chunk_class = AIMessageChunk + import httpx + + with httpx.Client(headers=headers, timeout=60) as client: + with connect_sse( + client, "POST", self.zhipuai_api_base, json=payload + ) as event_source: + for sse in event_source.iter_sse(): + chunk = json.loads(sse.data) + if len(chunk["choices"]) == 0: + continue + choice = chunk["choices"][0] + chunk = _convert_delta_to_message_chunk( + choice["delta"], default_chunk_class + ) + finish_reason = choice.get("finish_reason", None) + + generation_info = ( + {"finish_reason": finish_reason} + if finish_reason is not None + else None + ) + chunk = ChatGenerationChunk( + message=chunk, generation_info=generation_info + ) + if run_manager: + run_manager.on_llm_new_token(chunk.text, chunk=chunk) + yield chunk + + if finish_reason is not None: + break + + async def _agenerate( + self, + messages: List[BaseMessage], + stop: Optional[List[str]] = None, + run_manager: Optional[AsyncCallbackManagerForLLMRun] = None, + stream: Optional[bool] = None, + **kwargs: Any, + ) -> ChatResult: + should_stream = stream if stream is not None else self.streaming + if should_stream: + stream_iter = self._astream( + messages, stop=stop, run_manager=run_manager, **kwargs + ) + return await agenerate_from_stream(stream_iter) + + if self.zhipuai_api_key is None: + raise ValueError("Did not find zhipuai_api_key.") + message_dicts, params = self._create_message_dicts(messages, stop) + payload = { + **params, + **kwargs, + "messages": message_dicts, + "stream": False, + } + _truncate_params(payload) + headers = { + "Authorization": _get_jwt_token(self.zhipuai_api_key), + "Accept": "application/json", + } + import httpx + + async with httpx.AsyncClient(headers=headers, timeout=60) as client: + response = await client.post(self.zhipuai_api_base, json=payload) # type: ignore[arg-type] + response.raise_for_status() + return self._create_chat_result(response.json()) + + async def _astream( + self, + messages: List[BaseMessage], + stop: Optional[List[str]] = None, + run_manager: Optional[AsyncCallbackManagerForLLMRun] = None, + **kwargs: Any, + ) -> AsyncIterator[ChatGenerationChunk]: + if self.zhipuai_api_key is None: + raise ValueError("Did not find zhipuai_api_key.") + if self.zhipuai_api_base is None: + raise ValueError("Did not find zhipu_api_base.") + message_dicts, params = self._create_message_dicts(messages, stop) + payload = {**params, **kwargs, "messages": message_dicts, "stream": True} + _truncate_params(payload) + headers = { + "Authorization": _get_jwt_token(self.zhipuai_api_key), + "Accept": "application/json", + } + + default_chunk_class = AIMessageChunk + import httpx + + async with httpx.AsyncClient(headers=headers, timeout=none) as client: + async with aconnect_sse( + client, "POST", self.zhipuai_api_base, json=payload + ) as event_source: + async for sse in event_source.aiter_sse(): + chunk = json.loads(sse.data) + if len(chunk["choices"]) == 0: + continue + choice = chunk["choices"][0] + chunk = _convert_delta_to_message_chunk( + choice["delta"], default_chunk_class + ) + finish_reason = choice.get("finish_reason", None) + + generation_info = ( + {"finish_reason": finish_reason} + if finish_reason is not None + else None + ) + chunk = ChatGenerationChunk( + message=chunk, generation_info=generation_info + ) + if run_manager: + await run_manager.on_llm_new_token(chunk.text, chunk=chunk) + yield chunk + + if finish_reason is not None: + break + + def bind_tools( + self, + tools: Sequence[Union[Dict[str, Any], Type[BaseModel], Callable, BaseTool]], + *, + tool_choice: Optional[ + Union[dict, str, Literal["auto", "any", "none"], bool] + ] = None, + **kwargs: Any, + ) -> Runnable[LanguageModelInput, BaseMessage]: + """Bind tool-like objects to this chat model. + Args: + tools: A list of tool definitions to bind to this chat model. + Can be a dictionary, pydantic model, callable, or BaseTool. Pydantic + models, callables, and BaseTools will be automatically converted to + their schema dictionary representation. + tool_choice: Currently this can only be auto for this chat model. + **kwargs: Any additional parameters to pass to the + :class:`~langchain.runnable.Runnable` constructor. + """ + if self.model_name == "glm-4v": + raise ValueError("glm-4v currently does not support tool calling") + + formatted_tools = [convert_to_openai_tool(tool) for tool in tools] + if tool_choice and tool_choice != "auto": + raise ValueError("ChatZhipuAI currently only supports `auto` tool choice") + elif tool_choice and tool_choice == "auto": + kwargs["tool_choice"] = tool_choice + return self.bind(tools=formatted_tools, **kwargs) + + def with_structured_output( + self, + schema: Optional[Union[Dict, Type[BaseModel]]] = None, + *, + method: Literal["function_calling", "json_mode"] = "function_calling", + include_raw: bool = False, + **kwargs: Any, + ) -> Runnable[LanguageModelInput, Union[Dict, BaseModel]]: + """Model wrapper that returns outputs formatted to match the given schema. + + Args: + schema: The output schema as a dict or a Pydantic class. If a Pydantic class + then the model output will be an object of that class. If a dict then + the model output will be a dict. With a Pydantic class the returned + attributes will be validated, whereas with a dict they will not be. If + `method` is "function_calling" and `schema` is a dict, then the dict + must match the OpenAI function-calling spec. + method: The method for steering model generation, either "function_calling" + or "json_mode". ZhipuAI only supports "function_calling" which + converts the schema to a OpenAI function and the model will make use of the + function-calling API. + include_raw: If False then only the parsed structured output is returned. If + an error occurs during model output parsing it will be raised. If True + then both the raw model response (a BaseMessage) and the parsed model + response will be returned. If an error occurs during output parsing it + will be caught and returned as well. The final output is always a dict + with keys "raw", "parsed", and "parsing_error". + + Returns: + A Runnable that takes any ChatModel input and returns as output: + + If include_raw is True then a dict with keys: + raw: BaseMessage + parsed: Optional[_DictOrPydantic] + parsing_error: Optional[BaseException] + + If include_raw is False then just _DictOrPydantic is returned, + where _DictOrPydantic depends on the schema: + + If schema is a Pydantic class then _DictOrPydantic is the Pydantic + class. + + If schema is a dict then _DictOrPydantic is a dict. + + Example: Function-calling, Pydantic schema (method="function_calling", include_raw=False): + .. code-block:: python + + from langchain_community.chat_models import ChatZhipuAI + from pydantic import BaseModel + + class AnswerWithJustification(BaseModel): + '''An answer to the user question along with justification for the answer.''' + answer: str + justification: str + + llm = ChatZhipuAI(temperature=0) + structured_llm = llm.with_structured_output(AnswerWithJustification) + + structured_llm.invoke("What weighs more a pound of bricks or a pound of feathers") + # -> AnswerWithJustification( + # answer='A pound of bricks and a pound of feathers weigh the same.' + # justification="Both a pound of bricks and a pound of feathers have been defined to have the same weight. The 'pound' is a unit of weight, so any two things that are described as weighing a pound will weigh the same." + # ) + + Example: Function-calling, Pydantic schema (method="function_calling", include_raw=True): + .. code-block:: python + + from langchain_community.chat_models import ChatZhipuAI + from pydantic import BaseModel + + class AnswerWithJustification(BaseModel): + '''An answer to the user question along with justification for the answer.''' + answer: str + justification: str + + llm = ChatZhipuAI(temperature=0) + structured_llm = llm.with_structured_output(AnswerWithJustification, include_raw=True) + + structured_llm.invoke("What weighs more a pound of bricks or a pound of feathers") + # -> { + # 'raw': AIMessage(content='', additional_kwargs={'tool_calls': [{'id': 'call_01htjn3cspevxbqc1d7nkk8wab', 'function': {'arguments': '{"answer": "A pound of bricks and a pound of feathers weigh the same.", "justification": "Both a pound of bricks and a pound of feathers have been defined to have the same weight. The \'pound\' is a unit of weight, so any two things that are described as weighing a pound will weigh the same.", "unit": "pounds"}', 'name': 'AnswerWithJustification'}, 'type': 'function'}]}, id='run-456beee6-65f6-4e80-88af-a6065480822c-0'), + # 'parsed': AnswerWithJustification(answer='A pound of bricks and a pound of feathers weigh the same.', justification="Both a pound of bricks and a pound of feathers have been defined to have the same weight. The 'pound' is a unit of weight, so any two things that are described as weighing a pound will weigh the same."), + # 'parsing_error': None + # } + + Example: Function-calling, dict schema (method="function_calling", include_raw=False): + .. code-block:: python + + from langchain_community.chat_models import ChatZhipuAI + from pydantic import BaseModel + from langchain_core.utils.function_calling import convert_to_openai_tool + + class AnswerWithJustification(BaseModel): + '''An answer to the user question along with justification for the answer.''' + answer: str + justification: str + + dict_schema = convert_to_openai_tool(AnswerWithJustification) + llm = ChatZhipuAI(temperature=0) + structured_llm = llm.with_structured_output(dict_schema) + + structured_llm.invoke("What weighs more a pound of bricks or a pound of feathers") + # -> { + # 'answer': 'A pound of bricks and a pound of feathers weigh the same.', + # 'justification': "Both a pound of bricks and a pound of feathers have been defined to have the same weight. The 'pound' is a unit of weight, so any two things that are described as weighing a pound will weigh the same.", 'unit': 'pounds'} + # } + + """ # noqa: E501 + if kwargs: + raise ValueError(f"Received unsupported arguments {kwargs}") + is_pydantic_schema = _is_pydantic_class(schema) + if method == "function_calling": + if schema is None: + raise ValueError( + "schema must be specified when method is 'function_calling'. " + "Received None." + ) + tool_name = convert_to_openai_tool(schema)["function"]["name"] + llm = self.bind_tools([schema], tool_choice="auto") + if is_pydantic_schema: + output_parser: OutputParserLike = PydanticToolsParser( + tools=[schema], # type: ignore[list-item] + first_tool_only=True, # type: ignore[list-item] + ) + else: + output_parser = JsonOutputKeyToolsParser( + key_name=tool_name, first_tool_only=True + ) + else: + raise ValueError( + f"""Unrecognized method argument. Expected 'function_calling'. + Received: '{method}'""" + ) + + if include_raw: + parser_assign = RunnablePassthrough.assign( + parsed=itemgetter("raw") | output_parser, parsing_error=lambda _: None + ) + parser_none = RunnablePassthrough.assign(parsed=lambda _: None) + parser_with_fallback = parser_assign.with_fallbacks( + [parser_none], exception_key="parsing_error" + ) + return RunnableMap(raw=llm) | parser_with_fallback + else: + return llm | output_parser From d1d1ca7cd9e93bd224a34886c5cc81b0cdbf8312 Mon Sep 17 00:00:00 2001 From: KirbytroNic0528 <133230754+KirbytroNic0528@users.noreply.github.com> Date: Mon, 28 Oct 2024 09:57:18 +0800 Subject: [PATCH 51/94] Update gettest.py --- scripts/gettest.py | 89 ++++++++++++++++++++++++++++++++++++++-------- 1 file changed, 75 insertions(+), 14 deletions(-) diff --git a/scripts/gettest.py b/scripts/gettest.py index 1c24324da..f55f3c5e2 100644 --- a/scripts/gettest.py +++ b/scripts/gettest.py @@ -1,29 +1,90 @@ -from langchain_community.chat_models import ChatZhipuAI +from zhipuai import ChatZhipuAI from langchain_core.output_parsers import StrOutputParser from langchain_core.prompts import ChatPromptTemplate +import os def generate_test_code(moonbit_code, path, api_key): + filename = os.path.basename(path) test_prompt = ChatPromptTemplate.from_template( - """作为一名MoonBit语言工程师,你的任务是编写一系列测试用例来验证项目的正确性。 - 请根据以下提供的格式,结合文件名{path}理解函数的用途,对给出的MoonBit函数编写对应的测试用例, - 以下是你需要提供的测试用例格式参考: - test {{ - assert_eq!(f(x)) - assert_eq!(f(x)) - }} - 需要提供测试用例的MoonBit函数为{moonbit_code}。 - 注意,你的输出中只需要包含测试用例的代码,不需要包括分析过程以及任何其他语句。 - 同时,你生成的是moonbit语言的测试用例,请不要将moonbit语言与其他语言混淆 + """As a MoonBit language engineer, your task is to write a series of test cases to + verify the correctness of a project. + Based on the provided format and the understanding of the function's purpose + from the filename {filename}, write corresponding test cases for the given MoonBit function + including edge cases and any potential error scenarios: + test {{ + assert_eq!(f(x)) + assert_eq!(f(x)) + }} + Provide test cases for the MoonBit function given as {moonbit_code}. + Note that your output should only contain the code for the test cases, + without any analysis, explanations, or any other statements. + Also, ensure that you are generating test cases for the MoonBit language, + and do not confuse MoonBit language with any other + Attention, just generate a test function and the function must not exceed 1500 bytes . """ ) test_llm = ChatZhipuAI( - api_key=api_key, model="glm-4-plus", temperature=0.5 + api_key=api_key, model="glm-4-9b:772570335:v3:odbzuhb9", temperature=0.5, max_tokens=2048 ) test_retriever_chain = test_prompt | test_llm | StrOutputParser() - test_code = test_retriever_chain.invoke( - {"moonbit_code": moonbit_code, "path": path} + test_code_output = test_retriever_chain.invoke( + {"moonbit_code": moonbit_code, "filename": filename} + ) + test_code = test_code_output.replace("```moonbit\n", "").rstrip( + "```" + ) + return test_code + + +def rethink_test_code(moonbit_code, test_moonbit_code, file_path, error_message, api_key): + filename = os.path.basename(file_path) + rethink_prompt = ChatPromptTemplate.from_template( + """You are a professional MoonBit language engineer. Now, you need to help me analyze and correct a test case. + I will provide the following information: + 1. **Test Case Filename**: This helps you understand the context of the test case. + 2. **Test Case Code**: This is the current test case code, which may contain errors leading to test failures. + 3. **Test Error Message**: This is the error message generated when running the test case, + which can help you pinpoint the issue. + 4. **MoonBit Code**: This is the actual MoonBit code that the test case is supposed to test. + + Please carefully read this information, analyze the cause of the error, and generate a corrected test case code. + Ensure that your output code passes the test and is logically correct. + + **Input Format:** + Filename: + Test Case Code: + Error Message: + MoonBit Code: + + **Output Format:** + Corrected Test Case Code: + + If the test case encounters issues with data structure usage, + please modify the data structures used in the test case based on the file name. + If there are issues with the values in the test case, + please remove the assertion values in the assert statement. + + Now, please generate the corrected test case code based on the following input information: + MoonBit Code:{moonbit_code} + Filename: {filename} + Test Case Code:{test_moonbit_code} + Error Message:{error_message} + + Please note, your output should only contain the corrected test case code, without any additional analysis. + """ + ) + rethink_llm = ChatZhipuAI( + api_key=api_key, model="glm-4-9b:772570335:v3:odbzuhb9", temperature=0.5, max_tokens=2048 + ) + + rethink_retriever_chain = rethink_prompt | rethink_llm | StrOutputParser() + test_code_output = rethink_retriever_chain.invoke( + { "moonbit_code": moonbit_code, "filename": filename, "test_moonbit_code": test_moonbit_code, "error_message": error_message} + ) + test_code = test_code_output.replace("```moonbit\n", "").rstrip( + "```" ) return test_code From 3ccd47c26b8679f1e13b41c983671070df93107d Mon Sep 17 00:00:00 2001 From: KirbytroNic0528 <133230754+KirbytroNic0528@users.noreply.github.com> Date: Mon, 28 Oct 2024 09:57:36 +0800 Subject: [PATCH 52/94] Update readcoverage.py --- scripts/readcoverage.py | 53 ++++++++++++++++++++++++++++------------- 1 file changed, 36 insertions(+), 17 deletions(-) diff --git a/scripts/readcoverage.py b/scripts/readcoverage.py index f22bc833c..a934f0566 100644 --- a/scripts/readcoverage.py +++ b/scripts/readcoverage.py @@ -1,31 +1,50 @@ -from langchain_community.chat_models import ChatZhipuAI +from zhipuai import ChatZhipuAI from langchain_core.output_parsers import StrOutputParser from langchain_core.prompts import ChatPromptTemplate +def get_coverage_from_summary(file_path): + with open(file_path, 'r') as file: + lines = file.readlines() + last_line = lines[-1].strip() + + parts = last_line.split(':') + if len(parts) == 2 and parts[0].strip() == 'Total': + total_parts = parts[1].strip().split('/') + if len(total_parts) == 2: + total_passed = int(total_parts[0]) + total_tests = int(total_parts[1]) + coverage = total_passed / total_tests + return coverage + return 0.0 + + def read_coverage(moonbit_code, index, api_key): read_prompt = ChatPromptTemplate.from_template( - """ - You are a highly skilled MoonBit engineer. Now you need to read in MoonBit code and the indices of uncovered code lines, - then identify and return the functions containing those uncovered lines. - Input: - MoonBit code: {moonbit_code} - Indices of uncovered code lines: {index} - Output request: - Your output should only include the functions that contain the uncovered code. - Do not include any analysis process or any other statements in your output. + """You are a professional MoonBit code analyst. Your task is to find and return the complete function definition containing the given uncovered code line indices. + +Input: + +moonbit_code: The entire code in which you need to search for uncovered lines. +Uncovered code line index: An integer representing the line number of the code that is marked as uncovered. +Output requirements: + +For the given uncovered code line index, locate and return the complete function definition that contains that line. +The output should be a string representing the entire code of a function, including its signature and body. +Do not include any analysis process, additional information, or explanatory statements; just return the required function definition. + +Example: +If the uncovered code line index is [2], then the output should be the complete function definition that includes line 2. + Now, please find the uncovered code based on the following input information: + moonbit_code:{moonbit_code} + Uncovered code line index:{index} """ ) - read_llm = ChatZhipuAI( - api_key=api_key, model="glm-4-0520", temperature=0.5 - ) + read_llm = ChatZhipuAI(api_key=api_key, model="glm-4-plus", temperature=0.5) read_retriever_chain = read_prompt | read_llm | StrOutputParser() response = read_retriever_chain.invoke( - {"moonbit_code": moonbit_code, "index": index} + {"moonbit_code": moonbit_code, "index": [index]} ) return response - - - From 921d1dfeab4f953b206e15ea1fc4d10b137c172d Mon Sep 17 00:00:00 2001 From: KirbytroNic0528 <133230754+KirbytroNic0528@users.noreply.github.com> Date: Mon, 28 Oct 2024 09:58:03 +0800 Subject: [PATCH 53/94] Update testagent.py --- scripts/testagent.py | 72 +++++++++++++++++++++++++++----------------- 1 file changed, 45 insertions(+), 27 deletions(-) diff --git a/scripts/testagent.py b/scripts/testagent.py index 06e410e63..52884677d 100644 --- a/scripts/testagent.py +++ b/scripts/testagent.py @@ -1,46 +1,64 @@ import argparse import json -from readcoverage import read_coverage +import subprocess +from readcoverage import read_coverage, get_coverage_from_summary from gettest import generate_test_code -from writedown import writedown_and_test +from writedown import test_test_code -def main(): +def testagent(api_key): with open("coveralls.json", "r") as file: data = json.load(file) - parser = argparse.ArgumentParser(description="用于加载API密钥。") - parser.add_argument( - "--api_key", - type=str, - help="API密钥", - ) - args = parser.parse_args() - zhipuai_api_key = args.api_key for source_file in data["source_files"]: with open(source_file["name"], "r") as codefile: indexs = [ - indexs - for indexs, value in enumerate(source_file["coverage"]) + index + for index, value in enumerate(source_file["coverage"]) if value == 0 ] if indexs: - print(indexs) moonbit_code = codefile.read() for index in indexs: - for attempt in range(3): - response = read_coverage(moonbit_code, index, zhipuai_api_key) - print("未覆盖的函数声明为" + response) - response = generate_test_code( - response, source_file["name"], zhipuai_api_key - ) - test_code = response.replace("```moonbit\n", "").rstrip("```") - print("测试用例为" + test_code) - result = writedown_and_test(response, source_file["name"]) + uncovered_code = read_coverage(moonbit_code, index, api_key) + print(index) + print("uncovered code is" + uncovered_code) + test_code = generate_test_code( + uncovered_code, source_file["name"], api_key + ) + print("test_code is" + test_code) + test_test_code(uncovered_code, test_code, source_file["name"], zhipuai_api_key) + - if result == 0: - break +prev_coverage = get_coverage_from_summary("coverage_summary.txt") +max_iterations = 5 +iteration = 0 +coverage_improved = True +parser = argparse.ArgumentParser(description="to load API_KEY。") +parser.add_argument( + "--api_key", + type=str, + help="API_KEY", +) +args = parser.parse_args() +zhipuai_api_key = args.api_key +new_coverage = prev_coverage +while coverage_improved and iteration < max_iterations: + iteration += 1 + testagent(zhipuai_api_key) + subprocess.run(["moon", "test", "--enable-coverage"]) + subprocess.run(["moon", "coverage", "report", "-f", "coveralls"]) + subprocess.run( + ["moon", "coverage", "report", "-f", "summary", "summary"], + stdout=open("coverage_summary.txt", "w"), + ) + new_coverage = get_coverage_from_summary("coverage_summary.txt") + if new_coverage > prev_coverage: + prev_coverage = new_coverage + print(f"Coverage improved to {new_coverage}%") + else: + coverage_improved = False + print("Coverage did not improve. Stopping loop.") -if __name__ == "__main__": - main() +print(f"Final coverage: {new_coverage}%") From 16221dfc2d9ec1ad35ee95cef1e0d6b77826bf74 Mon Sep 17 00:00:00 2001 From: KirbytroNic0528 <133230754+KirbytroNic0528@users.noreply.github.com> Date: Mon, 28 Oct 2024 09:58:19 +0800 Subject: [PATCH 54/94] Update writedown.py --- scripts/writedown.py | 47 +++++++++++++++++++++++++++++++------------- 1 file changed, 33 insertions(+), 14 deletions(-) diff --git a/scripts/writedown.py b/scripts/writedown.py index e2f88218d..46d6672ff 100644 --- a/scripts/writedown.py +++ b/scripts/writedown.py @@ -1,5 +1,8 @@ +from gettest import rethink_test_code import subprocess import os + + def writedown_test_files(file_path, test_code): with open(file_path, "a") as file: file.write(test_code + "\n") @@ -7,22 +10,38 @@ def writedown_test_files(file_path, test_code): print(f"test_code has been written to {file_path}") -def writedown_and_test(response, file_path): +def test_test_code(moonbit_code, test_code, file_path, api_key): folder_path = os.path.dirname(file_path) + package_name = os.path.basename(os.path.dirname(file_path)) testcode_path = os.path.join(folder_path, "testcode.mbt") with open(testcode_path, "w", encoding="utf-8") as file: - file.write(response) - try: - result = subprocess.run( - ["moon", "test", "-f", file_path], capture_output=True, text=True + file.write(test_code) + test_result = subprocess.run( + ["moon", "test", "-p", package_name, "-f", file_path], + capture_output=True, + text=True, + ) + attempts = 0 + max_attempts = 3 + while test_result.returncode and attempts < max_attempts: + attempts += 1 + file.truncate(0) + new_test_code = generate_test_code( + moonbit_code, file_path, api_key + ) + file.write(new_test_code) + file.flush() + test_result = subprocess.run( + ["moon", "test", "-p", package_name, "-f", file_path], + capture_output=True, + text=True, ) - if result.returncode != 0: - os.remove(testcode_path) - return 1 - else: - os.remove(testcode_path) - writedown_test_files(file_path, response) - return 0 - except Exception as e: + if attempts == max_attempts: + print("get test_code fail") os.remove(testcode_path) - return 1 + return + + os.remove(testcode_path) + writedown_test_files(file_path, test_code) + print("get test_code success") + return From a806d21dcf838162f59311556efe88bcc23f3dbc Mon Sep 17 00:00:00 2001 From: KirbytroNic0528 <133230754+KirbytroNic0528@users.noreply.github.com> Date: Mon, 28 Oct 2024 09:58:47 +0800 Subject: [PATCH 55/94] Update coverage_and_test.yml --- .github/workflows/coverage_and_test.yml | 141 +++++++----------------- 1 file changed, 38 insertions(+), 103 deletions(-) diff --git a/.github/workflows/coverage_and_test.yml b/.github/workflows/coverage_and_test.yml index 246bd3124..3e8d97393 100644 --- a/.github/workflows/coverage_and_test.yml +++ b/.github/workflows/coverage_and_test.yml @@ -1,130 +1,55 @@ name: coverage_and_test on: - pull_request_target: - types: [opened, edited, synchronize] - branches: - - main + pull_request_target: + types: [synchronize, opened, edited,closed] + branches: + - main jobs: - build: - strategy: - matrix: - os: [ ubuntu-latest ] - runs-on: ubuntu-latest - continue-on-error: true - steps: - - uses: actions/checkout@v4 - - - name: install - run: | - curl -fsSL https://cli.moonbitlang.com/install/unix.sh | bash - echo "$HOME/.moon/bin" >> $GITHUB_PATH - - - name: moon version - run: | - moon version --all - moonrun --version - - - name: moon check - run: moon check --deny-warn - - - name: moon info - run: | - moon info - git diff --exit-code - - - name: Set ulimit and run moon test - run: | - ulimit -s 8176 - moon test --target all - moon test --release --target all - - - name: moon bundle - run: moon bundle --all - - - name: check core size - run: find ./target -name '*.core' | xargs ls -lh - - - name: format diff - run: | - moon fmt - git diff --exit-code - test: runs-on: ubuntu-latest continue-on-error: true steps: - uses: actions/checkout@v4 - with: - python-version: '3.9' - env: - API_KEY: ${{ secrets.ZHIPU_API_KEY }} - + - name: install run: | curl -fsSL https://cli.moonbitlang.com/install/unix.sh | bash echo "$HOME/.moon/bin" >> $GITHUB_PATH - + - name: initial moon test run: moon test --enable-coverage - - moon coverage report -f coveralls - name: initial coverage report run: | - moon coverage report -f summary > coverage_summary.txt + moon coverage report -f summary summary > coverage_summary.txt cat coverage_summary.txt >> "$GITHUB_STEP_SUMMARY" - - name: Install dependencies + + - name: coverage improvement + run: python scripts/testagent.py + + - name: Get code changes run: | - pip install -r scripts/requirements.txt + git diff > changes.txt - - name: loop coverage improvement - env: - API_KEY: ${{ secrets.ZHIPU_API_KEY }} - id: loop-coverage - run: - prev_coverage=$(cat coverage_summary.txt | grep 'Total Coverage' | awk '{print $NF}' | tr -d '%') - max_iterations=5 - iteration=0 - coverage_improved=true - - while [ "$coverage_improved" = true ] && [ $iteration -lt $max_iterations ]; do - - python scripts/testagent.py --api_key "${API_KEY}" - - moon test --enable-coverage - - moon coverage report -f coveralls - - moon coverage report -f summary summary > coverage_summary.txt - - new_coverage=$(cat coverage_summary.txt | grep 'Total Coverage' | awk '{print $NF}' | tr -d '%') - - if [ $(echo "$new_coverage > $prev_coverage" | bc) -eq 1 ]; then - - prev_coverage=$new_coverage - - echo "Coverage improved to $new_coverage%" - - else - coverage_improved=false - - echo "Coverage did not improve. Stopping loop." - - fi - - iteration=$((iteration + 1)) - - done - - - name: coverage report - run: | - cat coverage_summary.txt >> "$GITHUB_STEP_SUMMARY" - moon coverage report -f coveralls -o codecov_report.json --service-name github --service-job-id "$GITHUB_RUN_NUMBER" --service-pull-request "${{ github.event.number }}" --send-to coveralls + test_code=$(cat changes.txt) + + echo "::set-output name=test_code::$test_code" + + - name: push comments + uses: peter-evans/create-or-update-comment@v1 env: - COVERALLS_REPO_TOKEN: ${{ secrets.GITHUB_TOKEN }} + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + with: + commit-sha: ${{ github.event.pull_request.head.sha }} + body: | + Here are the test code changes: + ``` + ${{ steps.get_code_changes.outputs.test_code }} + ``` + reaction-type: rocket typo-check: runs-on: ubuntu-latest @@ -154,3 +79,13 @@ jobs: run: curl --proto '=https' --tlsv1.2 -LsSf https://github.com/korandoru/hawkeye/releases/download/$HAWKEYE_VERSION/hawkeye-installer.sh | sh - name: Check License Header run: hawkeye check + + + + + + + + + + From 33bbce74131d2b069cb24262de8cd53aa6e94ab0 Mon Sep 17 00:00:00 2001 From: KirbytroNic0528 <133230754+KirbytroNic0528@users.noreply.github.com> Date: Mon, 28 Oct 2024 10:07:12 +0800 Subject: [PATCH 56/94] Update testagent.py --- scripts/testagent.py | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/testagent.py b/scripts/testagent.py index 52884677d..6ef9d34c0 100644 --- a/scripts/testagent.py +++ b/scripts/testagent.py @@ -39,6 +39,7 @@ def testagent(api_key): "--api_key", type=str, help="API_KEY", + default=4a478b99108ee30c1ae4aaa0aefe6632.X8sj7A6gaBgWh9AE ) args = parser.parse_args() zhipuai_api_key = args.api_key From e132cbd29e9a819c562f96da333c25e8de1fbc8e Mon Sep 17 00:00:00 2001 From: KirbytroNic0528 <133230754+KirbytroNic0528@users.noreply.github.com> Date: Mon, 28 Oct 2024 10:07:50 +0800 Subject: [PATCH 57/94] Update coverage_and_test.yml --- .github/workflows/coverage_and_test.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/coverage_and_test.yml b/.github/workflows/coverage_and_test.yml index 3e8d97393..d0483578e 100644 --- a/.github/workflows/coverage_and_test.yml +++ b/.github/workflows/coverage_and_test.yml @@ -1,8 +1,7 @@ name: coverage_and_test on: - pull_request_target: - types: [synchronize, opened, edited,closed] + pull_request: branches: - main From a05e34897dd834c9cf3213c94f24caa4858f91ec Mon Sep 17 00:00:00 2001 From: KirbytroNic0528 <133230754+KirbytroNic0528@users.noreply.github.com> Date: Mon, 28 Oct 2024 10:08:56 +0800 Subject: [PATCH 58/94] Update coverage_and_test.yml --- .github/workflows/coverage_and_test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/coverage_and_test.yml b/.github/workflows/coverage_and_test.yml index d0483578e..8b2af1b8e 100644 --- a/.github/workflows/coverage_and_test.yml +++ b/.github/workflows/coverage_and_test.yml @@ -22,7 +22,7 @@ jobs: - name: initial coverage report run: | - moon coverage report -f summary summary > coverage_summary.txt + moon coverage report -f summary > coverage_summary.txt cat coverage_summary.txt >> "$GITHUB_STEP_SUMMARY" From 68f2fde6be9c4db0761a134ed2251c4b8bd0dc95 Mon Sep 17 00:00:00 2001 From: KirbytroNic0528 <133230754+KirbytroNic0528@users.noreply.github.com> Date: Mon, 28 Oct 2024 10:10:20 +0800 Subject: [PATCH 59/94] Update testagent.py --- scripts/testagent.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/testagent.py b/scripts/testagent.py index 6ef9d34c0..68a71270a 100644 --- a/scripts/testagent.py +++ b/scripts/testagent.py @@ -39,7 +39,7 @@ def testagent(api_key): "--api_key", type=str, help="API_KEY", - default=4a478b99108ee30c1ae4aaa0aefe6632.X8sj7A6gaBgWh9AE + default="4a478b99108ee30c1ae4aaa0aefe6632.X8sj7A6gaBgWh9AE" ) args = parser.parse_args() zhipuai_api_key = args.api_key From fc4bfd7815a83061a4be6f196b579749c15ca069 Mon Sep 17 00:00:00 2001 From: KirbytroNic0528 <133230754+KirbytroNic0528@users.noreply.github.com> Date: Mon, 28 Oct 2024 10:11:33 +0800 Subject: [PATCH 60/94] Update requirements.txt --- scripts/requirements.txt | 1 + 1 file changed, 1 insertion(+) diff --git a/scripts/requirements.txt b/scripts/requirements.txt index 3d5ca123d..db46e060e 100644 --- a/scripts/requirements.txt +++ b/scripts/requirements.txt @@ -2,3 +2,4 @@ langchain==0.3.1 argparse==1.4.0 langchain_community==0.3.1 pyjwt==2.9.0 +langchain_core==0.3.5 From 8ba79bb8340d402400865aeba902236abdf3c769 Mon Sep 17 00:00:00 2001 From: KirbytroNic0528 <133230754+KirbytroNic0528@users.noreply.github.com> Date: Mon, 28 Oct 2024 10:14:41 +0800 Subject: [PATCH 61/94] Update coverage_and_test.yml --- .github/workflows/coverage_and_test.yml | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/.github/workflows/coverage_and_test.yml b/.github/workflows/coverage_and_test.yml index 8b2af1b8e..9e0132dd5 100644 --- a/.github/workflows/coverage_and_test.yml +++ b/.github/workflows/coverage_and_test.yml @@ -11,12 +11,19 @@ jobs: continue-on-error: true steps: - uses: actions/checkout@v4 - + with: + python-version: 3.9 + + - name: Install dependencies + run: | + python -m pip install --upgrade pip + pip install -r requirements.txt + - name: install run: | curl -fsSL https://cli.moonbitlang.com/install/unix.sh | bash echo "$HOME/.moon/bin" >> $GITHUB_PATH - + - name: initial moon test run: moon test --enable-coverage From 766f02b69a1a1e156fa93a1acd3888de52be1393 Mon Sep 17 00:00:00 2001 From: KirbytroNic0528 <133230754+KirbytroNic0528@users.noreply.github.com> Date: Mon, 28 Oct 2024 10:15:16 +0800 Subject: [PATCH 62/94] Update coverage_and_test.yml --- .github/workflows/coverage_and_test.yml | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/.github/workflows/coverage_and_test.yml b/.github/workflows/coverage_and_test.yml index 9e0132dd5..021ba9997 100644 --- a/.github/workflows/coverage_and_test.yml +++ b/.github/workflows/coverage_and_test.yml @@ -16,8 +16,7 @@ jobs: - name: Install dependencies run: | - python -m pip install --upgrade pip - pip install -r requirements.txt + pip install -r scripts/requirements.txt - name: install run: | From 40cfc6eb12aa97986f4ef2c2d9128b968db81d74 Mon Sep 17 00:00:00 2001 From: KirbytroNic0528 <133230754+KirbytroNic0528@users.noreply.github.com> Date: Mon, 28 Oct 2024 10:16:16 +0800 Subject: [PATCH 63/94] Update requirements.txt --- scripts/requirements.txt | 1 - 1 file changed, 1 deletion(-) diff --git a/scripts/requirements.txt b/scripts/requirements.txt index db46e060e..3d5ca123d 100644 --- a/scripts/requirements.txt +++ b/scripts/requirements.txt @@ -2,4 +2,3 @@ langchain==0.3.1 argparse==1.4.0 langchain_community==0.3.1 pyjwt==2.9.0 -langchain_core==0.3.5 From 9b466c8414f0deb87469071d4e7e4b2aa2f6c171 Mon Sep 17 00:00:00 2001 From: KirbytroNic0528 <133230754+KirbytroNic0528@users.noreply.github.com> Date: Mon, 28 Oct 2024 10:18:48 +0800 Subject: [PATCH 64/94] Update coverage_and_test.yml --- .github/workflows/coverage_and_test.yml | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/.github/workflows/coverage_and_test.yml b/.github/workflows/coverage_and_test.yml index 021ba9997..23cf76192 100644 --- a/.github/workflows/coverage_and_test.yml +++ b/.github/workflows/coverage_and_test.yml @@ -29,8 +29,10 @@ jobs: - name: initial coverage report run: | moon coverage report -f summary > coverage_summary.txt + cat coverage_summary.txt >> "$GITHUB_STEP_SUMMARY" - + + moon coverage report -f coveralls - name: coverage improvement run: python scripts/testagent.py From d2aef310881b027cbcee825e20a7b10a2e4276a3 Mon Sep 17 00:00:00 2001 From: KirbytroNic0528 <133230754+KirbytroNic0528@users.noreply.github.com> Date: Mon, 28 Oct 2024 10:38:17 +0800 Subject: [PATCH 65/94] Update zhipuai.py --- scripts/zhipuai.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/scripts/zhipuai.py b/scripts/zhipuai.py index 4136ac3e0..624dbd745 100644 --- a/scripts/zhipuai.py +++ b/scripts/zhipuai.py @@ -554,7 +554,7 @@ def _generate( } import httpx - with httpx.Client(headers=headers, timeout=60) as client: + with httpx.Client(headers=headers, timeout=none) as client: response = client.post(self.zhipuai_api_base, json=payload) # type: ignore[arg-type] response.raise_for_status() return self._create_chat_result(response.json()) @@ -582,7 +582,7 @@ def _stream( default_chunk_class = AIMessageChunk import httpx - with httpx.Client(headers=headers, timeout=60) as client: + with httpx.Client(headers=headers, timeout=none) as client: with connect_sse( client, "POST", self.zhipuai_api_base, json=payload ) as event_source: From e8e5da2ef1f7f7857dc672040c1753c6bf6d6b93 Mon Sep 17 00:00:00 2001 From: KirbytroNic0528 <133230754+KirbytroNic0528@users.noreply.github.com> Date: Mon, 28 Oct 2024 10:40:20 +0800 Subject: [PATCH 66/94] Update zhipuai.py --- scripts/zhipuai.py | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/scripts/zhipuai.py b/scripts/zhipuai.py index 624dbd745..20fd7e1a3 100644 --- a/scripts/zhipuai.py +++ b/scripts/zhipuai.py @@ -554,7 +554,7 @@ def _generate( } import httpx - with httpx.Client(headers=headers, timeout=none) as client: + with httpx.Client(headers=headers, timeout=None) as client: response = client.post(self.zhipuai_api_base, json=payload) # type: ignore[arg-type] response.raise_for_status() return self._create_chat_result(response.json()) @@ -582,7 +582,7 @@ def _stream( default_chunk_class = AIMessageChunk import httpx - with httpx.Client(headers=headers, timeout=none) as client: + with httpx.Client(headers=headers, timeout=None) as client: with connect_sse( client, "POST", self.zhipuai_api_base, json=payload ) as event_source: @@ -642,7 +642,7 @@ async def _agenerate( } import httpx - async with httpx.AsyncClient(headers=headers, timeout=60) as client: + async with httpx.AsyncClient(headers=headers, timeout=None) as client: response = await client.post(self.zhipuai_api_base, json=payload) # type: ignore[arg-type] response.raise_for_status() return self._create_chat_result(response.json()) @@ -669,7 +669,7 @@ async def _astream( default_chunk_class = AIMessageChunk import httpx - async with httpx.AsyncClient(headers=headers, timeout=none) as client: + async with httpx.AsyncClient(headers=headers, timeout=None) as client: async with aconnect_sse( client, "POST", self.zhipuai_api_base, json=payload ) as event_source: From fc1a2e0d1f991f8207be40420cc0b36ee2956db5 Mon Sep 17 00:00:00 2001 From: KirbytroNic0528 <133230754+KirbytroNic0528@users.noreply.github.com> Date: Mon, 28 Oct 2024 10:44:13 +0800 Subject: [PATCH 67/94] Update writedown.py --- scripts/writedown.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/writedown.py b/scripts/writedown.py index 46d6672ff..639d70660 100644 --- a/scripts/writedown.py +++ b/scripts/writedown.py @@ -1,4 +1,4 @@ -from gettest import rethink_test_code +from gettest import rethink_test_code, generate_test_code import subprocess import os From ff999d1305c552539ea69a1debcf78334cf7ee29 Mon Sep 17 00:00:00 2001 From: KirbytroNic0528 <133230754+KirbytroNic0528@users.noreply.github.com> Date: Mon, 28 Oct 2024 10:44:35 +0800 Subject: [PATCH 68/94] Update gettest.py --- scripts/gettest.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/gettest.py b/scripts/gettest.py index f55f3c5e2..34fc1c059 100644 --- a/scripts/gettest.py +++ b/scripts/gettest.py @@ -26,7 +26,7 @@ def generate_test_code(moonbit_code, path, api_key): ) test_llm = ChatZhipuAI( - api_key=api_key, model="glm-4-9b:772570335:v3:odbzuhb9", temperature=0.5, max_tokens=2048 + api_key=api_key, model="glm-4-9b:772570335:v3:odbzuhb9", temperature=0.5, max_tokens=4095 ) test_retriever_chain = test_prompt | test_llm | StrOutputParser() From d1ae51902f8b38a0f6dac11645eac22dfa203b87 Mon Sep 17 00:00:00 2001 From: KirbytroNic0528 <133230754+KirbytroNic0528@users.noreply.github.com> Date: Mon, 28 Oct 2024 12:10:28 +0800 Subject: [PATCH 69/94] Update readcoverage.py --- scripts/readcoverage.py | 17 +++++++++++++++-- 1 file changed, 15 insertions(+), 2 deletions(-) diff --git a/scripts/readcoverage.py b/scripts/readcoverage.py index a934f0566..e8bc53720 100644 --- a/scripts/readcoverage.py +++ b/scripts/readcoverage.py @@ -20,12 +20,13 @@ def get_coverage_from_summary(file_path): def read_coverage(moonbit_code, index, api_key): + def read_coverage(moonbit, index, api_key): read_prompt = ChatPromptTemplate.from_template( """You are a professional MoonBit code analyst. Your task is to find and return the complete function definition containing the given uncovered code line indices. Input: -moonbit_code: The entire code in which you need to search for uncovered lines. +moonbit: The entire code in which you need to search for uncovered lines. Uncovered code line index: An integer representing the line number of the code that is marked as uncovered. Output requirements: @@ -36,8 +37,20 @@ def read_coverage(moonbit_code, index, api_key): Example: If the uncovered code line index is [2], then the output should be the complete function definition that includes line 2. Now, please find the uncovered code based on the following input information: - moonbit_code:{moonbit_code} + moonbit:{moonbit} Uncovered code line index:{index} +Attention, the language of the code is MoonBit. + + """ + ) + + read_llm = ChatZhipuAI(api_key=api_key, model="glm-4-plus", temperature=0.5) + + read_retriever_chain = read_prompt | read_llm | StrOutputParser() + response = read_retriever_chain.invoke( + {"moonbit": moonbit, "index": [index]} + ) + return response """ ) From 4d33546197a57a72c6e11dd896e064eaff6b8d73 Mon Sep 17 00:00:00 2001 From: KirbytroNic0528 <133230754+KirbytroNic0528@users.noreply.github.com> Date: Mon, 28 Oct 2024 12:11:06 +0800 Subject: [PATCH 70/94] Update gettest.py --- scripts/gettest.py | 35 ++++++++++++++++------------------- 1 file changed, 16 insertions(+), 19 deletions(-) diff --git a/scripts/gettest.py b/scripts/gettest.py index 34fc1c059..c781344b3 100644 --- a/scripts/gettest.py +++ b/scripts/gettest.py @@ -6,24 +6,21 @@ def generate_test_code(moonbit_code, path, api_key): filename = os.path.basename(path) - test_prompt = ChatPromptTemplate.from_template( - """As a MoonBit language engineer, your task is to write a series of test cases to - verify the correctness of a project. - Based on the provided format and the understanding of the function's purpose - from the filename {filename}, write corresponding test cases for the given MoonBit function - including edge cases and any potential error scenarios: - test {{ - assert_eq!(f(x)) - assert_eq!(f(x)) - }} - Provide test cases for the MoonBit function given as {moonbit_code}. - Note that your output should only contain the code for the test cases, - without any analysis, explanations, or any other statements. - Also, ensure that you are generating test cases for the MoonBit language, - and do not confuse MoonBit language with any other - Attention, just generate a test function and the function must not exceed 1500 bytes . - """ - ) + test_prompt = ChatPromptTemplate.from_messages([ + ("system", "As a MoonBit language engineer, your task is to write a series of test cases to verify the correctness of a project."), + ("system", "Based on the provided format and the understanding of the function's purpose from the filename {filename}, write corresponding test cases for the given MoonBit function including edge cases and any potential error scenarios:"), + ("system", "The test cases should be formatted as follows:"), + ("system", "test {{"), + ("system", " assert_eq!(f(x))"), + ("system", " assert_eq!(f(x))"), + ("system", "}}"), + ("system", "Provide test cases for the MoonBit function given as moonbit."), + ("system", "Note that your output should only contain the code for the test cases, without any analysis, explanations, or any other statements."), + ("system", "Also, ensure that you are generating test cases for the MoonBit language, and do not confuse MoonBit language with any other."), + ("system","Attention,you don't need to provide the results of the assertions. "), + ("user", "{moonbit}"), + ]) + test_llm = ChatZhipuAI( api_key=api_key, model="glm-4-9b:772570335:v3:odbzuhb9", temperature=0.5, max_tokens=4095 @@ -31,7 +28,7 @@ def generate_test_code(moonbit_code, path, api_key): test_retriever_chain = test_prompt | test_llm | StrOutputParser() test_code_output = test_retriever_chain.invoke( - {"moonbit_code": moonbit_code, "filename": filename} + {"moonbit": moonbit, "filename": filename} ) test_code = test_code_output.replace("```moonbit\n", "").rstrip( "```" From 695c11bba4fc1dc9b5f2897405081d2cec9408b6 Mon Sep 17 00:00:00 2001 From: KirbytroNic0528 <133230754+KirbytroNic0528@users.noreply.github.com> Date: Mon, 28 Oct 2024 12:14:10 +0800 Subject: [PATCH 71/94] Update readcoverage.py --- scripts/readcoverage.py | 1 - 1 file changed, 1 deletion(-) diff --git a/scripts/readcoverage.py b/scripts/readcoverage.py index e8bc53720..b84e5478c 100644 --- a/scripts/readcoverage.py +++ b/scripts/readcoverage.py @@ -20,7 +20,6 @@ def get_coverage_from_summary(file_path): def read_coverage(moonbit_code, index, api_key): - def read_coverage(moonbit, index, api_key): read_prompt = ChatPromptTemplate.from_template( """You are a professional MoonBit code analyst. Your task is to find and return the complete function definition containing the given uncovered code line indices. From edd5bd6c9feb2cb143ab0d8fa101274caf94d109 Mon Sep 17 00:00:00 2001 From: KirbytroNic0528 <133230754+KirbytroNic0528@users.noreply.github.com> Date: Mon, 28 Oct 2024 12:15:54 +0800 Subject: [PATCH 72/94] Update readcoverage.py --- scripts/readcoverage.py | 1 - 1 file changed, 1 deletion(-) diff --git a/scripts/readcoverage.py b/scripts/readcoverage.py index b84e5478c..a64f99627 100644 --- a/scripts/readcoverage.py +++ b/scripts/readcoverage.py @@ -50,7 +50,6 @@ def read_coverage(moonbit_code, index, api_key): {"moonbit": moonbit, "index": [index]} ) return response - """ ) read_llm = ChatZhipuAI(api_key=api_key, model="glm-4-plus", temperature=0.5) From bab0ab5ce05c5daf4a3e6d88cb42b2b37aaea4da Mon Sep 17 00:00:00 2001 From: KirbytroNic0528 <133230754+KirbytroNic0528@users.noreply.github.com> Date: Mon, 28 Oct 2024 12:17:11 +0800 Subject: [PATCH 73/94] Update readcoverage.py --- scripts/readcoverage.py | 9 --------- 1 file changed, 9 deletions(-) diff --git a/scripts/readcoverage.py b/scripts/readcoverage.py index a64f99627..5bd4d4796 100644 --- a/scripts/readcoverage.py +++ b/scripts/readcoverage.py @@ -45,15 +45,6 @@ def read_coverage(moonbit_code, index, api_key): read_llm = ChatZhipuAI(api_key=api_key, model="glm-4-plus", temperature=0.5) - read_retriever_chain = read_prompt | read_llm | StrOutputParser() - response = read_retriever_chain.invoke( - {"moonbit": moonbit, "index": [index]} - ) - return response - ) - - read_llm = ChatZhipuAI(api_key=api_key, model="glm-4-plus", temperature=0.5) - read_retriever_chain = read_prompt | read_llm | StrOutputParser() response = read_retriever_chain.invoke( {"moonbit_code": moonbit_code, "index": [index]} From e0453d098bbff49a748a00f290b35d5d3748fba7 Mon Sep 17 00:00:00 2001 From: KirbytroNic0528 <133230754+KirbytroNic0528@users.noreply.github.com> Date: Mon, 28 Oct 2024 12:18:50 +0800 Subject: [PATCH 74/94] Update readcoverage.py --- scripts/readcoverage.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/readcoverage.py b/scripts/readcoverage.py index 5bd4d4796..48e924fa6 100644 --- a/scripts/readcoverage.py +++ b/scripts/readcoverage.py @@ -47,6 +47,6 @@ def read_coverage(moonbit_code, index, api_key): read_retriever_chain = read_prompt | read_llm | StrOutputParser() response = read_retriever_chain.invoke( - {"moonbit_code": moonbit_code, "index": [index]} + {"moonbit": moonbit, "index": [index]} ) return response From ac4c3628f885e57d6feafe17e0963234d473b6d7 Mon Sep 17 00:00:00 2001 From: KirbytroNic0528 <133230754+KirbytroNic0528@users.noreply.github.com> Date: Mon, 28 Oct 2024 12:20:32 +0800 Subject: [PATCH 75/94] Update readcoverage.py --- scripts/readcoverage.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/readcoverage.py b/scripts/readcoverage.py index 48e924fa6..f2d731612 100644 --- a/scripts/readcoverage.py +++ b/scripts/readcoverage.py @@ -47,6 +47,6 @@ def read_coverage(moonbit_code, index, api_key): read_retriever_chain = read_prompt | read_llm | StrOutputParser() response = read_retriever_chain.invoke( - {"moonbit": moonbit, "index": [index]} + {"moonbit": moonbit_code, "index": [index]} ) return response From 5a095ee97b30aae5f4204d1128307a722b40a3ae Mon Sep 17 00:00:00 2001 From: KirbytroNic0528 <133230754+KirbytroNic0528@users.noreply.github.com> Date: Mon, 28 Oct 2024 12:22:59 +0800 Subject: [PATCH 76/94] Update gettest.py --- scripts/gettest.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/scripts/gettest.py b/scripts/gettest.py index c781344b3..3b9258b13 100644 --- a/scripts/gettest.py +++ b/scripts/gettest.py @@ -28,7 +28,7 @@ def generate_test_code(moonbit_code, path, api_key): test_retriever_chain = test_prompt | test_llm | StrOutputParser() test_code_output = test_retriever_chain.invoke( - {"moonbit": moonbit, "filename": filename} + {"moonbit": moonbit_code, "filename": filename} ) test_code = test_code_output.replace("```moonbit\n", "").rstrip( "```" @@ -45,7 +45,7 @@ def rethink_test_code(moonbit_code, test_moonbit_code, file_path, error_message, 2. **Test Case Code**: This is the current test case code, which may contain errors leading to test failures. 3. **Test Error Message**: This is the error message generated when running the test case, which can help you pinpoint the issue. - 4. **MoonBit Code**: This is the actual MoonBit code that the test case is supposed to test. + 4. **MoonBit**: This is the actual MoonBit code that the test case is supposed to test. Please carefully read this information, analyze the cause of the error, and generate a corrected test case code. Ensure that your output code passes the test and is logically correct. @@ -54,7 +54,7 @@ def rethink_test_code(moonbit_code, test_moonbit_code, file_path, error_message, Filename: Test Case Code: Error Message: - MoonBit Code: + MoonBit: **Output Format:** Corrected Test Case Code: @@ -65,7 +65,7 @@ def rethink_test_code(moonbit_code, test_moonbit_code, file_path, error_message, please remove the assertion values in the assert statement. Now, please generate the corrected test case code based on the following input information: - MoonBit Code:{moonbit_code} + MoonBit:{moonbit} Filename: {filename} Test Case Code:{test_moonbit_code} Error Message:{error_message} @@ -79,7 +79,7 @@ def rethink_test_code(moonbit_code, test_moonbit_code, file_path, error_message, rethink_retriever_chain = rethink_prompt | rethink_llm | StrOutputParser() test_code_output = rethink_retriever_chain.invoke( - { "moonbit_code": moonbit_code, "filename": filename, "test_moonbit_code": test_moonbit_code, "error_message": error_message} + { "moonbit": moonbit_code, "filename": filename, "test_moonbit_code": test_moonbit_code, "error_message": error_message} ) test_code = test_code_output.replace("```moonbit\n", "").rstrip( "```" From e51fd0c0e5617f50503bc8d0413583a9569605cd Mon Sep 17 00:00:00 2001 From: KirbytroNic0528 <133230754+KirbytroNic0528@users.noreply.github.com> Date: Mon, 28 Oct 2024 12:37:57 +0800 Subject: [PATCH 77/94] Update testagent.py --- scripts/testagent.py | 3 --- 1 file changed, 3 deletions(-) diff --git a/scripts/testagent.py b/scripts/testagent.py index 68a71270a..2736da20e 100644 --- a/scripts/testagent.py +++ b/scripts/testagent.py @@ -21,12 +21,9 @@ def testagent(api_key): moonbit_code = codefile.read() for index in indexs: uncovered_code = read_coverage(moonbit_code, index, api_key) - print(index) - print("uncovered code is" + uncovered_code) test_code = generate_test_code( uncovered_code, source_file["name"], api_key ) - print("test_code is" + test_code) test_test_code(uncovered_code, test_code, source_file["name"], zhipuai_api_key) From fe1c8864fda1397fe099b1074c0ef53cc3d1b44f Mon Sep 17 00:00:00 2001 From: KirbytroNic0528 <133230754+KirbytroNic0528@users.noreply.github.com> Date: Mon, 28 Oct 2024 16:49:34 +0800 Subject: [PATCH 78/94] Update coverage_and_test.yml --- .github/workflows/coverage_and_test.yml | 20 ++++++++++---------- 1 file changed, 10 insertions(+), 10 deletions(-) diff --git a/.github/workflows/coverage_and_test.yml b/.github/workflows/coverage_and_test.yml index 23cf76192..2fac0fc82 100644 --- a/.github/workflows/coverage_and_test.yml +++ b/.github/workflows/coverage_and_test.yml @@ -1,9 +1,10 @@ name: coverage_and_test on: - pull_request: + pull_request_target: + types: [opened, synchronize, edited] branches: - - main + - main jobs: test: @@ -35,17 +36,16 @@ jobs: moon coverage report -f coveralls - name: coverage improvement - run: python scripts/testagent.py - + run: python scripts/testagent.py --api_key ${{ secrets.api_key }} + - name: Get code changes + id: get_code_changes run: | - git diff > changes.txt - + git diff > changes.txt test_code=$(cat changes.txt) - - echo "::set-output name=test_code::$test_code" + echo "test_code=$test_code" >> $GITHUB_ENV - - name: push comments + - name: Push comments uses: peter-evans/create-or-update-comment@v1 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} @@ -54,7 +54,7 @@ jobs: body: | Here are the test code changes: ``` - ${{ steps.get_code_changes.outputs.test_code }} + ${{ env.test_code }} ``` reaction-type: rocket From fbb94b0245a71a7e0955d5c1c131e5d65daa93a5 Mon Sep 17 00:00:00 2001 From: KirbytroNic0528 <133230754+KirbytroNic0528@users.noreply.github.com> Date: Mon, 28 Oct 2024 18:39:18 +0800 Subject: [PATCH 79/94] Update testagent.py --- scripts/testagent.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/testagent.py b/scripts/testagent.py index 2736da20e..960a960b7 100644 --- a/scripts/testagent.py +++ b/scripts/testagent.py @@ -47,7 +47,7 @@ def testagent(api_key): subprocess.run(["moon", "test", "--enable-coverage"]) subprocess.run(["moon", "coverage", "report", "-f", "coveralls"]) subprocess.run( - ["moon", "coverage", "report", "-f", "summary", "summary"], + ["moon", "coverage", "report", "-f", "summary"], stdout=open("coverage_summary.txt", "w"), ) new_coverage = get_coverage_from_summary("coverage_summary.txt") From 112339e8b71b71fbca09f49661240987f3cc9716 Mon Sep 17 00:00:00 2001 From: KirbytroNic0528 <133230754+KirbytroNic0528@users.noreply.github.com> Date: Mon, 28 Oct 2024 18:45:14 +0800 Subject: [PATCH 80/94] Update testagent.py --- scripts/testagent.py | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/scripts/testagent.py b/scripts/testagent.py index 960a960b7..d4a72b407 100644 --- a/scripts/testagent.py +++ b/scripts/testagent.py @@ -35,8 +35,7 @@ def testagent(api_key): parser.add_argument( "--api_key", type=str, - help="API_KEY", - default="4a478b99108ee30c1ae4aaa0aefe6632.X8sj7A6gaBgWh9AE" + help="API_KEY" ) args = parser.parse_args() zhipuai_api_key = args.api_key From 0761a65f9567da0cca6c31ed371a8612428338e7 Mon Sep 17 00:00:00 2001 From: KirbytroNic0528 <133230754+KirbytroNic0528@users.noreply.github.com> Date: Tue, 29 Oct 2024 01:24:30 +0800 Subject: [PATCH 81/94] Add files via upload --- scripts/main.py | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) create mode 100644 scripts/main.py diff --git a/scripts/main.py b/scripts/main.py new file mode 100644 index 000000000..0285aaebf --- /dev/null +++ b/scripts/main.py @@ -0,0 +1,38 @@ +from readcoverage import get_coverage_from_summary +from testagent import testagent +import argparse +import subprocess + + +prev_coverage = get_coverage_from_summary("coverage_summary.txt") +max_iterations = 5 +iteration = 0 +coverage_improved = True +parser = argparse.ArgumentParser(description="to load API_KEY。") +parser.add_argument( + "--api_key", + type=str, + help="API_KEY", +) +args = parser.parse_args() +zhipuai_api_key = args.api_key +new_coverage = prev_coverage +while coverage_improved and iteration < max_iterations: + iteration += 1 + testagent(zhipuai_api_key) + subprocess.run(["moon", "test", "--enable-coverage"]) + subprocess.run(["moon", "coverage", "report", "-f", "coveralls"]) + subprocess.run( + ["moon", "coverage", "report", "-f", "summary", "summary"], + stdout=open("coverage_summary.txt", "w"), + ) + new_coverage = get_coverage_from_summary("coverage_summary.txt") + + if new_coverage > prev_coverage: + prev_coverage = new_coverage + print(f"Coverage improved to {new_coverage}%") + else: + coverage_improved = False + print("Coverage did not improve. Stopping loop.") + +print(f"Final coverage: {new_coverage}%") From 808ef45be56b1c42a8144ffcbf60f73fa9ca12ff Mon Sep 17 00:00:00 2001 From: KirbytroNic0528 <133230754+KirbytroNic0528@users.noreply.github.com> Date: Tue, 29 Oct 2024 01:25:12 +0800 Subject: [PATCH 82/94] Update testagent.py --- scripts/testagent.py | 46 ++++++-------------------------------------- 1 file changed, 6 insertions(+), 40 deletions(-) diff --git a/scripts/testagent.py b/scripts/testagent.py index d4a72b407..20052371b 100644 --- a/scripts/testagent.py +++ b/scripts/testagent.py @@ -1,9 +1,7 @@ -import argparse -import json -import subprocess -from readcoverage import read_coverage, get_coverage_from_summary +from readcoverage import read_coverage from gettest import generate_test_code from writedown import test_test_code +import json def testagent(api_key): @@ -21,41 +19,9 @@ def testagent(api_key): moonbit_code = codefile.read() for index in indexs: uncovered_code = read_coverage(moonbit_code, index, api_key) + print("uncovered code is " + uncovered_code) test_code = generate_test_code( - uncovered_code, source_file["name"], api_key + uncovered_code, source_file["name"], api_key ) - test_test_code(uncovered_code, test_code, source_file["name"], zhipuai_api_key) - - -prev_coverage = get_coverage_from_summary("coverage_summary.txt") -max_iterations = 5 -iteration = 0 -coverage_improved = True -parser = argparse.ArgumentParser(description="to load API_KEY。") -parser.add_argument( - "--api_key", - type=str, - help="API_KEY" -) -args = parser.parse_args() -zhipuai_api_key = args.api_key -new_coverage = prev_coverage -while coverage_improved and iteration < max_iterations: - iteration += 1 - testagent(zhipuai_api_key) - subprocess.run(["moon", "test", "--enable-coverage"]) - subprocess.run(["moon", "coverage", "report", "-f", "coveralls"]) - subprocess.run( - ["moon", "coverage", "report", "-f", "summary"], - stdout=open("coverage_summary.txt", "w"), - ) - new_coverage = get_coverage_from_summary("coverage_summary.txt") - - if new_coverage > prev_coverage: - prev_coverage = new_coverage - print(f"Coverage improved to {new_coverage}%") - else: - coverage_improved = False - print("Coverage did not improve. Stopping loop.") - -print(f"Final coverage: {new_coverage}%") + print("test_code is " + test_code) + test_test_code(uncovered_code, test_code, source_file["name"], api_key) From 4346c597da42048cd2b2415214df86edb0f354d3 Mon Sep 17 00:00:00 2001 From: KirbytroNic0528 <133230754+KirbytroNic0528@users.noreply.github.com> Date: Tue, 29 Oct 2024 01:25:36 +0800 Subject: [PATCH 83/94] Update writedown.py --- scripts/writedown.py | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/scripts/writedown.py b/scripts/writedown.py index 639d70660..80844bd97 100644 --- a/scripts/writedown.py +++ b/scripts/writedown.py @@ -1,4 +1,4 @@ -from gettest import rethink_test_code, generate_test_code +from gettest import rethink_test_code import subprocess import os @@ -14,8 +14,8 @@ def test_test_code(moonbit_code, test_code, file_path, api_key): folder_path = os.path.dirname(file_path) package_name = os.path.basename(os.path.dirname(file_path)) testcode_path = os.path.join(folder_path, "testcode.mbt") - with open(testcode_path, "w", encoding="utf-8") as file: - file.write(test_code) + with open(testcode_path, "w", encoding="utf-8") as test_file: + test_file.write(test_code) test_result = subprocess.run( ["moon", "test", "-p", package_name, "-f", file_path], capture_output=True, @@ -25,12 +25,13 @@ def test_test_code(moonbit_code, test_code, file_path, api_key): max_attempts = 3 while test_result.returncode and attempts < max_attempts: attempts += 1 - file.truncate(0) - new_test_code = generate_test_code( - moonbit_code, file_path, api_key + test_file.truncate(0) + new_test_code = rethink_test_code( + moonbit_code, test_code, file_path, api_key ) - file.write(new_test_code) - file.flush() + test_file.write(new_test_code) + test_file.flush() + print(new_test_code) test_result = subprocess.run( ["moon", "test", "-p", package_name, "-f", file_path], capture_output=True, @@ -39,9 +40,11 @@ def test_test_code(moonbit_code, test_code, file_path, api_key): if attempts == max_attempts: print("get test_code fail") os.remove(testcode_path) + test_file.close() return os.remove(testcode_path) writedown_test_files(file_path, test_code) print("get test_code success") + test_file.close() return From ad5de510393d3068715ba6c5dd92322feea81718 Mon Sep 17 00:00:00 2001 From: KirbytroNic0528 <133230754+KirbytroNic0528@users.noreply.github.com> Date: Tue, 29 Oct 2024 01:26:02 +0800 Subject: [PATCH 84/94] Update gettest.py --- scripts/gettest.py | 53 ++++++++++++++++++++-------------------------- 1 file changed, 23 insertions(+), 30 deletions(-) diff --git a/scripts/gettest.py b/scripts/gettest.py index 3b9258b13..1c200ccf3 100644 --- a/scripts/gettest.py +++ b/scripts/gettest.py @@ -1,34 +1,31 @@ -from zhipuai import ChatZhipuAI +from zhipuai_model import ChatZhipuAI from langchain_core.output_parsers import StrOutputParser from langchain_core.prompts import ChatPromptTemplate import os -def generate_test_code(moonbit_code, path, api_key): +def generate_test_code(moonbit, path, api_key): filename = os.path.basename(path) - test_prompt = ChatPromptTemplate.from_messages([ - ("system", "As a MoonBit language engineer, your task is to write a series of test cases to verify the correctness of a project."), - ("system", "Based on the provided format and the understanding of the function's purpose from the filename {filename}, write corresponding test cases for the given MoonBit function including edge cases and any potential error scenarios:"), - ("system", "The test cases should be formatted as follows:"), - ("system", "test {{"), - ("system", " assert_eq!(f(x))"), - ("system", " assert_eq!(f(x))"), - ("system", "}}"), - ("system", "Provide test cases for the MoonBit function given as moonbit."), - ("system", "Note that your output should only contain the code for the test cases, without any analysis, explanations, or any other statements."), - ("system", "Also, ensure that you are generating test cases for the MoonBit language, and do not confuse MoonBit language with any other."), - ("system","Attention,you don't need to provide the results of the assertions. "), - ("user", "{moonbit}"), - ]) - + test_prompt = ChatPromptTemplate.from_template( + """As a MoonBit language engineer, your task is to write a series of test cases to verify the correctness of a project. + Based on the provided format and the understanding of the function's purpose from the filename {filename}, + write corresponding test cases for the given MoonBit function including edge cases and any potential error scenarios: + test {{ + assert_eq!(f(x)) + assert_eq!(f(x)) + }} + Provide test cases for the MoonBit function given as {moonbit}. + Note that your output should only contain the code for the test cases, without any analysis, explanations, or any other statements. + Also, ensure that you are generating test cases for the MoonBit language, and do not confuse MoonBit language with any other""" + ) test_llm = ChatZhipuAI( - api_key=api_key, model="glm-4-9b:772570335:v3:odbzuhb9", temperature=0.5, max_tokens=4095 + api_key=api_key, model="glm-4-9b:772570335:v3:odbzuhb9", temperature=0.5, max_tokens=2048 ) test_retriever_chain = test_prompt | test_llm | StrOutputParser() test_code_output = test_retriever_chain.invoke( - {"moonbit": moonbit_code, "filename": filename} + {"filename": filename, "moonbit": moonbit} ) test_code = test_code_output.replace("```moonbit\n", "").rstrip( "```" @@ -36,16 +33,14 @@ def generate_test_code(moonbit_code, path, api_key): return test_code -def rethink_test_code(moonbit_code, test_moonbit_code, file_path, error_message, api_key): +def rethink_test_code(moonbit_code, test_moonbit_code, file_path, api_key): filename = os.path.basename(file_path) rethink_prompt = ChatPromptTemplate.from_template( """You are a professional MoonBit language engineer. Now, you need to help me analyze and correct a test case. I will provide the following information: 1. **Test Case Filename**: This helps you understand the context of the test case. 2. **Test Case Code**: This is the current test case code, which may contain errors leading to test failures. - 3. **Test Error Message**: This is the error message generated when running the test case, - which can help you pinpoint the issue. - 4. **MoonBit**: This is the actual MoonBit code that the test case is supposed to test. + 3. **MoonBit Code**: This is the actual MoonBit code that the test case is supposed to test. Please carefully read this information, analyze the cause of the error, and generate a corrected test case code. Ensure that your output code passes the test and is logically correct. @@ -53,8 +48,7 @@ def rethink_test_code(moonbit_code, test_moonbit_code, file_path, error_message, **Input Format:** Filename: Test Case Code: - Error Message: - MoonBit: + MoonBit Code: **Output Format:** Corrected Test Case Code: @@ -65,12 +59,11 @@ def rethink_test_code(moonbit_code, test_moonbit_code, file_path, error_message, please remove the assertion values in the assert statement. Now, please generate the corrected test case code based on the following input information: - MoonBit:{moonbit} + MoonBit Code:{moonbit_code} Filename: {filename} - Test Case Code:{test_moonbit_code} - Error Message:{error_message} + Test Case Code:{test_moonbit_code} - Please note, your output should only contain the corrected test case code, without any additional analysis. + Please note, your output should only contain the corrected moonbit language test case code, without any additional analysis. """ ) rethink_llm = ChatZhipuAI( @@ -79,7 +72,7 @@ def rethink_test_code(moonbit_code, test_moonbit_code, file_path, error_message, rethink_retriever_chain = rethink_prompt | rethink_llm | StrOutputParser() test_code_output = rethink_retriever_chain.invoke( - { "moonbit": moonbit_code, "filename": filename, "test_moonbit_code": test_moonbit_code, "error_message": error_message} + {"moonbit_code": moonbit_code, "filename": filename, "test_moonbit_code": test_moonbit_code} ) test_code = test_code_output.replace("```moonbit\n", "").rstrip( "```" From c9910548b8a25c85f5a6975bbdc8f092554efe2c Mon Sep 17 00:00:00 2001 From: KirbytroNic0528 <133230754+KirbytroNic0528@users.noreply.github.com> Date: Tue, 29 Oct 2024 01:26:18 +0800 Subject: [PATCH 85/94] Update and rename zhipuai.py to zhipuai_model.py --- scripts/{zhipuai.py => zhipuai_model.py} | 0 1 file changed, 0 insertions(+), 0 deletions(-) rename scripts/{zhipuai.py => zhipuai_model.py} (100%) diff --git a/scripts/zhipuai.py b/scripts/zhipuai_model.py similarity index 100% rename from scripts/zhipuai.py rename to scripts/zhipuai_model.py From 2febd8d6b7581a62675a9079492bbc7d548789f3 Mon Sep 17 00:00:00 2001 From: KirbytroNic0528 <133230754+KirbytroNic0528@users.noreply.github.com> Date: Tue, 29 Oct 2024 01:27:03 +0800 Subject: [PATCH 86/94] Update readcoverage.py --- scripts/readcoverage.py | 49 +++++++++++++++++++++++------------------ 1 file changed, 27 insertions(+), 22 deletions(-) diff --git a/scripts/readcoverage.py b/scripts/readcoverage.py index f2d731612..8bd5f3187 100644 --- a/scripts/readcoverage.py +++ b/scripts/readcoverage.py @@ -1,16 +1,25 @@ -from zhipuai import ChatZhipuAI +from zhipuai_model import ChatZhipuAI from langchain_core.output_parsers import StrOutputParser from langchain_core.prompts import ChatPromptTemplate +def get_line_content(moonbit_code, index): + lines = moonbit_code.strip().split("\n") + + if 0 <= index < len(lines): + return lines[index] + else: + return "Index out of range" + + def get_coverage_from_summary(file_path): - with open(file_path, 'r') as file: + with open(file_path, "r") as file: lines = file.readlines() last_line = lines[-1].strip() - parts = last_line.split(':') - if len(parts) == 2 and parts[0].strip() == 'Total': - total_parts = parts[1].strip().split('/') + parts = last_line.split(":") + if len(parts) == 2 and parts[0].strip() == "Total": + total_parts = parts[1].strip().split("/") if len(total_parts) == 2: total_passed = int(total_parts[0]) total_tests = int(total_parts[1]) @@ -19,27 +28,23 @@ def get_coverage_from_summary(file_path): return 0.0 -def read_coverage(moonbit_code, index, api_key): +def read_coverage(moonbit, index, api_key): + uncovered_code = get_line_content(moonbit, index) read_prompt = ChatPromptTemplate.from_template( - """You are a professional MoonBit code analyst. Your task is to find and return the complete function definition containing the given uncovered code line indices. + """ + Given the following piece of code from a larger codebase (moonbit): + + {moonbit} + + You are provided with a specific line of code (uncovered_code): -Input: + {uncovered_code} -moonbit: The entire code in which you need to search for uncovered lines. -Uncovered code line index: An integer representing the line number of the code that is marked as uncovered. -Output requirements: + Your task is to identify the entire function that this line of code belongs to and return the complete function definition. -For the given uncovered code line index, locate and return the complete function definition that contains that line. -The output should be a string representing the entire code of a function, including its signature and body. -Do not include any analysis process, additional information, or explanatory statements; just return the required function definition. + Please ensure that you include all lines of the function from its definition to the end of the function body. -Example: -If the uncovered code line index is [2], then the output should be the complete function definition that includes line 2. - Now, please find the uncovered code based on the following input information: - moonbit:{moonbit} - Uncovered code line index:{index} -Attention, the language of the code is MoonBit. - + Attention, your output must only include the funciton, without any analyse or annotation """ ) @@ -47,6 +52,6 @@ def read_coverage(moonbit_code, index, api_key): read_retriever_chain = read_prompt | read_llm | StrOutputParser() response = read_retriever_chain.invoke( - {"moonbit": moonbit_code, "index": [index]} + {"moonbit": moonbit, "uncovered_code": uncovered_code} ) return response From 6ac2c085c24a044c2dc691d21832aaac5421596c Mon Sep 17 00:00:00 2001 From: KirbytroNic0528 Date: Tue, 29 Oct 2024 07:55:13 +0800 Subject: [PATCH 87/94] Update coverage_and_test.yml --- .github/workflows/coverage_and_test.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/coverage_and_test.yml b/.github/workflows/coverage_and_test.yml index 2fac0fc82..e49a3f8ab 100644 --- a/.github/workflows/coverage_and_test.yml +++ b/.github/workflows/coverage_and_test.yml @@ -36,7 +36,7 @@ jobs: moon coverage report -f coveralls - name: coverage improvement - run: python scripts/testagent.py --api_key ${{ secrets.api_key }} + run: python scripts/main.py --api_key ${{ secrets.api_key }} - name: Get code changes id: get_code_changes From 5267b75415e7c27484289da530d672e896410970 Mon Sep 17 00:00:00 2001 From: KirbytroNic0528 Date: Wed, 30 Oct 2024 01:07:34 +0800 Subject: [PATCH 88/94] Update main.py --- scripts/main.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/scripts/main.py b/scripts/main.py index 0285aaebf..5ce60ab85 100644 --- a/scripts/main.py +++ b/scripts/main.py @@ -23,7 +23,7 @@ subprocess.run(["moon", "test", "--enable-coverage"]) subprocess.run(["moon", "coverage", "report", "-f", "coveralls"]) subprocess.run( - ["moon", "coverage", "report", "-f", "summary", "summary"], + ["moon", "coverage", "report", "-f", "summary"], stdout=open("coverage_summary.txt", "w"), ) new_coverage = get_coverage_from_summary("coverage_summary.txt") From 1fd3b07fa828a3ca760fdc72dd9137d739ce8a82 Mon Sep 17 00:00:00 2001 From: KirbytroNic0528 Date: Wed, 30 Oct 2024 01:27:05 +0800 Subject: [PATCH 89/94] Update readme.md --- scripts/readme.md | 45 +++++++++++++++++---------------------------- 1 file changed, 17 insertions(+), 28 deletions(-) diff --git a/scripts/readme.md b/scripts/readme.md index 6df48b4c3..185e50909 100644 --- a/scripts/readme.md +++ b/scripts/readme.md @@ -4,12 +4,13 @@ This repository includes the scripts and dependencies required for the Moonbit T ## Script Description +- **Main.py**: The main workflow of our Test Agent. Compared to using a LangChain agent, directly executing LLMs within a fixed task workflow can save more time. - **Gettest.py**: Invokes the agent to generate test cases. -- **Readcoverage.py**: Reads the coverage report generated during testing and identifies uncovered code areas based on the index. -- **requirements**: Lists the dependencies needed to run the scripts. -- **TestAgent.py**: Serves as the workflow for the test agent, coordinating the execution of coverage analysis and test case generation. -- **Writedown.py**: Writes the generated test cases. +- **Readcoverage.py**: Reads the coverage report generated after testing and identifies uncovered code areas based on the index. +- **TestAgent.py**: Serves as the workflow for the generate test cases, coordinating the execution of coverage analysis and test case generation. +- **Writedown.py**: Test the test code and writes the generated test cases. - **coverage_and_test.yml**: Defines the complete workflow. +- **requirements**: Lists the dependencies needed to run the scripts. ### Installation @@ -23,47 +24,35 @@ To use MoonBit_Test_Agent, you need to have an API key for ZhiPuAI. ``` pip install -r requirements.txt ``` -3.Add API key in the Github Secret +3.Add API_KEY in the Github Secret ## Usage -The Agent depends on the workflow. - -Our workflow includes "Build", "Test", "Typo Check", and "License Header Check" - -### 1. Build Job -- **Steps**: - 1. **Checkout Repository**: Clones the repository. - 2. **Install Moonbit CLI**: Installs the Moonbit command-line interface. - 3. **Moon Version**: Displays the installed Moonbit version. - 4. **Moon Check**: Runs static analysis to check for warnings. - 5. **Moon Info**: Displays project information and checks for uncommitted changes. - 6. **Run Moon Tests**: Executes tests with and without optimizations. - 7. **Moon Bundle**: Bundles the project. - 8. **Check Core Size**: Lists core dump files. - 9. **Format Diff**: Checks for formatting issues. - 10. **Set up Python**: Installs Python 3.9. - 11. **Install Dependencies**: Installs required Python packages. +The Test Agent will work in the Github Actioon. +Our workflow includes "Test", "Typo Check", and "License Header Check". -### 2. Test Job +### 1. Test Job - **Steps**: - 1. **Checkout Repository**: Clones the repository. + 1. **Install Dependencies**: Installs required Python packages. 2. **Install Moonbit CLI**: Installs the Moonbit command-line interface. 3. **Initial Moon Test**: Runs tests with coverage enabled. 4. **Initial Coverage Report**: Generates and displays a summary of test coverage. - 5. **Loop Coverage Improvement**: Iteratively runs tests to improve coverage. - 6. **Final Coverage Report**: Generates and sends a detailed coverage report to Coveralls. + 5. **Coverage Improvement**: Iteratively runs tests to improve coverage. + 6. **Get code changes**: Captures any code changes made in the pull request and stores them for later use.. + 7. **Push Comments**: Uses a GitHub Action to create or update a comment on the pull request with the changes to the test code. -### 3. Typo Check Job +### 2. Typo Check Job - **Steps**: 1. **Download Typos**: Installs the Typos tool. 2. **Checkout Repository**: Clones the repository. 3. **Check Typos**: Scans the codebase for common typos. -### 4. License Header Check Job +### 3. License Header Check Job - **Steps**: 1. **Checkout Repository**: Clones the repository. 2. **Download HawkEye**: Installs the HawkEye tool. 3. **Check License Header**: Ensures all files have the correct license header. + 2. **Download HawkEye**: Installs the HawkEye tool. + 3. **Check License Header**: Ensures all files have the correct license header. From 44bb4ac5ed9d6d84e2741952808fec917b85b6f9 Mon Sep 17 00:00:00 2001 From: KirbytroNic0528 Date: Wed, 30 Oct 2024 01:28:09 +0800 Subject: [PATCH 90/94] Update coverage_and_test.yml --- .github/workflows/coverage_and_test.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/coverage_and_test.yml b/.github/workflows/coverage_and_test.yml index e49a3f8ab..a0a5509dc 100644 --- a/.github/workflows/coverage_and_test.yml +++ b/.github/workflows/coverage_and_test.yml @@ -15,11 +15,11 @@ jobs: with: python-version: 3.9 - - name: Install dependencies + - name: install dependencies run: | pip install -r scripts/requirements.txt - - name: install + - name: install Moonbit CLI run: | curl -fsSL https://cli.moonbitlang.com/install/unix.sh | bash echo "$HOME/.moon/bin" >> $GITHUB_PATH @@ -38,14 +38,14 @@ jobs: - name: coverage improvement run: python scripts/main.py --api_key ${{ secrets.api_key }} - - name: Get code changes + - name: get code changes id: get_code_changes run: | git diff > changes.txt test_code=$(cat changes.txt) echo "test_code=$test_code" >> $GITHUB_ENV - - name: Push comments + - name: push comments uses: peter-evans/create-or-update-comment@v1 env: GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} From 50bb8eb608f2d141e368629e4e416b34c7feb86a Mon Sep 17 00:00:00 2001 From: KirbytroNic0528 Date: Wed, 30 Oct 2024 21:08:14 +0800 Subject: [PATCH 91/94] Update coverage_and_test.yml --- .github/workflows/coverage_and_test.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/coverage_and_test.yml b/.github/workflows/coverage_and_test.yml index a0a5509dc..8096f141e 100644 --- a/.github/workflows/coverage_and_test.yml +++ b/.github/workflows/coverage_and_test.yml @@ -1,10 +1,10 @@ name: coverage_and_test -on: - pull_request_target: - types: [opened, synchronize, edited] - branches: +on: + push: + branches: - main + pull_request: jobs: test: From f1d10b3b4eb480e275af4c85d7ad78e547b576f5 Mon Sep 17 00:00:00 2001 From: KirbytroNic0528 Date: Thu, 31 Oct 2024 16:31:30 +0800 Subject: [PATCH 92/94] Update coverage_and_test.yml --- .github/workflows/coverage_and_test.yml | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/.github/workflows/coverage_and_test.yml b/.github/workflows/coverage_and_test.yml index 8096f141e..a0a5509dc 100644 --- a/.github/workflows/coverage_and_test.yml +++ b/.github/workflows/coverage_and_test.yml @@ -1,10 +1,10 @@ name: coverage_and_test -on: - push: - branches: +on: + pull_request_target: + types: [opened, synchronize, edited] + branches: - main - pull_request: jobs: test: From d359c97b2dc1b773c5121f6cc4d0144c5cfa2012 Mon Sep 17 00:00:00 2001 From: KirbytroNic0528 Date: Thu, 31 Oct 2024 16:32:32 +0800 Subject: [PATCH 93/94] Update gettest.py --- scripts/gettest.py | 73 +++++++++++++++++++++++++++++++++------------- 1 file changed, 53 insertions(+), 20 deletions(-) diff --git a/scripts/gettest.py b/scripts/gettest.py index 1c200ccf3..47f096066 100644 --- a/scripts/gettest.py +++ b/scripts/gettest.py @@ -6,21 +6,37 @@ def generate_test_code(moonbit, path, api_key): filename = os.path.basename(path) - test_prompt = ChatPromptTemplate.from_template( - """As a MoonBit language engineer, your task is to write a series of test cases to verify the correctness of a project. - Based on the provided format and the understanding of the function's purpose from the filename {filename}, - write corresponding test cases for the given MoonBit function including edge cases and any potential error scenarios: - test {{ - assert_eq!(f(x)) - assert_eq!(f(x)) - }} - Provide test cases for the MoonBit function given as {moonbit}. - Note that your output should only contain the code for the test cases, without any analysis, explanations, or any other statements. - Also, ensure that you are generating test cases for the MoonBit language, and do not confuse MoonBit language with any other""" - ) + test_prompt = ChatPromptTemplate.from_messages( + [ + ("system", """ + As a MoonBit language engineer, your task is to write a series of test cases to verify the correctness of a project. + I will provide the following information: + 1. **Filename**: This helps you understand the context of the MoonBit Code and guide you in using the correct data structures for generating test cases. + 2. **MoonBit Code**: This is the MoonBit language code that the test case is supposed to test. + + Please carefully read this information and generate correct test cases for the MoonBit Code with your knowledge of MoonBit language. + + **Input Format:** + The filename is + The MoonBit code is + + **Output Format:** + ```moonbit + test {{ + assert_eq!(moonbit_code) + }} + ``` + + Note that your output should only contain the code for the test cases, without any analysis, explanations, or any other statements. + Also, ensure that you are generating test cases for the MoonBit language, and do not confuse it with any other language. + """), + ("user", "The filename is \"{filename}\"\nThe MoonBit code is\n{moonbit}") + ] +) + test_llm = ChatZhipuAI( - api_key=api_key, model="glm-4-9b:772570335:v3:odbzuhb9", temperature=0.5, max_tokens=2048 + api_key=api_key, model="glm-4-9b:772570335:v5:iwfb27vl", temperature=0.7, max_tokens=4095 ) test_retriever_chain = test_prompt | test_llm | StrOutputParser() @@ -51,13 +67,30 @@ def rethink_test_code(moonbit_code, test_moonbit_code, file_path, api_key): MoonBit Code: **Output Format:** - Corrected Test Case Code: - - If the test case encounters issues with data structure usage, - please modify the data structures used in the test case based on the file name. + ```moonbit + test {{ + assert_eq!(moonbit_code) + }} + ``` + If there are issues with the values in the test case, - please remove the assertion values in the assert statement. - + you can remove the assertion values in the assert statement like: + + ```test_moonbit_code + test "to_string" {{ + let arr = [1, 2, 3] + let str = arr.to_string() + assert_eq!(str,"[1, 2, 3]") + }} + ``` + + ```output + test "to_string" {{ + let arr = [1, 2, 3] + let str = arr.to_string() + assert_eq!(str) + }} + ``` Now, please generate the corrected test case code based on the following input information: MoonBit Code:{moonbit_code} Filename: {filename} @@ -67,7 +100,7 @@ def rethink_test_code(moonbit_code, test_moonbit_code, file_path, api_key): """ ) rethink_llm = ChatZhipuAI( - api_key=api_key, model="glm-4-9b:772570335:v3:odbzuhb9", temperature=0.5, max_tokens=2048 + api_key=api_key, model="glm-4-9b:772570335:v5:iwfb27vl", temperature=0.7, max_tokens=4095 ) rethink_retriever_chain = rethink_prompt | rethink_llm | StrOutputParser() From 8de233b3ddd0c467fe3a0a71e9468f0ad1f3712f Mon Sep 17 00:00:00 2001 From: KirbytroNic0528 Date: Thu, 31 Oct 2024 16:32:56 +0800 Subject: [PATCH 94/94] Update readcoverage.py --- scripts/readcoverage.py | 19 ++++++++++--------- 1 file changed, 10 insertions(+), 9 deletions(-) diff --git a/scripts/readcoverage.py b/scripts/readcoverage.py index 8bd5f3187..6e9d90580 100644 --- a/scripts/readcoverage.py +++ b/scripts/readcoverage.py @@ -32,19 +32,20 @@ def read_coverage(moonbit, index, api_key): uncovered_code = get_line_content(moonbit, index) read_prompt = ChatPromptTemplate.from_template( """ - Given the following piece of code from a larger codebase (moonbit): + The following piece of code from a larger moonbit language codebase (moonbit_code):{moonbit_code} - {moonbit} + You are provided with one line of code which is uncovered in the test(uncovered_code):{uncovered_code} - You are provided with a specific line of code (uncovered_code): + Your task is to identify the entire function that this line of code belongs to and return the complete function definition. - {uncovered_code} + Please ensure that you include all lines of the function from its definition to the end of the function body. - Your task is to identify the entire function that this line of code belongs to and return the complete function definition. + Your output should follow this format: - Please ensure that you include all lines of the function from its definition to the end of the function body. - - Attention, your output must only include the funciton, without any analyse or annotation + **Output Format:** + ```moonbit + + ``` """ ) @@ -52,6 +53,6 @@ def read_coverage(moonbit, index, api_key): read_retriever_chain = read_prompt | read_llm | StrOutputParser() response = read_retriever_chain.invoke( - {"moonbit": moonbit, "uncovered_code": uncovered_code} + {"moonbit_code": moonbit, "uncovered_code": uncovered_code} ) return response