You're Invited:Meet the Socket Team at RSAC and BSidesSF 2026, March 23–26.RSVP
Socket
Book a DemoSign in
Socket

agilecoder

Package Overview
Dependencies
Maintainers
1
Versions
9
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

agilecoder - pypi Package Compare versions

Comparing version
0.1.5
to
0.1.6
+13
-5
agilecoder.egg-info/PKG-INFO
Metadata-Version: 2.1
Name: agilecoder
Version: 0.1.5
Version: 0.1.6
Summary: AgileCoder

@@ -9,6 +9,14 @@ Home-page: https://github.com/FSoft-AI4Code/AgileCoder

License: Apache-2.0
Platform: UNKNOWN
Requires-Python: >=3.8
UNKNOWN
Requires-Dist: openai==0.28.1
Requires-Dist: tiktoken
Requires-Dist: markdown
Requires-Dist: colorama
Requires-Dist: nltk
Requires-Dist: tenacity
Requires-Dist: python-dotenv
Requires-Dist: codebleu
Requires-Dist: google-auth
Requires-Dist: google-auth-oauthlib
Requires-Dist: google-auth-httplib2
Requires-Dist: anthropic

@@ -8,1 +8,6 @@ openai==0.28.1

python-dotenv
codebleu
google-auth
google-auth-oauthlib
google-auth-httplib2
anthropic

@@ -194,8 +194,8 @@ # =========== Copyright 2023 @ CAMEL-AI.org. All Rights Reserved. ===========

# raise RuntimeError("OpenAI returned unexpected struct")
output_messages = [
try:
output_messages = [
ChatMessage(role_name=self.role_name, role_type=self.role_type,
meta_dict=dict(), role = choice.message.role, content = choice.message.content)
for choice in response.choices
]
info = self.get_info(
for choice in response.choices]
info = self.get_info(
response.id,

@@ -206,2 +206,15 @@ response.usage,

)
except:
output_messages = [
ChatMessage(role_name=self.role_name, role_type=self.role_type,
meta_dict=dict(), **dict(choice["message"]))
for choice in response["choices"]
]
info = self.get_info(
response["id"],
response["usage"],
[str(choice["finish_reason"]) for choice in response["choices"]],
num_tokens,
)

@@ -231,2 +244,2 @@ # TODO strict <INFO> check, only in the beginning of the line

"""
return f"ChatAgent({self.role_name}, {self.role_type}, {self.model})"
return f"ChatAgent({self.role_name}, {self.role_type}, {self.model})"

@@ -40,17 +40,23 @@ import ast

def get_test_order(adj_list):
if not adj_list:
return []
def get_test_order(adj_list, testing_file_map):
def dfs(node, visited, stack):
visited.add(node)
for neighbor in adj_list.get(node, []):
if neighbor not in visited:
dfs(neighbor, visited, stack)
stack.append(node)
visited = set()
test_order = []
stack = []
# Find leaf nodes (test suites)
leaf_nodes = [node for node in adj_list if node.startswith("test")]
# Call the DFS function for each node
for node in adj_list:
if node not in visited:
dfs(node, visited, stack)
# Perform DFS starting from each leaf node
for leaf_node in leaf_nodes:
if leaf_node not in visited:
dfs(adj_list, leaf_node, visited, test_order)
print(test_order)
return test_order
stack = list(filter(lambda x: not (x.startswith('test') or x.split('.')[0].endswith('test')), stack))
order = []
for filename in stack:
if filename in testing_file_map:
order.extend(list(set(testing_file_map[filename])))
# print('TEST ORDER:', order)
return order

@@ -24,2 +24,91 @@ # =========== Copyright 2023 @ CAMEL-AI.org. All Rights Reserved. ===========

from typing import Any, List, Optional, Dict
import google.auth.exceptions
import google.auth.transport.requests
from google.oauth2.service_account import Credentials
from logging import getLogger
logger = getLogger()
import json
from anthropic.lib.vertex import AnthropicVertex
import google.auth.transport
import anthropic
CLAUDE_3_HAIKU = "claude-3-haiku@20240307"
CLAUDE_3_SONNET = "claude-3-sonnet@20240229"
CLAUDE_3_OPUS = "claude-3-opus@20240229"
GCLOUD_LOCATION = "us-central1"
GCLOUD_PROJECT_ID = "ai4code-dev"
def convert_claude_to_openai(claude_output):
openai_output = {
"choices": [
{
"content_filter_results": {
"hate": {
"filtered": False,
"severity": "safe"
},
"self_harm": {
"filtered": False,
"severity": "safe"
},
"sexual": {
"filtered": False,
"severity": "safe"
},
"violence": {
"filtered": False,
"severity": "safe"
}
},
"finish_reason": "stop",
"index": 0,
"message": {
"content": str(claude_output.content[0].text),
"role": "user"
}
}
],
"created": 1716105669,
"id": "chatcmpl-9QVldRhe4q0z7qIz3uZ6oFq7E5lvw",
"model": claude_output.model,
"object": "chat.completion",
"prompt_filter_results": [
{
"prompt_index": 0,
"content_filter_results": {
"hate": {
"filtered": False,
"severity": "safe"
},
"self_harm": {
"filtered": False,
"severity": "safe"
},
"sexual": {
"filtered": False,
"severity": "safe"
},
"violence": {
"filtered": False,
"severity": "safe"
}
}
}
],
"system_fingerprint": None,
"usage": {
"completion_tokens": claude_output.usage.input_tokens,
"prompt_tokens": claude_output.usage.output_tokens,
"total_tokens": claude_output.usage.input_tokens + claude_output.usage.output_tokens
}
}
return openai_output
class ModelBackend(ABC):

@@ -42,3 +131,2 @@ r"""Base class for different model backends.

class OpenAIModel(ModelBackend):

@@ -52,3 +140,3 @@ r"""OpenAI API in a unified ModelBackend interface."""

if self.model_type == ModelType.GPT_3_5_AZURE:
if self.model_type == ModelType.GPT_3_5_AZURE or self.model_type==ModelType.GPT_4_32k:
RESOURCE_ENDPOINT = os.environ['RESOURCE_ENDPOINT']

@@ -58,2 +146,3 @@ API_TYPE = os.environ['API_TYPE']

API_KEY = os.environ['API_KEY']
print('RESOURCE_ENDPOINT', RESOURCE_ENDPOINT)
openai.api_key = API_KEY

@@ -63,3 +152,3 @@ openai.api_type = API_TYPE

openai.api_version = API_VERSION

@@ -80,3 +169,3 @@ def run(self, *args, **kwargs) -> Dict[str, Any]:

"gpt-4-0613": 8192,
"gpt-4-32k": 32768,
"gpt-4-32k": 4096,
}

@@ -86,4 +175,5 @@ num_max_token = num_max_token_map[self.model_type.value]

self.model_config_dict['max_tokens'] = num_max_completion_tokens
if self.model_type == ModelType.GPT_3_5_AZURE:
if self.model_type == ModelType.GPT_3_5_AZURE or self.model_type==ModelType.GPT_4_32k:
kwargs['engine'] = os.environ['API_ENGINE']
print('API_ENGINE', os.environ['API_ENGINE'])
else:

@@ -104,2 +194,197 @@ kwargs['model'] = self.model_type.value

class AI4CodeAnthropicVertex(AnthropicVertex):
def __init__(self, **kwargs):
self.model_name = kwargs.get("model_name", self.model_name)
super(AI4CodeAnthropicVertex, self).__init__(
region=GCLOUD_LOCATION, project_id=GCLOUD_PROJECT_ID, **kwargs
)
def _ensure_access_token(self) -> str:
request = google.auth.transport.requests.Request()
vertex_credentials = Credentials.from_service_account_info(
json.loads(open(os.path.join(os.getcwd(), "key.json"), "r").read()),
scopes=[
"https://www.googleapis.com/auth/cloud-platform",
"https://www.googleapis.com/auth/compute",
],
)
try:
vertex_credentials.refresh(request=request)
except google.auth.exceptions.RefreshError:
logger.error("Error retrieving accesstoken from service account")
self.access_token = vertex_credentials.token
if self.access_token:
logger.info("Successfullt retrieve access token from service account")
return self.access_token
return super()._ensure_access_token()
def generate(self, messages: List[Dict], **kwargs):
return self.messages.create(
max_tokens=kwargs.get("max_tokens", 1024),
stop_sequences=kwargs.get("stop_sequences", None),
temperature=kwargs.get("temperature", 0.2),
top_k=kwargs.get("top_k", 0),
model=self.model_name,
messages=messages,
)
class AI4CodeHaiku(AI4CodeAnthropicVertex):
def __init__(self, **kwargs):
self.model_name = CLAUDE_3_HAIKU
print('MODEL:', 'CLAUDE HAIKU')
super().__init__(**kwargs)
class AI4CodeSonnet(AI4CodeAnthropicVertex):
def __init__(self, **kwargs):
self.model_name = CLAUDE_3_SONNET
super().__init__(**kwargs)
class ClaudeAIModel(ModelBackend):
r"""Claude API in a unified ModelBackend interface."""
def __init__(self, model_type: ModelType, model_config_dict: Dict) -> None:
super().__init__()
self.model_type = model_type
self.model_config_dict = model_config_dict
def run(self, *args, **kwargs) -> Dict[str, Any]:
string = "\n".join([message["content"] for message in kwargs["messages"]])
# encoding = tiktoken.encoding_for_model(self.model_type.value)
try:
encoding = tiktoken.encoding_for_model(self.model_type.value)
except KeyError:
encoding = tiktoken.get_encoding("cl100k_base")
num_prompt_tokens = len(encoding.encode(string))
gap_between_send_receive = 15 * len(kwargs["messages"])
num_prompt_tokens += gap_between_send_receive
num_max_token_map = {
"claude-3-haiku-20240307": 4096,
"claude-3-opus-20240307": 4096,
"claude-3-sonneet-20240307": 4096,
'claude':4096
}
kwargs['model'] = 'claude-3-opus-20240229'
num_max_token = num_max_token_map[self.model_type.value]
num_max_completion_tokens = num_max_token - num_prompt_tokens
self.model_config_dict['max_tokens'] = num_max_token_map[self.model_type.value]
# self.model_config_dict
# if self.model_type == ModelType.GPT_3_5_CODE_VISTA:
# kwargs['engine'] = os.environ['API_ENGINE']
# else:
# raise NotImplementedError
# kwargs['model'] = self.model_type.value
# breakpoint()
# print('0'*100)
new_kwargs = {}
new_kwargs['system'] = kwargs['messages'][0]['content']
kwargs['messages'][1]['role'] = 'user'
messages = kwargs['messages'][1:2]
new_kwargs['model'] ='claude-3-haiku-20240307'
valid_kwargs = ['system', 'messages', 'model','max_tokens']
filtered_kwargs = {key: value for key, value in self.model_config_dict.items() if key in valid_kwargs}
kwargs['max_tokens'] = filtered_kwargs['max_tokens']
kwargs = new_kwargs
llm = AI4CodeHaiku()
# try:
claude_output = llm.generate(*args, messages=messages,**kwargs)
# except:
# breakpoint()
response = convert_claude_to_openai(claude_output)
log_and_print_online(
"**[CLAUDE_Usage_Info Receive]**\nprompt_tokens: {}\ncompletion_tokens: {}\ntotal_tokens: {}\n".format(
response["usage"]["prompt_tokens"], response["usage"]["completion_tokens"],
response["usage"]["total_tokens"]))
# if not isinstance(response, Dict):
# raise RuntimeError("Unexpected return from OpenAI API")
return response
class AuthropicClaudeAIModel(ModelBackend):
r"""Claude API in a unified ModelBackend interface."""
def __init__(self, model_type: ModelType, model_config_dict: Dict) -> None:
super().__init__()
self.model_type = model_type
self.model_config_dict = model_config_dict
self.client = anthropic.Anthropic(
api_key = os.environ["ANTHROPIC_API_KEY"],
)
def run(self, *args, **kwargs) -> Dict[str, Any]:
string = "\n".join([message["content"] for message in kwargs["messages"]])
# encoding = tiktoken.encoding_for_model(self.model_type.value)
try:
encoding = tiktoken.encoding_for_model(self.model_type.value)
except KeyError:
encoding = tiktoken.get_encoding("cl100k_base")
num_prompt_tokens = len(encoding.encode(string))
gap_between_send_receive = 15 * len(kwargs["messages"])
num_prompt_tokens += gap_between_send_receive
num_max_token_map = {
"claude-3-haiku-20240307": 4096,
"claude-3-opus-20240307": 4096,
"claude-3-sonneet-20240307": 4096,
'claude':4096,
'Authropic_Claude': 4096
}
# kwargs['model'] = 'claude-3-opus-20240229'
# num_max_token = num_max_token_map[self.model_type.value]
# num_max_completion_tokens = num_max_token - num_prompt_tokens
self.model_config_dict['max_tokens'] = num_max_token_map[self.model_type.value]
# self.model_config_dict
# if self.model_type == ModelType.GPT_3_5_CODE_VISTA:
# kwargs['engine'] = os.environ['API_ENGINE']
# else:
# raise NotImplementedError
# kwargs['model'] = self.model_type.value
# breakpoint()
# print('0'*100)
new_kwargs = {}
new_kwargs['system'] = kwargs['messages'][0]['content']
kwargs['messages'][1]['role'] = 'user'
messages = kwargs['messages'][1:2]
new_kwargs['model'] ='claude-3-haiku-20240307'
valid_kwargs = ['system', 'messages', 'model','max_tokens']
filtered_kwargs = {key: value for key, value in self.model_config_dict.items() if key in valid_kwargs}
kwargs['max_tokens'] = filtered_kwargs['max_tokens']
kwargs = new_kwargs
# llm = AI4CodeHaiku()
# # try:
# claude_output = llm.generate(*args, messages=messages,**kwargs)
# except:
# breakpoint()
kwargs.update({
'max_tokens': 1024,
'stop_sequences': None,
'temperature': 0.2,
'top_k': 0
})
claude_output = self.client.messages.create(
messages=messages,
**kwargs
)
response = convert_claude_to_openai(claude_output)
log_and_print_online(
"**[CLAUDE_Usage_Info Receive]**\nprompt_tokens: {}\ncompletion_tokens: {}\ntotal_tokens: {}\n".format(
response["usage"]["prompt_tokens"], response["usage"]["completion_tokens"],
response["usage"]["total_tokens"]))
# if not isinstance(response, Dict):
# raise RuntimeError("Unexpected return from OpenAI API")
return response
class StubModel(ModelBackend):

@@ -134,8 +419,11 @@ r"""A dummy model used for unit tests."""

default_model_type = ModelType.GPT_3_5_TURBO
if model_type in {
ModelType.GPT_3_5_TURBO, ModelType.GPT_4, ModelType.GPT_4_32k, ModelType.GPT_3_5_AZURE,
ModelType.GPT_3_5_TURBO, ModelType.GPT_4, ModelType.GPT_4_32k, ModelType.GPT_3_5_AZURE,
None
}:
model_class = OpenAIModel
elif model_type in {ModelType.CLAUDE }:
model_class = ClaudeAIModel
elif model_type in {ModelType.ANTHROPIC_CLAUDE}:
model_class = AuthropicClaudeAIModel
elif model_type == ModelType.STUB:

@@ -149,4 +437,6 @@ model_class = StubModel

# log_and_print_online("Model Type: {}".format(model_type))
inst = model_class(model_type, model_config_dict)
return inst
return inst

@@ -52,2 +52,4 @@ # =========== Copyright 2023 @ CAMEL-AI.org. All Rights Reserved. ===========

GPT_3_5_AZURE = "gpt-3.5-turbo"
CLAUDE = 'claude'
ANTHROPIC_CLAUDE = 'Authropic_Claude'

@@ -54,0 +56,0 @@ @property

@@ -87,3 +87,3 @@ # =========== Copyright 2023 @ CAMEL-AI.org. All Rights Reserved. ===========

ModelType.GPT_3_5_TURBO, ModelType.GPT_4, ModelType.GPT_4_32k,
ModelType.STUB, ModelType.GPT_3_5_AZURE
ModelType.STUB, ModelType.GPT_3_5_AZURE, ModelType.CLAUDE, ModelType.ANTHROPIC_CLAUDE
}:

@@ -119,2 +119,4 @@ return count_tokens_openai_chat_models(messages, encoding)

return 32768
elif model in [ModelType.CLAUDE, ModelType.ANTHROPIC_CLAUDE]:
return 20000
elif model == ModelType.STUB:

@@ -150,2 +152,4 @@ return 4096

return func(self, *args, **kwargs)
elif 'CLAUDE' in os.environ:
return func(self, *args, **kwargs)
else:

@@ -152,0 +156,0 @@ raise ValueError('OpenAI API key not found.')

@@ -14,6 +14,7 @@ import argparse

help="Name of software, your software will be generated in WareHouse/name_org_timestamp")
parser.add_argument('--max-num-sprints', type=int, default=10)
parser.add_argument('--model', type=str, default="GPT_3_5_AZURE",
help="GPT Model, choose from {'GPT_3_5_TURBO','GPT_4','GPT_4_32K', 'GPT_3_5_AZURE'}")
help="GPT Model, choose from {'GPT_3_5_TURBO','GPT_4','GPT_4_32K', 'GPT_3_5_AZURE', 'CLAUDE', 'ANTHROPIC_CLAUDE'}")
args = parser.parse_args()
print('------------------------------')
run_task(args)

@@ -92,3 +92,3 @@ {

"phaseType": "ComposedPhase",
"cycleNum": 2,
"cycleNum": 1,
"Composition": [

@@ -196,9 +196,16 @@ {

"phaseType": "ComposedPhase",
"cycleNum": 3,
"cycleNum": 2,
"Composition": [
{
"phase": "WritingTestSuite",
"phaseType": "SimplePhase",
"max_turn_step": 1,
"need_reflect": "False"
"phase": "WritingFullTestSuite",
"phaseType": "ComposedPhase",
"cycleNum": -1,
"Composition": [
{
"phase": "WritingTestSuite",
"phaseType": "SimplePhase",
"max_turn_step": 1,
"need_reflect": "False"
}
]
},

@@ -246,3 +253,3 @@ {

{
"phase": "TestErrorSummary",
"phase": "SprintTestErrorSummary",
"phaseType": "SimplePhase",

@@ -257,2 +264,8 @@ "max_turn_step": 1,

"need_reflect": "False"
},
{
"phase": "CheckProgressStatus",
"phaseType": "SimplePhase",
"max_turn_step": 1,
"need_reflect": "False"
}

@@ -278,3 +291,3 @@ ]

{
"phase": "SprintBacklogReview",
"phase": "NextSprintBacklogReview",
"phaseType": "SimplePhase",

@@ -285,3 +298,3 @@ "max_turn_step": 1,

{
"phase": "SprintBacklogModification",
"phase": "NextSprintBacklogModification",
"phaseType": "SimplePhase",

@@ -315,3 +328,3 @@ "max_turn_step": 1,

"phaseType": "ComposedPhase",
"cycleNum": 2,
"cycleNum": 1,
"Composition": [

@@ -419,9 +432,16 @@ {

"phaseType": "ComposedPhase",
"cycleNum": 5,
"cycleNum": 3,
"Composition": [
{
"phase": "WritingTestSuite",
"phaseType": "SimplePhase",
"max_turn_step": 1,
"need_reflect": "False"
"phase": "WritingFullTestSuite",
"phaseType": "ComposedPhase",
"cycleNum": -1,
"Composition": [
{
"phase": "WritingTestSuite",
"phaseType": "SimplePhase",
"max_turn_step": 1,
"need_reflect": "False"
}
]
},

@@ -469,3 +489,3 @@ {

{
"phase": "TestErrorSummary",
"phase": "SprintTestErrorSummary",
"phaseType": "SimplePhase",

@@ -480,17 +500,10 @@ "max_turn_step": 1,

"need_reflect": "False"
},
{
"phase": "CheckProgressStatus",
"phaseType": "SimplePhase",
"max_turn_step": 1,
"need_reflect": "False"
}
]
},
{
"phase": "EnvironmentDoc",
"phaseType": "SimplePhase",
"max_turn_step": 1,
"need_reflect": "True"
},
{
"phase": "Manual",
"phaseType": "SimplePhase",
"max_turn_step": 1,
"need_reflect": "False"
}

@@ -497,0 +510,0 @@ ],

@@ -29,3 +29,3 @@ {

"As the {assistant_role}, to satisfy the new user's demand and make the software realizable, you should propose suitable programming languages. If python can complete this task via Python, please answer Python; otherwise, answer another programming languages (e.g., Java, C++, etc,). If users wants to create a website, please consider HTML and CSS to complete the tasks.",
"Note that we must ONLY discuss the target programming languages and do not discuss anything else! Once we all have expressed our opinion(s) and agree with the results of the discussion unanimously, any of us must actively terminate the discussion and conclude the best programming language we have discussed without any other words or reasons, return only one line using the format: \"<INFO> LANGUAGES\" where LANGUAGES represents programming languages."
"Note that we must ONLY discuss the target programming languages and do not discuss anything else! Once we all have expressed our opinion(s) and agree with the results of the discussion unanimously, any of us must actively terminate the discussion and conclude the best programming languages we have discussed without any other words or reasons, importantly return only one line with the format: \"<INFO> LANGUAGES\" where LANGUAGES represents programming languages. Your answer strictly follows the required format."
]

@@ -45,5 +45,5 @@ },

"Your answer must follow the following format:",
"Product Backlog:",
"Product backlog:",
"PRODUCT_BACKLOG",
"Acceptance Criteria:",
"Acceptance criteria:",
"ACCEPTANCE_CRITERIA",

@@ -64,3 +64,3 @@ "where PRODUCT_BACKLOG is the product backlog for the user's task and ACCEPTANCE_CRITERIA is the corresponding acceptance criteria of the product backlog.",

"Product backlog:\n\"{plain_product_backlog}\"",
"Acceptance Criteria:\n\"{plain_acceptance_criteria}\"",
"Acceptance criteria:\n\"{plain_acceptance_criteria}\"",
"As the development team, you should review and provide useful feedback about tasks to make the software run flawlessly by obeying the regulations below:",

@@ -82,10 +82,10 @@ "1) considering the proficiency of the members, all the tasks are feasible and finished by at least one member",

"Product backlog:\n\"{plain_product_backlog}\"",
"Acceptance Criteria:\n\"{plain_acceptance_criteria}\"",
"Comments on Product backlog and Acceptance Criteria:",
"Acceptance criteria:\n\"{plain_acceptance_criteria}\"",
"Comments on Product backlog and Acceptance criteria:",
"\"{product_backlog_comments}\"",
"We have decided to complete the task through a executable software with multiple files implemented via {language}.",
"As the {assistant_role}, to satisfy the user's demand and make the software executive and robust, you should modify the product backlog and acceptance criteria according to the comments. Then, output the full and complete product backlog and acceptance criteria with all based on the comments. Your answer must follow the following format and you are not allowed to change the required format:",
"Product Backlog:",
"Product backlog:",
"PRODUCT_BACKLOG",
"Acceptance Criteria:",
"Acceptance criteria:",
"ACCEPTANCE_CRITERIA",

@@ -104,14 +104,41 @@ "where PRODUCT_BACKLOG is the revised product backlog and ACCEPTANCE_CRITERIA is the corresponding acceptance criteria of the product backlog."

"Product backlog:\n\"{plain_product_backlog}\"",
"We have decided to incorporate Agile Scrum with multiple sprints to complete the task through a executable software with multiple files implemented via {language}. As the {user_role}, to satisfy the user's demands, I suggest the following sprint goals and sprint backlog:",
"Sprint goals:\n\"{current_sprint_goals}\"",
"Acceptance criteria:\n\"{plain_acceptance_criteria}\"",
"We have decided to incorporate Agile Scrum with multiple sprints to complete the task through a executable software with multiple files implemented via {language}. As the {user_role}, to satisfy the user's demands, I suggest the first sprint backlog and acceptance criteria as below:",
"Sprint backlog:\n\"{current_programming_task}\"",
"Sprint acceptance criteria:\n\"{current_acceptance_criteria}\"",
"As the {assistant_role}, you should review and provide useful feedback about sprint goals, sprint backlog and sprint acceptance criteria to make the software run flawlessly by obeying the regulations below",
"1) considering the proficiency of the members, all the tasks are feasible and finished by at least one member,",
"2) the sprint backlog must not incorporate enhanced features like AI and sound effects unless explicitly specified in the user's task,",
"3) all the items in sprint backlog are from the product backlog.",
"4) the acceptance criteria should be detailed, clear and testable for Tester to write test cases.",
"Now, you should check the above regulations one by one and review the sprint goals, sprint backlog and sprint acceptance criteria in detail, propose one comment with the highest priority about them, and give me instructions on how to fix to ensure the sprint backlog aligns well with the regulations above. Tell me your comment with the highest priority and corresponding suggestions on revision. If the sprint goals and sprint backlog are perfect and you have no comment on them, return only one line like \"<INFO> Finished\"."
"As the {assistant_role}, you should review and provide useful feedback about the sprint backlog and sprint acceptance criteria to make the sprint easier to accomplish successfully by obeying the regulations below:",
"\t1) considering the proficiency of the members, all the tasks are feasible and finished by at least one member,",
"\t2) the sprint backlog must not incorporate enhanced features like AI and sound effects unless explicitly specified in the user's task,",
"\t3) it is prohibited to propose tasks that do not appear in the product backlog and any such tasks should be removed,",
"\t4) the acceptance criteria should be detailed, clear and testable for Tester to write test cases,",
"\t5) importantly, the product backlog should be divided into at least 2 sprints.",
"Now, you should check the above regulations one by one and review the sprint backlog and sprint acceptance criteria in detail, propose one comment with the highest priority about them, and give me instructions on how to fix to ensure the sprint backlog aligns well with the regulations above. Tell me your comment with the highest priority and corresponding suggestions on revision. If the sprint backlog is perfect and you have no comment on them, return only one line like \"<INFO> Finished\"."
]
},
"NextSprintBacklogReview": {
"assistant_role_name": "Development Team",
"user_role_name": "Product Owner",
"phase_prompt": [
"According to the new user's task, our software designs and current progress are listed below: ",
"Task: \"{task}\".",
"Modality: \"{modality}\".",
"Programming Language: \"{language}\"",
"Product backlog:\n\"{plain_product_backlog}\"",
"Acceptance criteria:\n\"{plain_acceptance_criteria}\"",
"Done tasks: ",
"{all_done_tasks}",
"Undone tasks:",
"{all_undone_tasks}",
"We have decided to incorporate Agile Scrum with multiple sprints to complete the task through a executable software with multiple files implemented via {language}. As the {user_role}, to satisfy the user's demands, I suggest the following the next sprint:",
"Sprint backlog:\n\"{current_programming_task}\"",
"Sprint acceptance criteria:\n\"{current_acceptance_criteria}\"",
"As the {assistant_role}, you should review and provide useful feedback about the sprint backlog and sprint acceptance criteria by obeying the regulations below",
"\t1) considering the proficiency of the members, all the tasks are feasible and finished by at least one member,",
"\t2) the sprint backlog must not incorporate enhanced features like AI and sound effects unless explicitly specified in the user's task,",
"\t3) all tasks in the sprint backlog must come from the product backlog, meaning that it is prohibited to propose tasks that do not appear in the product backlog and any such tasks should be removed,",
"\t4) the acceptance criteria should be detailed, clear and testable for Tester to write test cases,",
"\t5) Importantly, when done tasks match the entire product backlog and the product backlog is fully accomplished, we should conclude the project and we should not create any additional sprints.",
"Now, you should check the above regulations one by one and review the sprint backlog and sprint acceptance criteria in detail, propose one comment with the highest priority about them, and give me instructions on how to fix to ensure the sprint backlog aligns well with the regulations above. Tell me your comment with the highest priority and corresponding suggestions on revision. If the sprint backlog is perfect and you have no comment on them, return only one line like \"<INFO> Finished\"."
]
},
"SprintBacklogModification": {

@@ -121,3 +148,3 @@ "assistant_role_name": "Product Owner",

"phase_prompt": [
"According to the new user's task, our software designs, product backlog, sprint goals, sprint backlog and comments listed below: ",
"According to the new user's task, our software designs, product backlog, sprint backlog, sprint acceptance criteria and comments listed below: ",
"Task: \"{task}\".",

@@ -127,18 +154,17 @@ "Modality: \"{modality}\".",

"Product backlog:\n\"{plain_product_backlog}\"",
"Sprint goals:\n\"{current_sprint_goals}\"",
"Acceptance criteria:\n\"{plain_acceptance_criteria}\"",
"Sprint backlog:\n\"{current_programming_task}\"",
"Sprint acceptance criteria:\n\"{current_acceptance_criteria}\"",
"Comments on sprint goals, sprint backlog and sprint acceptance criteria:",
"Comments on sprint backlog and sprint acceptance criteria:",
"\"{sprint_backlog_comments}\"",
"We have decided to complete the task through a executable software with multiple files implemented via {language}.",
"As the {assistant_role}, to satisfy the user's demand and make the software executive and robust, and ensure that the sprint goals and sprint backlog are feasible and can be accomplished, you should modify corresponding sprint backlog according to the comments. Then, output the full and complete sprint backlog with all based on the comments. Return the output strictly following the required format and you are not allowed to change the required format:",
"Sprint Goals:",
"SPRINT_GOALS",
"Sprint Backlog:",
"As the {assistant_role}, to ensure that the first sprint backlog and sprint acceptance criteria are feasible and can be accomplished, you should modify corresponding sprint backlog according to the comments. It is important that the product backlog should be divided into at least 2 sprints and now the first sprint. Next, output the full and complete backlog and acceptance criteria of the first sprint with all based on the comments. Return the output strictly following the required format and you are not allowed to change the required format:",
"Sprint backlog:",
"SPRINT_BACKLOG",
"Sprint Acceptance Criteria:",
"Sprint acceptance criteria:",
"SPRINT_ACCEPTANCE_CRITERIA",
"where SPRINT_GOALS are the goals of the sprint, SPRINT_BACKLOG is the sprint backlog, and SPRINT_ACCEPTANCE_CRITERIA is the sprint acceptance criteria for the sprint backlog.",
"Note that SPRINT_GOALS, SPRINT_BACKLOG, and SPRINT_ACCEPTANCE_CRITERIA are pseudo tokens, and your answer is prohibited from including these tokens.",
"Importantly, note that the product backlog is divided into multiple sprints and each sprint should contain enough workload."
"where SPRINT_BACKLOG is the sprint backlog, and SPRINT_ACCEPTANCE_CRITERIA is the sprint acceptance criteria for the sprint backlog.",
"Note that SPRINT_BACKLOG, and SPRINT_ACCEPTANCE_CRITERIA are pseudo tokens, and your answer is prohibited from including these tokens.",
"Importantly, note that the product backlog is divided into multiple sprints and each sprint should contain enough workload.",
"Also, items in the sprint backlog are from the product backlog and do not introduce new tasks that do not appear in the product backlog."
]

@@ -159,11 +185,9 @@ },

"Your answer strictly obeys the following format and you are not allowed to change the required format:",
"Sprint Goals:",
"SPRINT_GOALS",
"Sprint Backlog:",
"Sprint backlog:",
"SPRINT_BACKLOG",
"Sprint Acceptance Criteria:",
"Sprint acceptance criteria:",
"SPRINT_ACCEPTANCE_CRITERIA",
"where SPRINT_GOALS are the goals of the sprint, SPRINT_BACKLOG is the sprint backlog whose items are from the product backlog, and SPRINT_ACCEPTANCE_CRITERIA is the sprint acceptance criteria for the sprint backlog, which can be tested autonomously by test suites.",
"Please note that SPRINT_GOALS, SPRINT_BACKLOG, and SPRINT_ACCEPTANCE_CRITERIA are pseudo tokens, and your answer is prohibited from including these tokens.",
"You must ensure that SPRINT_GOALS, SPRINT_BACKLOG and SPRINT_ACCEPTANCE_CRITERIA must not be empty and SPRINT_BACKLOG aligns with SPRINT_GOALS and SPRINT_ACCEPTANCE_CRITERIA.",
"where SPRINT_BACKLOG is the sprint backlog whose items are from the product backlog, and SPRINT_ACCEPTANCE_CRITERIA is the sprint acceptance criteria for the sprint backlog, which can be tested autonomously by test suites.",
"Please note that SPRINT_BACKLOG, and SPRINT_ACCEPTANCE_CRITERIA are pseudo tokens, and your answer is prohibited from including these tokens.",
"You must ensure that SPRINT_BACKLOG and SPRINT_ACCEPTANCE_CRITERIA must not be empty and SPRINT_BACKLOG aligns with SPRINT_ACCEPTANCE_CRITERIA.",
"As the Product Owner, you must create the first sprint and adhere to the following regulations:",

@@ -174,3 +198,4 @@ "\t1) considering the proficiency of the members, all the tasks are feasible and finished by at least one member,",

"\t4) the first sprint backlog sets the stage for next sprints.",
"\t5) the sprint acceptance criteria should be clear, detailed and testable for Tester to write test cases."
"\t5) the sprint acceptance criteria should be clear, detailed and testable for Tester to write test cases.",
"Note that you should break down the product backlog into at least 2 sprints and each sprint should contain enough workload."
]

@@ -188,21 +213,18 @@ },

"Acceptance Criteria:\n\"{plain_acceptance_criteria}\"",
"We have decided to complete the task through a executable software with multiple files implemented via {language}. We are using Agile Scrum for software development. We finished some sprints with done tasks and undone tasks as below:",
"Done tasks: ",
"{all_done_tasks}",
"We have decided to complete the task through a executable software with multiple files implemented via {language} by accomplishing the product backlog and acceptance criteria through multiple sprints. Until now, we finished done tasks and undone tasks as below:",
"Done tasks:",
"\"{all_done_tasks}\"",
"Undone tasks:",
"{all_undone_tasks}",
"As the {assistant_role}, to satisfy the user's demands, you must create the a next sprint backlog and the goals of this sprint from the product backlog, done tasks and undone tasks.",
"You should meticulously consider undone tasks when creating the next sprint.",
"\"{all_undone_tasks}\"",
"As the {assistant_role}, to satisfy the user's demands, you should carefully create a next sprint backlog and sprint acceptance criteria based on the product backlog, acceptance criteria, done works and undone works.",
"When creating the next sprint, you should meticulously review incomplete tasks in the product backlog, done tasks, undone tasks and existing bugs. You are not allowed to write new tasks that do not appear in the product backlog.",
"Think step by step and reason yourself to the right decisions to make sure we get it right.",
"Importantly, when done tasks are exactly the product backlog, just return a single line with the content: \"<INFO> DONE.\" and do nothing.",
"You must create a next sprint backlog and strictly obeys the following format:",
"Sprint Goals:",
"SPRINT_GOALS",
"Sprint Backlog:",
"You must create a next sprint backlog and strictly obey the following format:",
"Sprint backlog:",
"SPRINT_BACKLOG",
"Sprint Acceptance Criteria:",
"Sprint acceptance criteria:",
"SPRINT_ACCEPTANCE_CRITERIA",
"where SPRINT_GOALS are the goals of the sprint, SPRINT_BACKLOG is the sprint backlog whose items are from the product backlog, and SPRINT_ACCEPTANCE_CRITERIA is the sprint acceptance criteria for the sprint backlog, which can be tested autonomously by test suites. It should be noted that you must not devise new tasks or non-practical features.",
"Please note that SPRINT_GOALS, SPRINT_BACKLOG, and SPRINT_ACCEPTANCE_CRITERIA are pseudo tokens, and your answer is prohibited from including these tokens.",
"You must ensure that SPRINT_GOALS, SPRINT_BACKLOG and SPRINT_ACCEPTANCE_CRITERIA must not be empty and SPRINT_BACKLOG aligns with SPRINT_GOALS and SPRINT_ACCEPTANCE_CRITERIA.",
"where SPRINT_BACKLOG is the sprint backlog whose items are from the product backlog, and SPRINT_ACCEPTANCE_CRITERIA is the sprint acceptance criteria for the sprint backlog, which can be tested autonomously by test suites. It should be noted that you must not devise new tasks or non-practical features.",
"Please note that SPRINT_BACKLOG, and SPRINT_ACCEPTANCE_CRITERIA are pseudo tokens, and your answer is prohibited from including these tokens.",
"You must ensure that SPRINT_BACKLOG and SPRINT_ACCEPTANCE_CRITERIA must not be empty and SPRINT_BACKLOG aligns with SPRINT_ACCEPTANCE_CRITERIA.",
"As the Product Owner, you must adhere to the following regulations:",

@@ -213,5 +235,62 @@ "1) considering the proficiency of the members, all the tasks are feasible and finished by at least one member,",

"4) the sprint acceptance criteria should be clear, detailed and testable for Tester to write test cases.",
"Note that the product backlog is divided into multiple sprints and each sprint should contain enough workload."
"Note that the product backlog is divided into multiple sprints and each sprint should contain enough workload. Your answer must follow the required format above."
]
},
"CheckProgressStatus": {
"assistant_role_name": "Product Owner",
"user_role_name": "Development Team",
"phase_prompt": [
"According to the user's task, our software designs, product backlog and acceptance criteria listed below: ",
"Task: \"{task}\".",
"Modality: \"{modality}\".",
"Programming Language: \"{language}\"",
"Product backlog:\n\"{plain_product_backlog}\"",
"Acceptance Criteria:\n\"{plain_acceptance_criteria}\"",
"We have decided to complete the task through a executable software with multiple files implemented via {language} by accomplishing the product backlog and acceptance criteria through multiple sprints. Until now, we have finished done tasks and undone tasks as below:",
"Current done tasks:",
"\"{all_done_tasks}\"",
"Current undone tasks:",
"\"{all_undone_tasks}\"",
"As the {assistant_role}, to satisfy the user's demands, you should carefully decide whether to conclude the project or create a next sprint based on the product backlog, acceptance criteria, done works and undone works.",
"Specifically, you compare done works with the product backlog to determine whether any items in the product backlog or acceptance criteria are incomplete, and you carefully review undone works to check if the program has any errors.",
"When all tasks in the product backlog and acceptance criteria are fully accomplished and the program is completely error-free, you should end the project by returning a only single line with the content: \"<INFO> DONE.\".",
"Otherwise, your answer must be a single line with the content: \"<INFO> UNDONE.\", indicating that the product backlog has not been accomplished or the program has some existing bugs, so you must create a next sprint to complete remaining tasks and fix all existing bugs.",
"Importantly, you are not allowed to conclude the project if there is any existing bug.",
"Think step by step and reason yourself to the right decisions before making a decision to make sure we get it right.",
"Additionally, you must adhere to the following regulations:",
"\t1) the project is concluded only if all the tasks in the product backlog and acceptance criteria are accomplished without any errors,",
"\t2) if the software has any bugs and errors, you should not conclude the project, and you should focus on making the software executable successfully.",
"Note that your answer must follow the required format above."
]
},
"NextSprintBacklogModification": {
"assistant_role_name": "Product Owner",
"user_role_name": "Development Team",
"phase_prompt": [
"According to the new user's task, our software designs, product backlog, acceptance criteria and our current progress, including done and undone tasks, are listed below: ",
"Task: \"{task}\".",
"Modality: \"{modality}\".",
"Programming Language: \"{language}\"",
"Product backlog:\n\"{plain_product_backlog}\"",
"Acceptance criteria:\n\"{plain_acceptance_criteria}\"",
"Done tasks:",
"\"{all_done_tasks}\"",
"Undone tasks:",
"\"{all_undone_tasks}\"",
"We have decided to complete the task through multiple sprints. Based on the product backlog, done and undone works, we propose the next sprint and we have corresponding comments as below:",
"Sprint backlog:\n\"{current_programming_task}\"",
"Sprint acceptance criteria:\n\"{current_acceptance_criteria}\"",
"Comments on sprint backlog and sprint acceptance criteria:",
"\"{sprint_backlog_comments}\"",
"As the {assistant_role}, to satisfy the user's demand and ensure that the sprint backlog and sprint acceptance criteria are feasible and can be accomplished, you should review comments to modify corresponding sprint backlog according to the comments. Then output the full and complete sprint backlog based on the comments. Return the output strictly following the required format and you are not allowed to change the required format:",
"Sprint backlog:",
"SPRINT_BACKLOG",
"Sprint acceptance criteria:",
"SPRINT_ACCEPTANCE_CRITERIA",
"where SPRINT_BACKLOG is the sprint backlog, and SPRINT_ACCEPTANCE_CRITERIA is the sprint acceptance criteria for the sprint backlog.",
"Note that SPRINT_BACKLOG, and SPRINT_ACCEPTANCE_CRITERIA are pseudo tokens, and your answer is prohibited from including these tokens.",
"Importantly, note that the product backlog is divided into multiple sprints and each sprint should contain enough workload.",
"Also, items in the sprint backlog are from the product backlog and do not introduce new tasks that do not appear in the product backlog."
]
},
"SprintReview": {

@@ -221,7 +300,6 @@ "assistant_role_name": "Product Owner",

"phase_prompt": [
"According to the user's task, our software designs, the sprint goals, the sprint backlog, our developed source code, and corresponding test reports and summaries are listed below: ",
"According to the user's task, our software designs, the sprint backlog, our developed source code, and corresponding test reports and summaries are listed below: ",
"Task: \"{task}\".",
"Modality: \"{modality}\".",
"Programming Language: \"{language}\"",
"Sprint goals:\n\"{current_sprint_goals}\"",
"Sprint backlog:\n\"{current_programming_task}\"",

@@ -235,5 +313,9 @@ "Sprint acceptance criteria:\n\"{current_acceptance_criteria}\"",

"\"{error_summary}\"",
"To satisfy the sprint goals, we have decided to complete the sprint backlog. As the {assistant_role}, you implemented source code and tested source code, then you wrote test reports and error summaries.",
"Now is at the end of the sprint, you should review all the work, what has been done, what has not.",
"You should answer according to the following format:",
"To complete the current sprint, we have addressed the sprint backlog and acceptance criteria. We have implemented and tested the source code, and produced test reports and error summaries.",
"As the {assistant_role}, it is now time to review each item in the sprint backlog to determine its completion status.",
"Your tasks are:",
"\t1. Review each item in the sprint backlog,",
"\t2. Categorize each item as Done Work or Undone Work,",
"\t3. Review test reports and error summaries to idenitify any existing bugs or failed test cases as Undone Work.",
"Please provide your answer in the following format:",
"Done Work:",

@@ -254,5 +336,4 @@ "DONE_WORK",

"Programming Language: \"{language}\"",
"Sprint goals:\n\"{current_sprint_goals}\"",
"Sprint backlog:\n\"{plain_sprint_backlog}\"",
"To satisfy the sprint goals, we have decided to complete the task through a executable software with multiple files implemented via {language}. As the {assistant_role}, to satisfy the user's demands and the sprint goals, you must assess the technical and skill requirements of each task and determine which team members are best suited for the work. You also need to prioritize tasks with the important tasks appearing first.",
"To satisfy the user's task, we have decided to complete the task through a executable software with multiple files implemented via {language}. As the {assistant_role}, to satisfy the user's demands, you must assess the technical and skill requirements of each task and determine which team members are best suited for the work. You also need to prioritize tasks with the important tasks appearing first.",
"Think step by step and reason yourself to the right decisions to make sure we get it right.",

@@ -273,9 +354,8 @@ "Your answer includes many lines where each separate line strictly obeys the following format:",

"Programming Language: \"{language}\"",
"Sprint goals:\n\"{current_sprint_goals}\"",
"Sprint backlog:\n\"{current_programming_task}\"",
"Sprint acceptance criteria:\n\"{current_acceptance_criteria}\"",
"To satisfy the sprint goals, we have decided to complete the sprint backlog through a executable software with multiple files implemented via {language}. As the {assistant_role}, to satisfy the user's demands and the sprint goals, you should accomplish the sprint backlog by writing one or multiple files and make sure that every detail of the architecture is, in the end, implemented as code. {gui}",
"To satisfy the user's task, we have decided to complete the sprint backlog through a executable software with multiple files implemented via {language}. As the {assistant_role}, to satisfy the user's demands, you should accomplish the sprint backlog by writing one or multiple files and make sure that every detail of the architecture is, in the end, implemented as code.",
"Think step by step and reason yourself to the right decisions to make sure we get it right.",
"You will first lay out the names of the core classes, functions, methods that will be necessary, as well as a quick comment on their purpose.",
"Then you will output the content of each file including complete code. Each file must strictly follow a markdown code block format, where the following tokens must be replaced such that FILENAME is the lowercase file name including the file extension, LANGUAGE in the programming language, DOCSTRING is a string literal specified in source code that is used to document a specific segment of code, and CODE is the original code:",
"Then you will output the content of each file including complete code, and each file should contain only one class. Each file must strictly follow a markdown code block format, where the following tokens must be replaced such that FILENAME is the lowercase file name including the file extension, LANGUAGE in the programming language, DOCSTRING is a string literal specified in source code that is used to document a specific segment of code, and CODE is the original code:",
"FILENAME",

@@ -297,3 +377,2 @@ "```LANGUAGE",

"```",
"You will start with the \"main\" file, then go to the ones that are imported by that file, and so on.",
"Please note that the code should be fully functional. Ensure to implement all functions. No placeholders (such as 'pass' in Python)."

@@ -310,10 +389,12 @@ ]

"Programming Language: \"{language}\"",
"Sprint goals:\n\"{current_sprint_goals}\"",
"Sprint backlog:\n\"{current_programming_task}\"",
"Sprint acceptance criteria:\n\"{current_acceptance_criteria}\"",
"To satisfy the sprint goals, we have decided to complete the sprint backlog through a executable software with multiple files implemented via {language} with detailed source code below:",
"Codes:",
"\"{codes}\"",
"However, the source code above has not been tested comprehensively to ensure the correctness, so it potential has undiscovered bugs.",
"As the Software Test Engineer, you must write automated tests to ensure that the source code runs flawlessly and aligns with the sprint goals and the sprint backlog. Your test cases should cover all possibilities of source code and fulfill the sprint acceptance criteria.",
"To satisfy the user's task, we have decided to complete the sprint backlog through a executable software with multiple files implemented via {language}.",
"However, source code has not been tested comprehensively to ensure the correctness, so it potentially has undiscovered bugs. Below are untested code and its dependencies.",
"Dependencies:",
"\"{code_dependencies}\"",
"Untested code:",
"\"{untested_code}\"",
"As the Software Test Engineer, you are only allowed to write automated test cases for the untested code to ensure that the source code runs flawlessly and aligns with the sprint backlog and sprint acceptance criteria. You should not write test cases for code dependencies and just focus on the untested code. Your test cases should cover all possibilities of source code and fulfill the sprint acceptance criteria.",
"Importantly, test cases should cover basic, normal conditions and extreme or unusual conditions to comprehensively test the correctness of source code in all possible cases.",
"Think step by step and reason yourself to the right decisions to make sure we get it right.",

@@ -339,6 +420,5 @@ "Then you will only output the content of each testing script including complete testing code. Each file must strictly follow a markdown code block format, where the following tokens must be replaced such that FILENAME is the lowercase file name including the file extension, LANGUAGE in the programming language, DOCSTRING is a string literal specified in source code that is used to document a specific segment of code, and CODE is the original code:",

"Programming Language: \"{language}\"",
"Sprint goals:\n\"{current_sprint_goals}\"",
"Sprint backlog:\n\"{current_programming_task}\"",
"Sprint acceptance criteria:\n\"{current_acceptance_criteria}\"",
"To satisfy the sprint goals, we have decided to complete the sprint backlog through a executable software with multiple files implemented via {language}. As the {assistant_role}, to satisfy the user's demands and the sprint goals, you should accomplish the sprint backlog and sprint goals by designing solution architecture and method interfaces. {gui}",
"To satisfy the user's task, we have decided to complete the sprint backlog through a executable software with multiple files implemented via {language}. As the {assistant_role}, to satisfy the user's demands, you should accomplish the sprint backlog and sprint acceptance criteria by designing solution architecture and method interfaces. {gui}",
"Think step by step and reason yourself to the right decisions to make sure we get it right.",

@@ -385,10 +465,13 @@ "You will first lay out the names of the core classes, functions, methods that will be necessary, as well as a quick comment on their purpose.",

"The code above contains enough values for the required fields: FILENAME, LANGUAGES, DOCSTRING and CODE. However, they are not written to follow the format properly. You should rearrange them to satisfy the requirement.",
"Example:",
"Example of the format:",
"a.py",
"```python",
"def f():",
"'''",
"an empty function",
"'''",
" pass",
"```",
"As the {assistant_role}, to make the code satisfy the required format, you should modify corresponding codes according to the comments and then return all codes strictly following the required format.",
"Please note that you are not allowed to write new code or change the values of any fields, meaning that the new code is only different from the original code in terms of the format."
"Please note that you are not allowed to write new code or change the values of any fields and filenames, meaning that the new code is only different from the original code in terms of the format."
]

@@ -408,6 +491,5 @@ },

"Here is the details of the current sprint:",
"Sprint goals:\n\"{current_sprint_goals}\"",
"Sprint backlog:\n\"{current_programming_task}\"",
"Sprint acceptance criteria:\n\"{current_acceptance_criteria}\"",
"As the {assistant_role}, to satisfy the user's demands and the sprint goals, you should accomplish the sprint backlog by inheriting existing source code and writing one or multiple files and make sure that every detail of the architecture is, in the end, implemented as code. {gui}",
"As the {assistant_role}, to satisfy the user's demands, you should accomplish the sprint backlog by inheriting existing source code and writing one or multiple files and make sure that every detail of the architecture is, in the end, implemented as code.",
"Think step by step and reason yourself to the right decisions to make sure we get it right.",

@@ -432,3 +514,2 @@ "You will first lay out the names of the core classes, functions, methods that will be necessary, as well as a quick comment on their purpose.",

"```",
"You will start with the \"main\" file, then go to the ones that are imported by that file, and so on.",
"Please note that the code should be fully functional. Ensure to implement all functions. No placeholders (such as 'pass' in Python)."

@@ -521,3 +602,2 @@ ]

"Programming Language: \"{language}\"",
"Sprint goals:\n\"{current_sprint_goals}\"",
"Sprint backlog:\n\"{current_programming_task}\"",

@@ -535,3 +615,3 @@ "Sprint acceptance criteria:\n\"{current_acceptance_criteria}\"",

"\t5) The entire project conforms to the tasks proposed by the user;",
"\t6) To satisfy the sprint goals, the code implements all the tasks in the sprint backlog;",
"\t6) To satisfy the user's task, the code implements all the tasks in the sprint backlog;",
"\t7) Make sure the used assets like images must exist and be referred properly;",

@@ -553,3 +633,2 @@ "\t8) Ensure that the colors used are easy on the eye;",

"Programming Language: \"{language}\"",
"Sprint goals:\n\"{current_sprint_goals}\"",
"Sprint backlog:\n\"{current_programming_task}\"",

@@ -560,3 +639,3 @@ "Changed Codes:",

"\"{paths}\"",
"As the {assistant_role}, to make the software directly operable without further coding, AgileCoder have formulated the following regulations:",
"As the {assistant_role}, to satisfy the sprint backlog, you adhere to the following regulations of AgileCoder:",
"\t1) all referenced classes should be imported;",

@@ -569,3 +648,3 @@ "\t2) all methods should be implemented;",

"\t7) Make sure the used assets like images must exist and be referred properly;",
"Now, you should check the above regulations one by one and review the changed codes in detail, propose one comment with the highest priority about the codes, and give me instructions in text on how to fix and does not include modified code.Tell me your comment with the highest priority and corresponding suggestions on revision. If the codes are perfect and you have no comment on them, return only one line like \"<INFO> Finished\"."
"Now, you should check the above regulations one by one and review the changed codes in detail, propose one comment with the highest priority about the changed codes, and give me instructions in text on how to fix and does not include modified code. You just review the changed code to make sure that new code is correct and bug-free. Tell me your comment with the highest priority and corresponding suggestions on revision. Importantly, when the codes are perfect and you have no comment on them, just return one line with the content: \"<INFO> Finished.\" and do nothing."
]

@@ -581,12 +660,11 @@ },

"Programming Language: \"{language}\"",
"Sprint goals:\n\"{current_sprint_goals}\"",
"Sprint backlog:\n\"{current_programming_task}\"",
"Changed Codes:",
"\"{codes}\"",
"As the {assistant_role}, to make the software directly operable without further coding, AgileCoder have formulated the following regulations:",
"As the {assistant_role}, to satisfy the sprint backlog, you adhere to the following regulations of AgileCoder:",
"\t1) The entire project conforms to the tasks proposed by the user;",
"\t2) To satisfy the sprint goals, the code implements all the tasks in the sprint backlog;",
"\t2) To satisfy the user's task, the code implements all the tasks in the sprint backlog;",
"\t3) ensure that no code is duplicated and the answer is not allowed to repeat code;",
"\t4) most importantly, do not only check the errors in the code, but also the logic of code. Make sure that user can interact with generated software without losing any feature in the requirement;",
"Now, you should check the above regulations one by one and review the changed codes in detail, propose one comment with the highest priority about the codes, and give me instructions in text on how to fix and does not include modified code. Tell me your comment with the highest priority and corresponding suggestions on revision. If the codes are perfect and you have no comment on them, return only one line like \"<INFO> Finished\"."
"Now, you should check the above regulations one by one and review the changed codes in detail, propose one comment with the highest priority about the codes, and give me instructions in text on how to fix and does not include modified code. You just review the changed code to make sure that new code is correct and bug-free. Tell me your comment with the highest priority and corresponding suggestions on revision. Importantly, when the codes are perfect and you have no comment on them, just return one line with the content: \"<INFO> Finished.\" and do nothing."
]

@@ -602,7 +680,6 @@ },

"Programming Language: \"{language}\"",
"Sprint goals:\n\"{current_sprint_goals}\"",
"Sprint acceptance criteria:\n\"{current_acceptance_criteria}\"",
"Changed Codes:",
"\"{codes}\"",
"As the {assistant_role}, to make the software directly operable without further coding, AgileCoder have formulated the following regulations:",
"As the {assistant_role}, to satisfy the sprint acceptance criteria, you adhere to the following regulations of AgileCoder:",
"\t1) no potential bugs;",

@@ -612,3 +689,3 @@ "\t2) the code fulfills all criteria in the sprint acceptance criteria;",

"\t4) most importantly, do not only check the errors in the code, but also the logic of code. Make sure that user can interact with generated software without creating any new bugs;",
"Now, you should check the above regulations one by one and review the changed codes in detail, propose one comment with the highest priority about the codes, and give me instructions in text on how to fix and does not include modified code. Tell me your comment with the highest priority and corresponding suggestions on revision. If the codes are perfect and you have no comment on them, return only one line like \"<INFO> Finished\"."
"Now, you should check the above regulations one by one and review the changed codes in detail, propose one comment with the highest priority about the codes, and give me instructions in text on how to fix and does not include modified code. You just review the changed code to make sure that new code is correct and bug-free. Tell me your comment with the highest priority and corresponding suggestions on revision. Importantly, when the codes are perfect and you have no comment on them, just return one line with the content: \"<INFO> Finished.\" and do nothing."
]

@@ -620,7 +697,6 @@ },

"phase_prompt": [
"According to the user's task, our designed product modality, languages, the sprint goals and the sprint backlog, our changed source codes are listed below: ",
"According to the user's task, our designed product modality, languages, the sprint backlog, sprint acceptance criteria and our changed source codes are listed below: ",
"User's task: \"{task}\".",
"Modality: \"{modality}\".",
"Programming Language: \"{language}\"",
"Sprint goals:\n\"{current_sprint_goals}\"",
"Sprint backlog:\n\"{current_programming_task}\"",

@@ -640,3 +716,3 @@ "Sprint acceptance criteria:\n\"{current_acceptance_criteria}\"",

"```",
"As the {assistant_role}, to satisfy the user's demand and the sprint goals, make the software creative, executive and robust, and ensure that the code resolves the sprint backlog, you should modify corresponding codes according to the comments. Then, output the full and complete codes with all bugs fixed based on the comments. Return all codes strictly following the required format."
"As the {assistant_role}, to make the software executive and robust, and ensure that the code resolves the sprint backlog, you should modify corresponding codes according to the comments. Then, output the full and complete codes with all bugs fixed based on the comments. Return all codes strictly following the required format."
]

@@ -648,11 +724,9 @@ },

"phase_prompt": [
"According to the user's task, our designed product modality, languages, the sprint goals and the sprint backlog, our developed source codes are listed below: ",
"According to the user's task, our designed product modality, languages, the sprint backlog, and our changed code files are listed below: ",
"User's task: \"{task}\".",
"Modality: \"{modality}\".",
"Programming Language: \"{language}\"",
"Sprint goals:\n\"{current_sprint_goals}\"",
"Sprint backlog:\n\"{current_programming_task}\"",
"Codes:",
"Changed Code Files:",
"\"{codes}\"",
"Comments on Codes:",
"Comments on Changed Codes:",
"\"{comments}\"",

@@ -667,3 +741,3 @@ "In the software, each file must strictly follow a markdown code block format, where the following tokens must be replaced such that FILENAME is the lowercase file name including the file extension, LANGUAGE in the programming language, DOCSTRING is a string literal specified in source code that is used to document a specific segment of code, and CODE is the original code. Format:",

"```",
"As the {assistant_role}, to satisfy the user's demand, the sprint goals and the sprint backlog, make the software creative, executive and robust, and ensure that the code resolves the sprint backlog, you should modify corresponding codes according to the comments. Then, output the full and complete codes with all bugs fixed based on the comments. Return all codes strictly following the required format."
"As the {assistant_role}, to ensure that the code resolves the comments, you should modify corresponding codes according to the comments. Then, only return complete and new code files that were changed, with all bugs fixed based on the comments. Your response must not include unchanged files and must strictly follow the required format."
]

@@ -675,11 +749,9 @@ },

"phase_prompt": [
"According to the user's task, our designed product modality, languages, the sprint goals and the sprint backlog, our developed source codes are listed below: ",
"According to the user's task, our designed product modality, languages, the sprint backlog, and our changed source codes are listed below: ",
"User's task: \"{task}\".",
"Modality: \"{modality}\".",
"Programming Language: \"{language}\"",
"Sprint goals:\n\"{current_sprint_goals}\"",
"Sprint backlog:\n\"{current_programming_task}\"",
"Codes:",
"Changed Codes:",
"\"{codes}\"",
"Comments on Codes:",
"Comments on Changed Codes:",
"\"{comments}\"",

@@ -694,3 +766,3 @@ "In the software, each file must strictly follow a markdown code block format, where the following tokens must be replaced such that FILENAME is the lowercase file name including the file extension, LANGUAGE in the programming language, DOCSTRING is a string literal specified in source code that is used to document a specific segment of code, and CODE is the original code. Format:",

"```",
"As the {assistant_role}, to satisfy the user's demand, the sprint goals and the sprint backlog, make the software creative, executive and robust, and ensure that the code resolves the sprint backlog, you should modify corresponding codes according to the comments. Then, output the full and complete codes with all bugs fixed based on the comments. Return all codes strictly following the required format."
"As the {assistant_role}, to ensure that the code resolves the comments, you should modify corresponding codes according to the comments. Then, only return complete and new code files that were changed, with all bugs fixed based on the comments. Your response must not include unchanged files and must strictly follow the required format."
]

@@ -702,11 +774,9 @@ },

"phase_prompt": [
"According to the user's task, our designed product modality, languages, the sprint goals and the sprint acceptance criteria, our developed source codes are listed below: ",
"According to the user's task, our designed product modality, languages, the sprint acceptance criteria, and our changed source codes are listed below: ",
"User's task: \"{task}\".",
"Modality: \"{modality}\".",
"Programming Language: \"{language}\"",
"Sprint goals:\n\"{current_sprint_goals}\"",
"Sprint acceptance criteria:\n\"{current_acceptance_criteria}\"",
"Codes:",
"Changed Codes:",
"\"{codes}\"",
"Comments on Codes:",
"Comments on Changed Codes:",
"\"{comments}\"",

@@ -721,3 +791,3 @@ "In the software, each file must strictly follow a markdown code block format, where the following tokens must be replaced such that FILENAME is the lowercase file name including the file extension, LANGUAGE in the programming language, DOCSTRING is a string literal specified in source code that is used to document a specific segment of code, and CODE is the original code. Format:",

"```",
"As the {assistant_role}, to satisfy the user's demand, the sprint goals and the sprint acceptance criteria, make the software creative, executive and robust, and ensure that the code resolves the sprint backlog, you should modify corresponding codes according to the comments. Then, output the full and complete codes with all bugs fixed based on the comments. Return all codes strictly following the required format."
"As the {assistant_role}, to ensure that the code resolves the comments, you should modify corresponding codes according to the comments. Then, only return complete and new code files that were changed, with all bugs fixed based on the comments. Your response must not include unchanged files and must strictly follow the required format."
]

@@ -729,7 +799,6 @@ },

"phase_prompt": [
"According to the user's task, our designed product modality, the sprint goals and the sprint backlog, our developed first-edition source codes are listed below: ",
"According to the user's task, our designed product modality, the sprint backlog, and our developed first-edition source codes are listed below: ",
"User's task: \"{task}\".",
"Modality: \"{modality}\".",
"Programming Language: \"{language}\"",
"Sprint goals:\n\"{current_sprint_goals}\"",
"Sprint backlog:\n\"{current_programming_task}\"",

@@ -748,3 +817,3 @@ "Codes: ",

"```",
"As the {assistant_role}, to satisfy new user's demand and the sprint goals, make the software creative, executive and robust, and ensure that the code resolves the sprint backlog, you should modify corresponding codes according to the comments. Then, output the fixed codes strictly following the required format."
"As the {assistant_role}, to satisfy new user's demand, make the software creative, executive and robust, and ensure that the code resolves the sprint backlog, you should modify corresponding changed codes according to the comments. Then, output the fixed codes strictly following the required format."
]

@@ -756,3 +825,3 @@ },

"phase_prompt": [
"Our developed source codes and corresponding test reports are listed below: ",
"Our potentially buggy source codes and corresponding test reports are listed below: ",
"Programming Language: \"{language}\"",

@@ -763,5 +832,18 @@ "Source Codes:",

"\"{test_reports}\"",
"According to my test reports, please locate and summarize the bugs that cause the problem."
"According to my test reports, please locate and summarize the bugs that cause the problem. Importantly, it should be noted that the failed test case may be an incorrect test case, so you should carefully review code, failed test case, sprint backlog and acceptance criteria to figure out problems correctly."
]
},
"SprintTestErrorSummary": {
"assistant_role_name": "Programmer",
"user_role_name": "Software Test Engineer",
"phase_prompt": [
"Our potentially buggy source codes and corresponding test reports are listed below: ",
"Programming Language: \"{language}\"",
"Source Codes:",
"\"{codes}\"",
"Test Reports of Source Codes:",
"\"{test_reports}\"",
"According to my test reports, please locate and summarize the bugs that cause the problem. Importantly, it should be noted that the failed test case may be an incorrect test case, so you should carefully review code, failed test case, sprint backlog and acceptance criteria to figure out problems correctly."
]
},
"TestingPlan": {

@@ -771,13 +853,12 @@ "assistant_role_name": "Software Test Engineer",

"phase_prompt": [
"According to the user's task, our designed product modality, the sprint goals and the sprint backlog, our developed first-edition source codes are listed below: ",
"According to the user's task, our designed product modality, the sprint backlog, and our developed source codes are listed below: ",
"User's task: \"{task}\".",
"Modality: \"{modality}\".",
"Programming Language: \"{language}\"",
"Sprint goals:\n\"{current_sprint_goals}\"",
"Sprint backlog:\n\"{current_programming_task}\"",
"Codes:",
"\"{codes}\"",
"As the {assistant_role}, to make that the code above satisfies the sprint goals and backlog and runs flawlessly, you must write commands to:",
"As the {assistant_role}, to make that the code above satisfies the sprint backlog and runs flawlessly, you must write commands to:",
"\t1) run testing scripts available in the source code,",
"\t2) start the UI of the software and test the correctness of the code above.",
"\t2) test the correctness of the code above.",
"Also, you strictly follow the format:",

@@ -793,5 +874,5 @@ "Commands:",

"phase_prompt": [
"Our developed source codes and corresponding test reports are listed below: ",
"Our potentially buggy source codes and corresponding test reports are listed below:",
"Programming Language: \"{language}\"",
"Source Codes:",
"Potentially Buggy Source Codes:",
"\"{codes}\"",

@@ -810,5 +891,15 @@ "Test Reports of Source Codes:",

"```",
"As the {assistant_role}, to satisfy the new user's demand and make the software execute smoothly and robustly, you should modify the codes based on the error summary.",
"Now, use the format exemplified above and modify the problematic codes based on the error summary. If you cannot find the assets from the existing paths, you should consider remove relevant code and features. Output the codes that you fixed based on the test reported and corresponding explanations (strictly follow the format defined above, including FILENAME, LANGUAGE, DOCSTRING and CODE; incomplete \"TODO\" codes are strictly prohibited). If no bugs are reported, please return only one line like \"<INFO> Finished\"."
]
"Example of the format:",
"a.py",
"```python",
"def f():",
"'''",
"an empty function",
"'''",
" pass",
"```",
"As the {assistant_role}, to satisfy the new user's demand and make the software execute smoothly and robustly, you should modify the codes based on failed test cases and the error summary. It is important to note that failed test case may be an incorrect test case, so you should comprehend the user's task, sprint backlog and sprint acceptance criteria to modify code correctly.",
"Now, use the format exemplified above, and carefully review code and failed test cases to modify code correctly. Next, output complete and updated code files that you fixed based on the test reported and corresponding explanations (strictly follow the format defined above, including FILENAME, LANGUAGE, DOCSTRING and CODE; incomplete \"TODO\" codes are strictly prohibited). Your response should include only the complete and updated code files and must not repeat unchanged files."
]
},

@@ -815,0 +906,0 @@ "EnvironmentDoc": {

@@ -42,3 +42,3 @@ {

"Ideas:\"{ideas}\"",
"We have decided to complete the task through a executable software with multiple files implemented via {language}. As the {assistant_role}, to satisfy the new user's demands, you should write one or multiple files and make sure that every detail of the architecture is, in the end, implemented as code. {gui}",
"We have decided to complete the task through a executable software with multiple files implemented via {language}. As the {assistant_role}, to satisfy the new user's demands, you should write one or multiple files and make sure that every detail of the architecture is, in the end, implemented as code.",
"Think step by step and reason yourself to the right decisions to make sure we get it right.",

@@ -45,0 +45,0 @@ "You will first lay out the names of the core classes, functions, methods that will be necessary, as well as a quick comment on their purpose.",

@@ -24,2 +24,3 @@ import importlib

def __init__(self,
max_num_sprints: int,
config_path: str = None,

@@ -44,2 +45,3 @@ config_phase_path: str = None,

# load config file
self.max_num_sprints = max_num_sprints
self.config_path = config_path

@@ -166,3 +168,3 @@ self.config_phase_path = config_phase_path

self.execute_step(phase_item)
for i in range(10):
for i in range(self.max_num_sprints - 1):
if self.chat_env.env_dict.get('end-sprint', False):

@@ -206,3 +208,3 @@ break

os.remove(file_path)
print("{} Removed.".format(file_path))
# print("{} Removed.".format(file_path))
software_path = os.path.join(directory, "_".join([self.project_name, self.org_name, self.start_time]))

@@ -263,3 +265,3 @@ self.chat_env.set_directory(software_path)

get_info(self.chat_env.env_dict['directory'], self.log_filepath) + "\n\n🕑**duration**={:.2f}s\n\n".format(duration))
post_info += f'Number of sprints {self.chat_env.env_dict["num-sprints"]}\n\n'
post_info += f'Number of sprints {self.chat_env.env_dict.get("num-sprints", 1)}\n\n'
post_info += "AgileCoder Starts ({})".format(self.start_time) + "\n\n"

@@ -266,0 +268,0 @@ post_info += "AgileCoder Ends ({})".format(now_time) + "\n\n"

@@ -8,3 +8,3 @@ import os

import time
from typing import Dict
from typing import Dict, Tuple

@@ -17,3 +17,3 @@ import openai

from agilecoder.components.roster import Roster
from agilecoder.components.utils import log_and_print_online
from agilecoder.components.utils import log_and_print_online, extract_first_error_traceback, extract_top_k_errors
from agilecoder.camel.dependency import build_dependency_graph, get_test_order

@@ -60,6 +60,18 @@

self.dependency_graph = None
self.testing_file_map = {}
self.proposed_images: Dict[str, str] = {}
self.incorporated_images: Dict[str, str] = {}
self.context_images: Dict[str, str] = {}
self.requirements: Documents = Documents()
self.manuals: Documents = Documents()
self.tool_usage = {
'FileSystem': 0,
'Class': 0,
'Testcase': 0,
'Module': 0,
'AttributeError': 0,
'TypeError': 0,
'other': 0,
'graph': 0
}
self.env_dict = {

@@ -75,3 +87,19 @@ "directory": "",

}
def count_file_system_call(self):
self.tool_usage['FileSystem'] += 1
def count_class_call(self):
self.tool_usage['Class'] += 1
def count_test_case_call(self):
self.tool_usage['Testcase'] += 1
def count_module_call(self):
self.tool_usage['Module'] += 1
def count_attribute_error(self):
self.tool_usage['AttributeError'] += 1
def count_type_error(self):
self.tool_usage['TypeError'] += 1
def count_other_call(self):
self.tool_usage['other'] += 1
def count_graph_call(self):
self.tool_usage['graph'] += 1
@staticmethod

@@ -96,3 +124,3 @@ def fix_module_not_found_error(test_reports):

shutil.copytree(directory, new_directory)
print("{} Copied to {}".format(directory, new_directory))
# print("{} Copied to {}".format(directory, new_directory))
if self.config.clear_structure:

@@ -102,3 +130,3 @@ if os.path.exists(self.env_dict['directory']):

os.mkdir(self.env_dict['directory'])
print("{} Created".format(directory))
# print("{} Created".format(directory))
else:

@@ -108,5 +136,5 @@ os.mkdir(self.env_dict['directory'])

def exist_bugs(self, chat_env) -> tuple[bool, str]:
def exist_bugs(self, chat_env) -> Tuple[bool, str]:
directory = self.env_dict['directory']
print('DIRECTORY:', directory)
# print('DIRECTORY:', directory)

@@ -127,27 +155,35 @@ success_info = "The software run successfully without errors."

else:
all_files = os.listdir(directory)
runnable_files = []
is_python = False
for file in all_files:
program_files = []
for file, code in self.codes.codebooks.items():
# print('FILE:', file, code)
if not file.endswith('.py'): continue
is_python = True
with open(os.path.join(directory, file)) as f:
code = f.read()
if has_entry_point(code):
runnable_files.append(file)
if not (('test_' in file) or ('_test' in file)):
program_files.append(file)
return_flag = False
if 'testing_commands' not in self.env_dict:
chat_env.count_graph_call()
testing_commands = self.env_dict['commands']
_testing_commands = list(filter(lambda x: 'test_' in x, get_test_order(chat_env.dependency_graph)))
_testing_commands = list(filter(lambda x: x.startswith('test_') or x.split('.')[0].endswith('_test'), get_test_order(chat_env.dependency_graph, chat_env.testing_file_map)))
additional_commands = list(set(testing_commands) - set(_testing_commands))
testing_commands = _testing_commands + additional_commands
# print('additional_commands', additional_commands)
# additional_commands = list(filter(lambda x: x in runnable_files, additional_commands))
testing_commands = _testing_commands + additional_commands + program_files
# testing_commands = _testing_commands + additional_commands
# for file in program_files:
# if file not in testing_commands:
# testing_commands.append(file)
error_contents = ''
if is_python and len(runnable_files) == 0:
return True, "[Error] the software lacks an entry point to start"
testing_commands.extend(runnable_files)
# testing_commands.extend(runnable_files)
for file in runnable_files:
if file not in testing_commands:
testing_commands.append(file)
# testing_commands.extend(['-m unittest'])
testing_commands = list(set(testing_commands))
# testing_commands = list(set(testing_commands))
else:

@@ -159,32 +195,18 @@ testing_commands = self.env_dict['testing_commands']

if testing_command != '-m unittest' and testing_command not in runnable_files:
errs = "[Error] the software lacks an entry point to start"
error_contents += """\nError Traceback for Running {testing_command}:\n{errs}""".format(testing_command = testing_command, errs = errs)
return_flag = True
continue
if 'main.py' in all_files and testing_command == 'main.py':
command = "cd {}; ls -l; python3 main.py;".format(directory)
# process = subprocess.Popen(command,
# shell=True,
# preexec_fn=os.setsid,
# stdout=subprocess.PIPE,
# stderr=subprocess.PIPE
# )
if testing_command.startswith('test_') or testing_command.split('.')[0].endswith('_test'):
errs = "[Error] the testing script lacks an entry point to start. Please modify accordingly to run test cases."
error_contents += """\nError Traceback for Running File "{testing_command}":\n{errs}""".format(testing_command = testing_command, errs = errs)
return_flag = True
break
else:
errs = "[Error] the software lacks an entry point to start. Please modify accordingly to make the program executable."
error_contents += """\nError Traceback for Running File "{testing_command}":\n{errs}""".format(testing_command = testing_command, errs = errs)
return_flag = True
break
if 'main.py' in self.codes.codebooks and testing_command == 'main.py':
command = "cd {}; ls -l; python main.py;".format(directory)
else:
# flag = False
# for file in all_files:
# if not file.endswith('.py'): continue
# with open(os.path.join(directory, file)) as f:
# code = f.read()
# if has_entry_point(code):
# command = "cd {}; ls -l; python3 ".format(directory) + file
# flag = True
# process = subprocess.Popen(command,
# shell=True,
# preexec_fn=os.setsid,
# stdout=subprocess.PIPE,
# stderr=subprocess.PIPE
# )
# break
command = "cd {}; ls -l; python3 ".format(directory) + testing_command
print('COMMAND:', command)
command = "cd {}; ls -l; python ".format(directory) + testing_command
# print('COMMAND:', command)
process = subprocess.Popen(command,

@@ -222,2 +244,4 @@ shell=True,

error_output = process.stderr.read().decode('utf-8')
std_output = process.stdout.read().decode('utf-8')
# print('error_output', "Traceback".lower() in error_output.lower(), ':return_code:', return_code)
if return_code != 0:

@@ -227,6 +251,23 @@ if error_output:

errs = error_output.replace(directory + "/", "")
# all_file_names = re.findall(r'File "(.*?)"', errs)
# if len(all_file_names) > len(set(all_file_names)):
# errs = extract_first_error_traceback(errs)
if errs.count('--------------------------') > 1:
new_errs = extract_first_error_traceback(errs)
if len(new_errs):
errs = new_errs
# return True, errs
error_contents += """\nError Traceback for Running `{testing_command}:\n{errs}""".format(testing_command = testing_command, errs = errs)
error_contents += """\nError Traceback for running File "{testing_command}":\n{errs}""".format(testing_command = testing_command, errs = errs)
return_flag = True
elif testing_command.startswith('test_') or testing_command.split('.')[0].endswith('_test'):
if 'FAILED' in std_output and '**************' not in std_output:
std_output = extract_top_k_errors(std_output, k = 1)
error_contents += """\nError Traceback for running File "{testing_command}":\n{std_output}""".format(testing_command = testing_command, std_output = std_output)
return_flag = True
elif 'failures' in std_output.lower() and 'failed' in std_output.lower():
error_contents += """\nError Traceback for running File "{testing_command}":\n{std_output}""".format(testing_command = testing_command, std_output = std_output)
return_flag = True
# else:

@@ -237,6 +278,7 @@ # return False, success_info

# error_contents += """\nError Traceback for Running `{testing_command}`":\n{errs}""".format(testing_command = testing_command, errs = errs)
# print('return_flag:', return_flag)
current_idx += 1
if return_flag:
chat_env.env_dict['testing_commands'] = testing_commands[current_idx:]
break
return return_flag, error_contents
if return_flag:

@@ -254,2 +296,130 @@ return return_flag, error_contents

def exist_bugs_ignoring_test_cases(self, chat_env) -> Tuple[bool, str]:
directory = self.env_dict['directory']
# print('DIRECTORY:', directory)
success_info = "The software run successfully without errors."
try:
# check if we are on windows or linux
if os.name == 'nt':
command = "cd {} && dir && python main.py".format(directory)
process = subprocess.Popen(
command,
shell=True,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE,
creationflags=subprocess.CREATE_NEW_PROCESS_GROUP
)
else:
runnable_files = []
is_python = False
program_files = []
for file, code in self.codes.codebooks.items():
# print('FILE:', file, code)
if not file.endswith('.py'): continue
is_python = True
if has_entry_point(code):
runnable_files.append(file)
if not (('test_' in file) or ('_test' in file)):
program_files.append(file)
return_flag = False
testing_commands = self.env_dict['commands']
_testing_commands = list(filter(lambda x: x.startswith('test_') or x.split('.')[0].endswith('_test'), get_test_order(chat_env.dependency_graph, chat_env.testing_file_map)))
additional_commands = list(set(testing_commands) - set(_testing_commands))
# print('additional_commands', additional_commands)
# additional_commands = list(filter(lambda x: x in runnable_files, additional_commands))
testing_commands = additional_commands + program_files
error_contents = ''
for testing_command in testing_commands:
if testing_command not in runnable_files:
errs = "[Error] the software lacks an entry point to start. Please modify accordingly to make the program executable."
error_contents += """\nError Traceback for Running File "{testing_command}":\n{errs}""".format(testing_command = testing_command, errs = errs)
return_flag = True
continue
if 'main.py' in self.codes.codebooks and testing_command == 'main.py':
command = "cd {}; ls -l; python main.py;".format(directory)
else:
command = "cd {}; ls -l; python ".format(directory) + testing_command
# print('COMMAND:', command)
process = subprocess.Popen(command,
shell=True,
preexec_fn=os.setsid,
stdout=subprocess.PIPE,
stderr=subprocess.PIPE
)
# if len(process.stderr.read().decode('utf-8')) > 0: break
# if not flag:
# return False, "Error: the software lacks the entry point to start"
time.sleep(3)
return_code = process.returncode
# Check if the software is still running
if process.poll() is None:
if "killpg" in dir(os):
os.killpg(os.getpgid(process.pid), signal.SIGTERM)
else:
os.kill(process.pid, signal.SIGTERM)
if process.poll() is None:
os.kill(process.pid,signal.CTRL_BREAK_EVENT)
# if return_code == 0:
# return False, success_info
# else:
# error_output = process.stderr.read().decode('utf-8')
# if error_output:
# if "Traceback".lower() in error_output.lower():
# errs = error_output.replace(directory + "/", "")
# return True, errs
# else:
# return False, success_info
error_output = process.stderr.read().decode('utf-8')
# print('error_output', "Traceback".lower() in error_output.lower(), ':return_code:', return_code)
std_output = process.stdout.read().decode('utf-8')
if return_code != 0:
if error_output:
if "Traceback".lower() in error_output.lower():
errs = error_output.replace(directory + "/", "")
# all_file_names = re.findall(r'File "(.*?)"', errs)
# if len(all_file_names) > len(set(all_file_names)):
# errs = extract_first_error_traceback(errs)
if errs.count('--------------------------') > 1:
new_errs = extract_first_error_traceback(errs, 1)
if len(new_errs):
errs = new_errs
# return True, errs
error_contents += """\nError Traceback for running File "{testing_command}":\n{errs}""".format(testing_command = testing_command, errs = errs)
return_flag = True
elif testing_command.startswith('test_') or testing_command.split('.')[0].endswith('_test'):
if 'FAILED' in std_output and '**************' not in std_output:
std_output = extract_top_k_errors(std_output, k = 1)
error_contents += """\nError Traceback for running File "{testing_command}":\n{std_output}""".format(testing_command = testing_command, std_output = std_output)
return_flag = True
elif 'failures' in std_output.lower() and 'failed' in std_output.lower():
error_contents += """\nError Traceback for running File "{testing_command}":\n{std_output}""".format(testing_command = testing_command, std_output = std_output)
return_flag = True
# else:
# return False, success_info
# else:
# return_flag = True
# error_contents += """\nError Traceback for Running `{testing_command}`":\n{errs}""".format(testing_command = testing_command, errs = errs)
if return_flag:
return return_flag, error_contents
else:
return False, success_info
except subprocess.CalledProcessError as e:
return True, f"Error: {e}"
except Exception as ex:
return True, f"An error occurred: {ex}"
return False, success_info
def recruit(self, agent_name: str):

@@ -264,4 +434,4 @@ self.roster._recruit(agent_name)

def update_codes(self, generated_content, is_testing = False):
return self.codes._update_codes(generated_content, is_testing)
def update_codes(self, generated_content, is_testing = False, file_name = None):
return self.codes._update_codes(generated_content, is_testing, file_name)

@@ -271,8 +441,8 @@ def rewrite_codes(self) -> None:

self.dependency_graph = build_dependency_graph(self.env_dict['directory'])
print('self.dependency_graph', self.dependency_graph)
# print('self.dependency_graph', self.dependency_graph)
def get_high_overlap_code(self):
return self.codes._get_high_overlap_code()
def get_codes(self, ignore_test_code = True, simplify_code = False, only_test_code = False) -> str:
return self.codes._get_codes(ignore_test_code, simplify_code, only_test_code)
def get_codes(self, ignore_test_code = True, get_entry_point = False, simplify_code = False, only_test_code = False) -> str:
return self.codes._get_codes(ignore_test_code, get_entry_point, simplify_code, only_test_code)

@@ -284,4 +454,10 @@ def _load_from_hardware(self, directory) -> None:

if hasattr(self.codes, 'total_changed_lines'): return self.codes.total_changed_lines
def get_changed_codes(self, changed_files, _simplify_code = False) -> str:
return self.codes._get_changed_codes(changed_files, _simplify_code = _simplify_code)
def get_changed_files(self):
return self.codes._get_changed_files()
def get_all_changed_files(self):
return self.codes.all_changed_files
def reset_all_changed_files(self):
self.codes.all_changed_files = set()
def _update_requirements(self, generated_content):

@@ -333,13 +509,16 @@ self.requirements._update_docs(generated_content)

for regex in [r"(\w+.png)", r"(\w+.gif)"]:
joined_codes = self.get_codes()
matches = re.finditer(regex, joined_codes, re.DOTALL)
# matched_images = {}
for _code in self.codes.codebooks.values():
joined_codes = _code
matches = re.finditer(regex, joined_codes, re.DOTALL)
# matched_images = {}
for match in matches:
filename = match.group(1).strip()
if filename in self.proposed_images.keys():
self.incorporated_images[filename] = self.proposed_images[filename]
flag = True
else:
self.incorporated_images[filename] = filename.replace("_", " ")
for match in matches:
filename = match.group(1).strip()
if filename in self.proposed_images.keys():
self.incorporated_images[filename] = self.proposed_images[filename]
flag = True
else:
self.incorporated_images[filename] = filename.replace("_", " ")
self.context_images[filename] = _code

@@ -353,3 +532,3 @@ for filename in self.incorporated_images.keys():

{"role": "system", "content": "You are an experienced Art Prompt Engineer and working in the AgileCoder in the IT field. Your task is to write optimal prompts to feed to DALLE models to generate high-quality images needed for software."},
{"role": "user", "content": f"The user's task and our relevant code files are listed:\nTask: \"{self.env_dict['task_prompt']}\"\nCodes:\n\"{self.codes}\".\nAs a Prompt Engineer, you write a prompt to generate the image \"{filename}\" and you also make sure that the generated image has a suitable size and highly aligns with the user's task and existing source code.\nThen just output the prompt with the format:\nPrompt: PROMPT where PROMPT is the possible prompt."}
{"role": "user", "content": f"The user's task and our relevant code files are listed:\nTask: \"{self.env_dict['task_prompt']}\"\nCodes:\n\"{self.context_images[filename]}\".\nAs a Prompt Engineer, you write a prompt to generate the image \"{filename}\" and you also make sure that the generated image has a suitable size and highly aligns with the user's task and existing source code.\nThen just output the prompt with the format:\nPrompt: PROMPT where PROMPT is the possible prompt."}
])['choices'][0]["message"]["content"]

@@ -363,3 +542,3 @@ # log_and_print_online('*****************response', response)

image_url = response['data'][0]['url']
download(image_url, filename)
download(image_url, filename)
flag = True

@@ -404,3 +583,3 @@ return flag

{"role": "system", "content": "You are an experienced Prompt Engineer and working in a AgileCoder in the IT field. Your task is to write optimal prompts to feed to DALLE models to generate high-quality images needed for software."},
{"role": "user", "content": f"The user's task and our relevant code files are listed:\nTask: \"{self.env_dict['task_prompt']}\"\nCodes:\n\"{self.codes}\".\nAs a Prompt Engineer, you write a prompt to generate the image \"{filename}\" and you also make sure that the generated image has a suitable size and highly aligns with the user's task and existing source code.\nThen just output the prompt with the format:\nPrompt: PROMPT where PROMPT is the possible prompt."}
{"role": "user", "content": f"The user's task and our relevant code files are listed:\nTask: \"{self.env_dict['task_prompt']}\"\nCodes:\n\"{self.context_images[filename]}\".\nAs a Prompt Engineer, you write a prompt to generate the image \"{filename}\" and you also make sure that the generated image has a suitable size and highly aligns with the user's task and existing source code.\nThen just output the prompt with the format:\nPrompt: PROMPT where PROMPT is the possible prompt."}
])['choices'][0]["message"]["content"]

@@ -407,0 +586,0 @@ # log_and_print_online('*****************response', response)

@@ -5,2 +5,3 @@ import os

from nltk.translate.bleu_score import sentence_bleu
from codebleu import calc_codebleu
from agilecoder.components.utils import log_and_print_online

@@ -15,2 +16,7 @@ import difflib

return False
def check_the_same_file(name1, name2):
name1 = name1.split('.')[0].replace('_', '')
name2 = name2.split('.')[0].replace('_', '')
return name2 in name1
def extract_files(code_string):

@@ -72,4 +78,18 @@ """Extracts code and names for each file from the given string."""

return '\n'.join(outputs)
def has_entry_point(code):
try:
tree = ast.parse(code)
# Check for if __name__ == "__main__": condition
# Check for standalone code (no functions or classes)
for node in ast.iter_child_nodes(tree):
if not isinstance(node, (ast.Expr, ast.Import, ast.ImportFrom, ast.Module, ast.FunctionDef, ast.ClassDef)):
return True
return False
except SyntaxError:
return False
class Codes:

@@ -83,3 +103,3 @@ def __init__(self, generated_content="", is_testing = False):

self.is_testing = is_testing
self.all_changed_files = set()
def extract_filename_from_line(lines):

@@ -142,3 +162,7 @@ file_name = ""

for filename, file_code in self.codebooks.items():
scores.append((filename, formatted_code, sentence_bleu([formatted_code.split()], file_code.split())))
if filename.endswith('.py'):
_score = max(sentence_bleu([formatted_code.split()], file_code.split()), calc_codebleu([formatted_code], [file_code], lang = 'python')['codebleu'])
scores.append((filename, formatted_code, _score))
else:
scores.append((filename, formatted_code, sentence_bleu([formatted_code.split()], file_code.split())))
has_duplicated = False

@@ -152,2 +176,6 @@ if len(scores) > 0:

filename = extract_filename_from_code(code)
for _filename in self.codebooks:
if _filename.lower().replace('_', '') == filename:
filename = _filename
break
if filename is not None and filename != '.py' and formatted_code is not None and len(filename) > 0 and len(formatted_code) > 0:

@@ -208,3 +236,7 @@ self.codebooks[filename] = formatted_code

for _filename, file_code in self.codebooks.items():
scores.append((_filename, formatted_code, sentence_bleu([formatted_code.split()], file_code.split())))
if _filename.endswith('.py'):
_score = max(sentence_bleu([formatted_code.split()], file_code.split()), calc_codebleu([formatted_code], [file_code], lang = 'python')['codebleu'])
scores.append((_filename, formatted_code, _score))
else:
scores.append((_filename, formatted_code, sentence_bleu([formatted_code.split()], file_code.split())))
if len(scores) > 0:

@@ -253,3 +285,6 @@ scores = sorted(scores, key = lambda x: x[2], reverse = True)[0]

else: continue
s = sentence_bleu([filecode.split()], filecode1.split())
if filename.endswith('.py'):
s = max(calc_codebleu([filecode], [filecode1], lang = 'python')['codebleu'], sentence_bleu([filecode.split()], filecode1.split()))
else:
s = sentence_bleu([filecode.split()], filecode1.split())
if s > 0.6:

@@ -260,3 +295,3 @@ results[p] = s

def _update_codes(self, generated_content, is_testing):
def _update_codes(self, generated_content, is_testing, file_name):
new_codes = Codes(generated_content, is_testing)

@@ -267,4 +302,8 @@ # differ = difflib.Differ()

total_changed_lines = ''
changed_files = []
total_generated_line_num = len(list(filter(lambda x: len(x.strip()), generated_content.splitlines())))
for key in new_codes.codebooks.keys():
total_new_length += len(new_codes.codebooks[key])
if file_name is not None and not check_the_same_file(key, file_name): continue
total_new_length += len(new_codes.codebooks[key].splitlines())
corres_key = None

@@ -274,3 +313,7 @@ if key not in self.codebooks.keys():

for filename, file_code in self.codebooks.items():
scores.append((filename, sentence_bleu([new_codes.codebooks[key].split()], file_code.split())))
if filename.endswith('.py'):
_score = max(sentence_bleu([new_codes.codebooks[key].split()], file_code.split()), calc_codebleu([new_codes.codebooks[key]], [file_code], lang = 'python')['codebleu'])
scores.append((filename, _score))
else:
scores.append((filename, sentence_bleu([new_codes.codebooks[key].split()], file_code.split())))
if len(scores):

@@ -280,2 +323,6 @@ scores = sorted(scores, key = lambda x: x[1], reverse = True)[0]

corres_key = scores[0]
if corres_key is None:
for filename in self.codebooks:
if filename.lower().replace('_', '') == key:
corres_key = filename
if key not in self.codebooks.keys() or self.codebooks[key] != new_codes.codebooks[key]:

@@ -305,7 +352,16 @@ if is_testing:

self.codebooks[corres_key or key] = new_codes.codebooks[key]
changed_files.append(corres_key or key)
flag = True
self.total_changed_lines = total_changed_lines
return flag and (total_new_length / len(generated_content) > 0.7)
self.changed_files = changed_files
self.all_changed_files.update(self.changed_files)
# print('changed_files', changed_files)
return flag and (total_new_length / total_generated_line_num > 0.5)
# return hasattr(new_codes, 'has_correct_format') and new_codes.has_correct_format
def _get_changed_files(self):
if hasattr(self, 'changed_files'): return self.changed_files
return []
def _rewrite_codes(self, git_management) -> None:

@@ -321,3 +377,3 @@ directory = self.directory

for filename in self.codebooks.keys():
filepath = os.path.join(directory, filename)
filepath = os.path.join(directory, os.path.basename(filename))
with open(filepath, "w", encoding="utf-8") as writer:

@@ -335,8 +391,18 @@ writer.write(self.codebooks[filename])

def _get_codes(self, ignore_test_code, _simplify_code = False, only_test_code = False) -> str:
def _get_codes(self, ignore_test_code, get_entry_point = False, _simplify_code = False, only_test_code = False) -> str:
content = ""
print('self.testing_filenames', self.testing_filenames)
# print('self.testing_filenames', self.testing_filenames)
for filename in self.codebooks.keys():
if only_test_code and filename not in self.testing_filenames: continue
elif ignore_test_code and filename in self.testing_filenames: continue
if get_entry_point:
if has_entry_point(self.codebooks[filename]):
if ignore_test_code and (filename.startswith('test_') or filename.split('.')[0].endswith('_test')): continue
code = self.codebooks[filename]
if _simplify_code:
code = simplify_code(code)
content += "{}\n```{}\n{}\n```\n\n".format(filename,
"python" if filename.endswith(".py") else filename.split(".")[
-1], code)
continue
if only_test_code and not (filename.startswith('test_') or filename.split('.')[0].endswith('_test')): continue
elif ignore_test_code and (filename.startswith('test_') or filename.split('.')[0].endswith('_test')): continue
code = self.codebooks[filename]

@@ -350,2 +416,14 @@ if _simplify_code:

def _get_changed_codes(self, changed_files, _simplify_code = False) -> str:
content = ""
for filename in self.codebooks.keys():
if filename not in changed_files: continue
code = self.codebooks[filename]
if _simplify_code:
code = simplify_code(code)
content += "{}\n```{}\n{}\n```\n\n".format(filename,
"python" if filename.endswith(".py") else filename.split(".")[
-1], code)
return content
def _load_from_hardware(self, directory) -> None:

@@ -352,0 +430,0 @@ assert len([filename for filename in os.listdir(directory) if filename.endswith(".py")]) > 0

@@ -5,8 +5,9 @@ import importlib

from collections import defaultdict
import copy
import concurrent.futures
from agilecoder.camel.typing import ModelType
from agilecoder.components.chat_env import ChatEnv
from agilecoder.components.utils import log_and_print_online
from agilecoder.components.utils import log_and_print_online, find_ancestors
from copy import deepcopy
def check_bool(s):

@@ -153,10 +154,13 @@ return s.lower() == "true"

if phase in ['ProductBacklogModification', 'SprintBacklogModification', 'SprintReview']:
while True:
if phase in ['ProductBacklogModification', 'SprintBacklogModification', 'SprintReview', 'NextSprintBacklogCreating']:
for i in range(3):
try:
chat_env = self.phases[phase].execute(chat_env,
_chat_env = copy.deepcopy(chat_env)
_chat_env = self.phases[phase].execute(_chat_env,
self.chat_turn_limit_default if max_turn_step <= 0 else max_turn_step,
need_reflect)
chat_env = _chat_env
break
except: pass
except:
pass
else:

@@ -207,4 +211,5 @@ chat_env = self.phases[phase].execute(chat_env,

def break_cycle(self, chat_env) -> bool:
return False
def break_cycle(self, phase_env) -> bool:
return 'Finished.' == phase_env.get('product_backlog_comments', '')

@@ -272,3 +277,3 @@ class SprintCompletion(ComposedPhase):

def break_cycle(self, chat_env) -> bool:
def break_cycle(self, phase_env) -> bool:
return False

@@ -287,6 +292,5 @@

def break_cycle(self, phase_env) -> bool:
if "<INFO> Finished".lower() in phase_env['modification_conclusion'].lower():
return True
else:
return False
if phase_env.get('has_no_comment', False): return True
if len(phase_env['changed_files']) == 0: return True
return False

@@ -304,6 +308,3 @@ class SprintBacklogUpdate(ComposedPhase):

def break_cycle(self, phase_env) -> bool:
if "<INFO> Finished".lower() in phase_env['modification_conclusion'].lower():
return True
else:
return False
return "Finished." == phase_env.get('sprint_backlog_comments', '')

@@ -344,2 +345,78 @@

return False
def execute(self, chat_env) -> ChatEnv:
"""
similar to Phase.execute, but add control for breaking the loop
1. receive information from environment(ComposedPhase): update the phase environment from global environment
2. for each SimplePhase in ComposedPhase
a) receive information from environment(SimplePhase)
b) check loop break
c) execute the chatting
d) change the environment(SimplePhase)
e) check loop break
3. change the environment(ComposedPhase): update the global environment using the conclusion
Args:
chat_env: global chat chain environment
Returns:
"""
self.update_phase_env(chat_env)
for cycle_index in range(self.cycle_num):
for phase_item in self.composition:
if phase_item["phaseType"] == "SimplePhase": # right now we do not support nested composition
phase = phase_item['phase']
max_turn_step = phase_item['max_turn_step']
need_reflect = check_bool(phase_item['need_reflect'])
log_and_print_online(
f"**[Execute Detail]**\n\nexecute SimplePhase:[{phase}] in ComposedPhase:[{self.phase_name}], cycle {cycle_index}")
if phase in self.phases:
self.phases[phase].phase_env = self.phase_env
self.phases[phase].update_phase_env(chat_env)
if self.break_cycle(self.phases[phase].phase_env):
return chat_env
counter = 0
while not self.break_cycle(self.phases[phase].phase_env) and counter < 3:
log_and_print_online('TEST FORMAT COUNTER: ' + str(counter))
_chat_env = copy.deepcopy(chat_env)
try:
_chat_env = self.phases[phase].execute(_chat_env,
self.chat_turn_limit_default if max_turn_step <= 0 else max_turn_step,
need_reflect)
except:
pass
counter += 1
chat_env = _chat_env
# print('@' * 20)
# print('self.phases[phase].phase_env', self.phases[phase].phase_env)
if self.break_cycle(self.phases[phase].phase_env):
return chat_env
# chat_env = self.phases[phase].update_chat_env(chat_env)
if chat_env.env_dict.get('end-sprint', False):
return chat_env
else:
print(f"Phase '{phase}' is not yet implemented. \
Please write its config in phaseConfig.json \
and implement it in components.phase")
elif phase_item['phaseType'] == 'ComposedPhase':
phase = phase_item['phase']
cycle_num = phase_item['cycleNum']
composition = phase_item['Composition']
compose_phase_class = getattr(self.compose_phase_module, phase)
compose_phase_instance = compose_phase_class(phase_name=phase,
cycle_num=cycle_num,
composition=composition,
config_phase=self.config_phase,
config_role=self.config_role,
model_type=self.model_type,
log_filepath=self.log_filepath)
chat_env = compose_phase_instance.execute(chat_env)
else:
raise NotImplementedError
chat_env = self.update_chat_env(chat_env)
return chat_env
class BugFixing(ComposedPhase):

@@ -378,2 +455,4 @@ def __init__(self, **kwargs):

for phase_item in self.composition:
log_and_print_online("BUGFIXING:" + str(phase_item))
# print("BUGFIXING:", phase_item)
if phase_item["phaseType"] == "SimplePhase": # right now we do not support nested composition

@@ -387,13 +466,14 @@ phase = phase_item['phase']

self.phases[phase].phase_env = self.phase_env
self.phases[phase].update_phase_env(chat_env)
if self.break_cycle(self.phases[phase].phase_env):
return chat_env
if phase_item['phase'] != 'TestErrorSummary':
self.phases[phase].update_phase_env(chat_env)
chat_env = self.phases[phase].execute(chat_env,
self.chat_turn_limit_default if max_turn_step <= 0 else max_turn_step,
need_reflect)
log_and_print_online("chat_env.env_dict['test_reports']: " + chat_env.env_dict['test_reports'])
if chat_env.env_dict['test_reports'] == 'The software run successfully without errors.':
break
# print('@' * 20)
# print('self.phases[phase].phase_env', self.phases[phase].phase_env)
if self.break_cycle(self.phases[phase].phase_env):
return chat_env
# chat_env = self.phases[phase].update_chat_env(chat_env)

@@ -425,2 +505,105 @@ if chat_env.env_dict.get('end-sprint', False):

return chat_env
def write_a_single_instance(phase, chat_env, turn_limit, need_reflect):
return phase.phase_env['current_file_name'], phase.execute(chat_env, turn_limit, need_reflect)
class WritingFullTestSuite(ComposedPhase):
def __init__(self, **kwargs):
super().__init__(**kwargs)
def update_phase_env(self, chat_env):
self.phase_env = dict()
def update_chat_env(self, chat_env):
return chat_env
def break_cycle(self, phase_env) -> bool:
return False
def execute(self, chat_env) -> ChatEnv:
"""
similar to Phase.execute, but add control for breaking the loop
1. receive information from environment(ComposedPhase): update the phase environment from global environment
2. for each SimplePhase in ComposedPhase
a) receive information from environment(SimplePhase)
b) check loop break
c) execute the chatting
d) change the environment(SimplePhase)
e) check loop break
3. change the environment(ComposedPhase): update the global environment using the conclusion
Args:
chat_env: global chat chain environment
Returns:
"""
self.update_phase_env(chat_env)
all_changed_files = find_ancestors(chat_env.dependency_graph, deepcopy(list(chat_env.get_all_changed_files())))
if len(all_changed_files) == 0: return chat_env
futures = []
max_workers = min(len(all_changed_files), 5)
with concurrent.futures.ThreadPoolExecutor(max_workers = max_workers) as executor:
for file_name in all_changed_files:
if file_name.startswith('test_') or file_name.split('.')[0].endswith('_test'): continue
for phase_item in self.composition:
if phase_item["phaseType"] == "SimplePhase": # right now we do not support nested composition
phase = phase_item['phase']
max_turn_step = phase_item['max_turn_step']
need_reflect = check_bool(phase_item['need_reflect'])
log_and_print_online(
f"**[Execute Detail]**\n\nexecute SimplePhase:[{phase}] in ComposedPhase:[{self.phase_name}]")
if phase in self.phases:
untested_code = chat_env.get_changed_codes([file_name], True)
code_dependencies = chat_env.get_changed_codes(chat_env.dependency_graph.get(file_name, []), True)
_phase = deepcopy(self.phases[phase])
_phase.phase_env.update({
'code_dependencies': code_dependencies,
'untested_code': untested_code,
'current_file_name': file_name
})
futures.append(executor.submit(write_a_single_instance, _phase, deepcopy(chat_env), self.chat_turn_limit_default if max_turn_step <= 0 else max_turn_step, need_reflect))
# chat_env = self.phases[phase].execute(chat_env,
# self.chat_turn_limit_default if max_turn_step <= 0 else max_turn_step,
# need_reflect)
# print('@' * 20)
# print('self.phases[phase].phase_env', self.phases[phase].phase_env)
# chat_env = self.phases[phase].update_chat_env(chat_env)
else:
print(f"Phase '{phase}' is not yet implemented. \
Please write its config in phaseConfig.json \
and implement it in components.phase")
elif phase_item['phaseType'] == 'ComposedPhase':
phase = phase_item['phase']
cycle_num = phase_item['cycleNum']
composition = phase_item['Composition']
compose_phase_class = getattr(self.compose_phase_module, phase)
compose_phase_instance = compose_phase_class(phase_name=phase,
cycle_num=cycle_num,
composition=composition,
config_phase=self.config_phase,
config_role=self.config_role,
model_type=self.model_type,
log_filepath=self.log_filepath)
chat_env = compose_phase_instance.execute(chat_env)
else:
raise NotImplementedError
results = []
for future in concurrent.futures.as_completed(futures):
results.append(future.result())
testing_file_map = {}
for filename, result in results:
_files = set(filter(lambda x: x.startswith('test') or x.split('.')[0].endswith('test'), result.get_changed_files()))
if len(_files):
testing_file_map[filename] = list(_files)
# print('[FILENAME]:', filename, result.codes.codebooks.keys())
chat_env.codes.codebooks.update(result.codes.codebooks)
chat_env.rewrite_codes()
for key, value in testing_file_map.items():
chat_env.testing_file_map[key] = chat_env.testing_file_map.get(key, []) + value
chat_env = self.update_chat_env(chat_env)
return chat_env

@@ -5,2 +5,3 @@ import html

import time
from collections import defaultdict

@@ -113,1 +114,129 @@ import markdown

return wrapper
def extract_product_requirements(input, is_product = True):
lines = input.splitlines()
if is_product:
keyword1 = 'product backlog'
keyword2 = 'acceptance criteria'
else:
keyword1 = 'sprint backlog'
keyword2 = 'sprint acceptance criteria'
backlog, acceptance_criteria = [], []
backlog_flag, criteria_flag = False, False
for line in lines:
_line = line.replace("_", ' ').lower()
if keyword1 in _line:
backlog_flag = True
criteria_flag = False
continue
if keyword2 in _line:
backlog_flag = False
criteria_flag = True
continue
if backlog_flag:
backlog.append(line)
if criteria_flag:
acceptance_criteria.append(line)
if len(backlog) and len(acceptance_criteria) and len(_line.strip()) == 0: break
return '\n'.join(backlog), '\n'.join(acceptance_criteria)
def get_non_leaf_and_intermediate_files(adj_list):
if adj_list is None: return []
all_deps = []
for node, deps in adj_list.items():
if node.startswith('test_') or node.split('.')[0].endswith('_test'): continue
all_deps.extend(deps)
all_nodes = set()
for k, v in adj_list.items():
all_nodes.update(v + [k])
return [node for node in all_nodes if node not in all_deps and not (node.startswith('test_') or node.split('.')[0].endswith('_test'))]
def extract_first_error_traceback(traceback_output, num_returns = 3):
# Split the traceback output into lines
traceback_lines = traceback_output.splitlines()
# Iterate through the lines to find the first failed test case traceback
first_error_traceback = []
found_failure = False
count = 0
for line in traceback_lines:
# print('LINE', line)
if line.startswith("FAIL:") or line.startswith("ERROR:"):
found_failure = True#len(first_error_traceback) == 0
# print('line', line)
if found_failure and count < num_returns:
first_error_traceback.append(line)
count += 1
elif found_failure and count <= num_returns:
# Append subsequent lines until the next test case starts
if line.startswith("Ran "):
break
# print('line1', line)
first_error_traceback.append(line)
# Join the lines to form the complete traceback
return '\n'.join(first_error_traceback)
def extract_top_k_errors(content, k = 1):
lines = content.splitlines()
results = []
start_flag = False
count = 0
for line in lines:
if 'FAILURES' in line:
start_flag = True
if start_flag and len(results) == 0:
results.append(line)
continue
if line.startswith('_______________'):
count += 1
if start_flag and count <= k:
results.append(line)
return '\n'.join(results)
def _build_reverse_adjacency_list(adj_list):
reverse_adj_list = defaultdict(list)
for child, parents in adj_list.items():
for parent in parents:
reverse_adj_list[parent].append(child)
return reverse_adj_list
def find_ancestors(adj_list, start_nodes):
if adj_list is None: return []
reverse_adj_list = _build_reverse_adjacency_list(adj_list)
ancestors = set()
for start_node in start_nodes:
stack = [start_node]
while stack:
node = stack.pop()
if node in ancestors:
continue
ancestors.add(node)
stack.extend(reverse_adj_list[node])
return ancestors
def extract_function_from_class(file_content, function_names):
tree = ast.parse(file_content)
lines = file_content.splitlines()
class_code = []
for line in lines:
if line.strip().startswith('def'): break
class_code.append(line)
function_code_lines = []
for function_name in function_names:
if function_name == '<module>': return file_content
function_code = None
for node in tree.body:
if isinstance(node, ast.ClassDef):
for class_node in node.body:
if isinstance(class_node, ast.FunctionDef) and class_node.name == function_name:
function_code = ast.get_source_segment(file_content, class_node)
break
if function_code is None: return file_content
function_code_lines.extend(function_code.splitlines())
results = class_code + function_code_lines
return '\n'.join(results)

@@ -75,4 +75,5 @@ import logging

os.makedirs(warehouse_path, exist_ok = True)
args2type = {'GPT_3_5_TURBO': ModelType.GPT_3_5_TURBO, 'GPT_4': ModelType.GPT_4, 'GPT_4_32K': ModelType.GPT_4_32k, 'GPT_3_5_AZURE': ModelType.GPT_3_5_AZURE}
chat_chain = ChatChain(config_path=config_path,
args2type = {'GPT_3_5_TURBO': ModelType.GPT_3_5_TURBO, 'GPT_4': ModelType.GPT_4, 'GPT_4_32K': ModelType.GPT_4_32k, 'GPT_3_5_AZURE': ModelType.GPT_3_5_AZURE, 'CLAUDE': ModelType.CLAUDE, 'ANTHROPIC_CLAUDE': ModelType.ANTHROPIC_CLAUDE}
chat_chain = ChatChain(args.max_num_sprints,
config_path=config_path,
config_phase_path=config_phase_path,

@@ -113,3 +114,3 @@ config_role_path=config_role_path,

# ----------------------------------------
print('CHAINNNNNNN')
# print('CHAINNNNNNN')
chat_chain.execute_chain()

@@ -116,0 +117,0 @@

@@ -223,3 +223,3 @@ import os

self.codebooks[key] = new_codes.codebooks[key]
print('self.codebooks', self.codebooks)
# print('self.codebooks', self.codebooks)

@@ -226,0 +226,0 @@ def _rewrite_codes(self, git_management) -> None:

Metadata-Version: 2.1
Name: agilecoder
Version: 0.1.5
Version: 0.1.6
Summary: AgileCoder

@@ -9,6 +9,14 @@ Home-page: https://github.com/FSoft-AI4Code/AgileCoder

License: Apache-2.0
Platform: UNKNOWN
Requires-Python: >=3.8
UNKNOWN
Requires-Dist: openai==0.28.1
Requires-Dist: tiktoken
Requires-Dist: markdown
Requires-Dist: colorama
Requires-Dist: nltk
Requires-Dist: tenacity
Requires-Dist: python-dotenv
Requires-Dist: codebleu
Requires-Dist: google-auth
Requires-Dist: google-auth-oauthlib
Requires-Dist: google-auth-httplib2
Requires-Dist: anthropic
from setuptools import setup, find_packages
setup(name='agilecoder',
version='0.1.5',
version='0.1.6',
description='AgileCoder',

@@ -22,5 +22,10 @@ url='https://github.com/FSoft-AI4Code/AgileCoder',

"tenacity",
"python-dotenv"
"python-dotenv",
"codebleu",
"google-auth",
"google-auth-oauthlib",
"google-auth-httplib2",
"anthropic"
],
packages=find_packages(),
zip_safe=False)

Sorry, the diff of this file is too big to display