peichao.dong commited on
Commit
7a27b40
1 Parent(s): a72034e

refactor code generate tools

Browse files
.gitignore CHANGED
@@ -1,2 +1,3 @@
1
  __pycache__/*
 
2
  .DS_Store
 
1
  __pycache__/*
2
+ **/__pycache__/*
3
  .DS_Store
README.md CHANGED
@@ -11,3 +11,18 @@ license: apache-2.0
11
  ---
12
 
13
  Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
11
  ---
12
 
13
  Check out the configuration reference at https://huggingface.co/docs/hub/spaces-config-reference
14
+
15
+ ## 环境依赖
16
+ python3
17
+
18
+ ## 安装依赖
19
+
20
+ ```shell
21
+ pip install -r requirments
22
+ ```
23
+
24
+ ## 运行命令
25
+
26
+ ```shell
27
+ python -m app.py
28
+ ```
code_generate.py → agents/code_generate_agent.py RENAMED
@@ -2,42 +2,14 @@ import re
2
  from typing import List, Union
3
  from langchain.chains import LLMChain
4
  from langchain.chat_models import ChatOpenAI
5
- from langchain.agents import tool, Tool, LLMSingleActionAgent, AgentExecutor, AgentOutputParser
6
  from langchain.schema import AgentAction, AgentFinish
7
  from langchain.agents import initialize_agent
8
- from langchain.memory import ConversationBufferMemory
9
  from langchain.prompts import StringPromptTemplate
10
  from promopts import code_generate_agent_template
11
-
12
-
13
-
14
-
15
- from promopts import API_LAYER_PROMPT, DOMAIN_LAYER_PROMPT, PERSISTENT_LAYER_PROMPT
16
-
17
- domainLayerChain = LLMChain(llm = ChatOpenAI(temperature=0.1), prompt=DOMAIN_LAYER_PROMPT)
18
-
19
- persistentChain = LLMChain(llm = ChatOpenAI(temperature=0.1), prompt=PERSISTENT_LAYER_PROMPT)
20
-
21
- apiChain = LLMChain(llm = ChatOpenAI(temperature=0.1), prompt=API_LAYER_PROMPT)
22
-
23
- @tool("Generate Domain Layer Code", return_direct=True)
24
- def domainLayerCodeGenerator(input: str) -> str:
25
- '''useful for when you need to generate domain layer code'''
26
- response = domainLayerChain.run(input)
27
- return response
28
-
29
- @tool("Generate Persistent Layer Code", return_direct=True)
30
- def persistentLayerCodeGenerator(input: str) -> str:
31
- '''useful for when you need to generate persistent layer code'''
32
- response = persistentChain.run(input)
33
- return response
34
-
35
- @tool("Generate API Layer Code", return_direct=True)
36
- def apiLayerCodeGenerator(input: str) -> str:
37
- '''useful for when you need to generate API layer code'''
38
- response = apiChain.run(input)
39
- return response
40
-
41
 
42
 
43
  class CustomPromptTemplate(StringPromptTemplate):
@@ -94,19 +66,13 @@ class CustomOutputParser(AgentOutputParser):
94
 
95
  # agent = initialize_agent(
96
  # tools=tools, llm=llm_chain, template=AGENT_PROMPT, stop=["\nObservation:"], agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=True)
97
- tools = [domainLayerCodeGenerator, persistentLayerCodeGenerator, apiLayerCodeGenerator]
98
-
99
 
100
  def code_agent_executor() -> AgentExecutor:
101
-
102
-
103
-
104
  output_parser = CustomOutputParser()
105
-
106
-
107
  AGENT_PROMPT = CustomPromptTemplate(
108
  template=code_generate_agent_template,
109
- tools=tools,
110
  # This omits the `agent_scratchpad`, `tools`, and `tool_names` variables because those are generated dynamically
111
  # This includes the `intermediate_steps` variable because that is needed
112
  input_variables=["input", "intermediate_steps"]
@@ -114,7 +80,7 @@ def code_agent_executor() -> AgentExecutor:
114
 
115
  code_llm_chain = LLMChain(llm=ChatOpenAI(temperature=0.7), prompt=AGENT_PROMPT)
116
 
117
- tool_names = [tool.name for tool in tools]
118
  code_agent = LLMSingleActionAgent(
119
  llm_chain=code_llm_chain,
120
  output_parser=output_parser,
@@ -123,7 +89,7 @@ def code_agent_executor() -> AgentExecutor:
123
  )
124
 
125
  code_agent_executor = AgentExecutor.from_agent_and_tools(
126
- agent=code_agent, tools=tools, verbose=True)
127
  return code_agent_executor
128
 
129
  # if __name__ == "__main__":
 
2
  from typing import List, Union
3
  from langchain.chains import LLMChain
4
  from langchain.chat_models import ChatOpenAI
5
+ from langchain.agents import Tool, LLMSingleActionAgent, AgentExecutor, AgentOutputParser
6
  from langchain.schema import AgentAction, AgentFinish
7
  from langchain.agents import initialize_agent
 
8
  from langchain.prompts import StringPromptTemplate
9
  from promopts import code_generate_agent_template
10
+ from agents.tools.api_layer_code_tool import apiLayerCodeGenerator
11
+ from agents.tools.domain_layer_code_tool import domainLayerCodeGenerator
12
+ from agents.tools.persistent_layer_code_tool import persistentLayerCodeGenerator
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13
 
14
 
15
  class CustomPromptTemplate(StringPromptTemplate):
 
66
 
67
  # agent = initialize_agent(
68
  # tools=tools, llm=llm_chain, template=AGENT_PROMPT, stop=["\nObservation:"], agent=AgentType.ZERO_SHOT_REACT_DESCRIPTION, verbose=True)
69
+ code_agent_tools = [domainLayerCodeGenerator, persistentLayerCodeGenerator, apiLayerCodeGenerator]
 
70
 
71
  def code_agent_executor() -> AgentExecutor:
 
 
 
72
  output_parser = CustomOutputParser()
 
 
73
  AGENT_PROMPT = CustomPromptTemplate(
74
  template=code_generate_agent_template,
75
+ tools=code_agent_tools,
76
  # This omits the `agent_scratchpad`, `tools`, and `tool_names` variables because those are generated dynamically
77
  # This includes the `intermediate_steps` variable because that is needed
78
  input_variables=["input", "intermediate_steps"]
 
80
 
81
  code_llm_chain = LLMChain(llm=ChatOpenAI(temperature=0.7), prompt=AGENT_PROMPT)
82
 
83
+ tool_names = [tool.name for tool in code_agent_tools]
84
  code_agent = LLMSingleActionAgent(
85
  llm_chain=code_llm_chain,
86
  output_parser=output_parser,
 
89
  )
90
 
91
  code_agent_executor = AgentExecutor.from_agent_and_tools(
92
+ agent=code_agent, tools=code_agent_tools, verbose=True)
93
  return code_agent_executor
94
 
95
  # if __name__ == "__main__":
agents/tools/api_layer_code_tool.py ADDED
@@ -0,0 +1,95 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from langchain import LLMChain, PromptTemplate
2
+ from langchain.chat_models import ChatOpenAI
3
+ from langchain.agents import tool
4
+
5
+
6
+ API_LAYER = """You are a software developer. Your task is to generate the api layer tests and product code.
7
+
8
+ ===TechStack
9
+ Java17、reactor、lombok、Junit5、reactor test、Mockito、 Spring WebFlux、Spring Boot Test
10
+ ===END OF TechStack
11
+
12
+ ===Architecture
13
+ the api layer inclue 2 componets:
14
+ * DTO: This component is use to define data structure that api request and response.
15
+ * Controller: This component is use to define the interface to access api.
16
+ ---eaxmple code:
17
+ @RestController
18
+ @RequiredArgsConstructor
19
+ @RequestMapping("/features")
20
+ public class FeatureController {{
21
+ private final Features features;
22
+
23
+ @GetMapping()
24
+ public Flux<Feature> findAll() {{
25
+ return features.getAll();
26
+ }}
27
+
28
+ @PostMapping()
29
+ public Mono<Feature> add(@RequestBody Feature feature) {{
30
+ return features.add(feature);
31
+ }}
32
+ }}
33
+ ---end of eaxmple code
34
+ ===END OF Architecture
35
+
36
+ ===TestStrategy
37
+ For the Controller and DTO, we can write component test to test the actual implementation of api operations, test class rely on Association interface use WebFluxTest and WebTestClient ability.
38
+ ---eaxmple code:
39
+ @ExtendWith(SpringExtension.class)
40
+ @WebFluxTest(value = FeatureFlagApi.class, properties = "spring.main.lazy-initialization=true")
41
+ @ContextConfiguration(classes = TestConfiguration.class)
42
+ class FeatureControllerTest extends ControllerTestBase {{
43
+ @Autowired
44
+ WebTestClient webClient;
45
+
46
+ @MockBean
47
+ Features features;
48
+
49
+ @Test
50
+ void should_getAll_success_when_no_records() {{
51
+ when(features.getAll(Mockito.any())).thenReturn(Flux.empty());
52
+
53
+ webClient.get()
54
+ .uri("/features")
55
+ .exchange()
56
+ .expectStatus()
57
+ .isOk()
58
+ .expectBodyList(FeatureFlagResponse.class)
59
+ .hasSize(0);
60
+ }}
61
+ }}
62
+ ---end of eaxmple code
63
+ ===END OF TestStrategy
64
+
65
+ Use the following format:
66
+ request: the request that you need to fulfill include Entity and Association of domain layer
67
+
68
+ DTO:
69
+ ```
70
+ the DTO code that you write to fulfill the request, follow TechStack and Architecture
71
+ ```
72
+
73
+ Controller:
74
+ ```
75
+ the Controller code that you write to fulfill the request, follow TechStack and Architecture
76
+ ```
77
+
78
+ Test:
79
+ ```
80
+ the test code that you write to fulfill the request, follow TechStack Architecture and TestStrategy
81
+ ```
82
+
83
+ request: {input}"""
84
+
85
+ API_LAYER_PROMPT = PromptTemplate(input_variables=["input"], template=API_LAYER,)
86
+
87
+
88
+ apiChain = LLMChain(llm = ChatOpenAI(temperature=0.1), prompt=API_LAYER_PROMPT)
89
+
90
+
91
+ @tool("Generate API Layer Code", return_direct=True)
92
+ def apiLayerCodeGenerator(input: str) -> str:
93
+ '''useful for when you need to generate API layer code'''
94
+ response = apiChain.run(input)
95
+ return response
agents/tools/domain_layer_code_tool.py ADDED
@@ -0,0 +1,85 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from langchain import LLMChain, PromptTemplate
2
+ from langchain.chat_models import ChatOpenAI
3
+ from langchain.agents import tool
4
+
5
+
6
+ DOMAIN_LAYER = """You are a software developer. Your task is to generate the domain layer tests and product code.
7
+
8
+ ===TechStack
9
+ Java17、reactor、lombok、Junit5、reactor test、Mockito
10
+ ===END OF TechStack
11
+
12
+ ===Architecture
13
+ the domain layer inclue 2 componets:
14
+ * Entity: This component is use to represents business concepts and encapsulates business rules.
15
+ ---eaxmple code:
16
+ public class Feature {{
17
+ private FeatureId id;
18
+ private FeatureDescription description;
19
+
20
+ public record FeatureId(String featureKey) {{
21
+
22
+ }}
23
+
24
+ @Builder
25
+ public record FeatureDescription(String name, String description, Boolean isEnable))) {{
26
+
27
+ }}
28
+ }}
29
+ ---end of eaxmple code
30
+ * Association: This component is use to define association between entities, which can represents the concept of a set of entity.
31
+ ---eaxmple code:
32
+ public interface Features {{
33
+ Flux<Feature> findAll();
34
+
35
+ Mono<Feature> findById(FeatureId id);
36
+
37
+ Mono<Feature> save(Feature feature);
38
+
39
+ Mono<Void> update(FeatureId id, FeatureDescription description);
40
+
41
+ Mono<Void> delete(FeatureId id);
42
+
43
+ Mono<Void> publish(FeatureId id);
44
+
45
+ Mono<Void> disable(FeatureId id);
46
+ }}
47
+ ---end of eaxmple code
48
+ ===END OF Architecture
49
+
50
+ ===TestStrategy
51
+ For the Entity, we can write unit test to ensure that the business rules related to Merchandise are correctly encapsulated.
52
+ For the Association,do not write tests because it is has no impletation.
53
+ ===END OF TestStrategy
54
+
55
+ Use the following format:
56
+ request: the request that you need to fulfill
57
+
58
+ Entity:
59
+ ```
60
+ the Entity code that you write to fulfill the request, follow TechStack and Architecture
61
+ ```
62
+
63
+ Association:
64
+ ```
65
+ the Association code that you write to fulfill the request, follow TechStack and Architecture
66
+ ```
67
+
68
+ Test:
69
+ ```
70
+ the test code that you write to fulfill the request, follow TechStack Architecture and TestStrategy
71
+ ```
72
+
73
+ request: {input}"""
74
+
75
+
76
+ DOMAIN_LAYER_PROMPT = PromptTemplate(input_variables=["input"], template=DOMAIN_LAYER,)
77
+
78
+ domainLayerChain = LLMChain(llm = ChatOpenAI(temperature=0.1), prompt=DOMAIN_LAYER_PROMPT)
79
+
80
+
81
+ @tool("Generate Domain Layer Code", return_direct=True)
82
+ def domainLayerCodeGenerator(input: str) -> str:
83
+ '''useful for when you need to generate domain layer code'''
84
+ response = domainLayerChain.run(input)
85
+ return response
agents/tools/persistent_layer_code_tool.py ADDED
@@ -0,0 +1,172 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ from langchain import LLMChain, PromptTemplate
2
+ from langchain.chat_models import ChatOpenAI
3
+ from langchain.agents import tool
4
+
5
+
6
+ PERSISTENT_LAYER = """You are a software developer. Your task is to generate the persistent layer tests and product code.
7
+
8
+ ===TechStack
9
+ Java17、reactor、lombok、Junit5、reactor test、Mockito、 Spring Data Reactive Couchbase、Testcontainers、Couchbase、WebClient
10
+ ===END OF TechStack
11
+
12
+ ===Architecture
13
+ the persistent layer inclue 3 componets:
14
+ * DbEntity: This component is use to define data structure that save to DB.
15
+ ---eaxmple code:
16
+ @Document
17
+ public class FeatureDb {{
18
+ @Version
19
+ private long version;
20
+
21
+ @Id
22
+ @GeneratedValue(strategy = GenerationStrategy.UNIQUE)
23
+ private String id;
24
+
25
+ private String featureKey;
26
+
27
+ private Feature.FeatureDescription description;
28
+ }}
29
+ ---end of eaxmple code
30
+ * Repository: This component is use to define the interface to access DB.
31
+ ---eaxmple code:
32
+ public interface FeatureDbRepository extends ReactiveCrudRepository<FeatureDb, String> {{
33
+ Mono<FeatureDb> findByFeatureKey(String featureKey);
34
+ }}
35
+ ---end of eaxmple code
36
+ * Association Impletation: This component provide implementation of Association of domain layer, rely on Repository.
37
+ ---eaxmple code:
38
+ @Component
39
+ @RequiredArgsConstructor
40
+ public class FeaturesImpl implements Features{{
41
+ private final FeatureDbRepository featureDbRepository;
42
+
43
+ Flux<Feature> findAll() {{
44
+ return featureDbRepository.findAll().map(FeatureDb::toFeature);
45
+ }}
46
+
47
+ Mono<Feature> save(Feature feature) {{
48
+ return featureDbRepository.save(FeatureDb.fromFeature(feature)).map(FeatureDb::toFeature);
49
+ }}
50
+ }}
51
+ ---end of eaxmple code
52
+ ===END OF Architecture
53
+
54
+ ===TestStrategy
55
+ For the DbEntity And Repository, we can write component test to test the actual implementation of database operations, test class should extends RepositoryTestBase to use Testcontainers ability.
56
+ ---eaxmple code:
57
+ class FeatureDbRepositoryTest extends RepositoryTestBase {{
58
+ @Autowired
59
+ FeatureDbRepository repository;
60
+
61
+ @BeforeEach
62
+ void setUp() {{
63
+ repository.deleteAll().block();
64
+ }}
65
+
66
+ @AfterEach
67
+ void tearDown() {{
68
+ repository.deleteAll().block();
69
+ }}
70
+
71
+ @Test
72
+ void should_save_Feature_success() {{
73
+ var featureKey = "featureKey1";
74
+ repository.save(FeatureTestUtil.createFeatureDb(featureKey))
75
+ .as(StepVerifier::create)
76
+ .expectNextCount(1)
77
+ .verifyComplete();
78
+ }}
79
+
80
+ @Test
81
+ void should_add_same_featureKey_fail() {{
82
+ var featureKey = "featureKey1";
83
+ repository.save(FeatureTestUtil.createFeatureDb(featureKey)).block();
84
+
85
+ repository.save(FeatureTestUtil.createFeatureDb(featureKey))
86
+ .as(StepVerifier::create)
87
+ .expectError()
88
+ .verify();
89
+ }}
90
+ }}
91
+ ---end of eaxmple code
92
+ For Association Impletation,we writ unit test, and stub repository method with Mockito.
93
+ ---eaxmple code:
94
+ @ExtendWith(MockitoExtension.class)
95
+ class FeatureImplTest {{
96
+ @Mock
97
+ FeatureDbRepository repository;
98
+
99
+ Features features;
100
+
101
+ @BeforeEach
102
+ void setUp() {{
103
+ features = new FeaturesImpl(repository);
104
+ }}
105
+
106
+ @Test
107
+ void should_add_success() {{
108
+ when(repository.save(any(FeatureDb.class))).thenAnswer(invocation -> {{
109
+ FeatureDb featureDb = invocation.getArgument(0);
110
+ return Mono.just(featureDb);
111
+ }});
112
+
113
+ features.add(createFeature("featureKey1"))
114
+ .as(StepVerifier::create)
115
+ .expectNextMatches(config -> config.getId().featureKey().equals("featureKey1")
116
+ && config.getDescription().updatedAt() != null
117
+ && config.getDescription().createdAt() != null
118
+ )
119
+ .verifyComplete();
120
+ }}
121
+
122
+ @Test
123
+ void should_add_return_error_when_repository_save_error() {{
124
+ Feature feature = createFeature("featureKey1");
125
+
126
+ when(repository.save(any(FeatureDb.class))).thenReturn(Mono.error(new DuplicateKeyException("save error")));
127
+
128
+ features.add(feature)
129
+ .as(StepVerifier::create)
130
+ .expectError()
131
+ .verify();
132
+ }}
133
+ }}
134
+
135
+
136
+ ===END OF TestStrategy
137
+
138
+ Use the following format:
139
+ request: the request that you need to fulfill include Entity and Association of domain layer
140
+
141
+ DBEntity:
142
+ ```
143
+ the DBEntity code that you write to fulfill the request, follow TechStack and Architecture
144
+ ```
145
+
146
+ Repository:
147
+ ```
148
+ the Repository code that you write to fulfill the request, follow TechStack and Architecture
149
+ ```
150
+
151
+ Association Impletation:
152
+ ```
153
+ the Association Impletation code that you write to fulfill the request, follow TechStack and Architecture
154
+ ```
155
+
156
+ Test:
157
+ ```
158
+ the test code that you write to fulfill the request, follow TechStack Architecture and TestStrategy
159
+ ```
160
+
161
+ request: {input}"""
162
+
163
+ PERSISTENT_LAYER_PROMPT = PromptTemplate(input_variables=["input"], template=PERSISTENT_LAYER,)
164
+
165
+ persistentChain = LLMChain(llm = ChatOpenAI(temperature=0.1), prompt=PERSISTENT_LAYER_PROMPT)
166
+
167
+
168
+ @tool("Generate Persistent Layer Code", return_direct=True)
169
+ def persistentLayerCodeGenerator(input: str) -> str:
170
+ '''useful for when you need to generate persistent layer code'''
171
+ response = persistentChain.run(input)
172
+ return response
app.py CHANGED
@@ -7,7 +7,7 @@ from embedding import CustomEmbedding
7
  from memories import HumenFeedbackBufferMemory
8
  from langchain.memory import ConversationBufferMemory
9
  from promopts import FEEDBACK, FEEDBACK_PROMPT
10
- from code_generate import code_agent_executor, tools
11
 
12
  # llm = ChatOpenAI(temperature=0.7)
13
 
@@ -110,7 +110,8 @@ with gr.Blocks() as demo:
110
  story = gr.Textbox(show_label=True, label="User Story", placeholder="Enter User Story").style(
111
  container=False)
112
  with gr.Row():
113
- buisinessButton = gr.Button("Generate Scenarios")
 
114
  with gr.Row():
115
  with gr.Column(scale=5):
116
  gr.Button("Rewrite Context").click(rewriteContext, [context, chatbot], [chatbot, context])
@@ -136,7 +137,7 @@ with gr.Blocks() as demo:
136
  with gr.Row():
137
  relateCode = gr.Textbox(show_label=True, label="Relate Code", placeholder="Enter Relate Code").style(
138
  container=False)
139
- for index, tool in enumerate(tools):
140
  with gr.Row():
141
  toolTextBox.append(gr.Textbox(show_label=False, visible=False, label=tool.name, value=tool.name).style())
142
  gr.Button(tool.name).click(
@@ -148,10 +149,7 @@ with gr.Blocks() as demo:
148
  faq = gr.Textbox(show_label=False, placeholder="Enter text and press enter").style(
149
  container=False)
150
 
151
-
152
- buisinessButton.click(clearMemory, [chatbot], [chatbot, txt]).then(sendMessage, [chatbot, txt], [chatbot]).then(
153
- feedBack, [context, story, chatbot], [chatbot, txt])
154
-
155
  txt.submit(sendMessage, [chatbot, txt], [chatbot]).then(
156
  feedBack, [context, story, chatbot, txt], [chatbot, txt, context])
157
 
 
7
  from memories import HumenFeedbackBufferMemory
8
  from langchain.memory import ConversationBufferMemory
9
  from promopts import FEEDBACK, FEEDBACK_PROMPT
10
+ from agents.code_generate_agent import code_agent_executor, code_agent_tools
11
 
12
  # llm = ChatOpenAI(temperature=0.7)
13
 
 
110
  story = gr.Textbox(show_label=True, label="User Story", placeholder="Enter User Story").style(
111
  container=False)
112
  with gr.Row():
113
+ gr.Button("Generate Scenarios").click(clearMemory, [chatbot], [chatbot, txt]).then(sendMessage, [chatbot, txt], [chatbot]).then(
114
+ feedBack, [context, story, chatbot], [chatbot, txt])
115
  with gr.Row():
116
  with gr.Column(scale=5):
117
  gr.Button("Rewrite Context").click(rewriteContext, [context, chatbot], [chatbot, context])
 
137
  with gr.Row():
138
  relateCode = gr.Textbox(show_label=True, label="Relate Code", placeholder="Enter Relate Code").style(
139
  container=False)
140
+ for index, tool in enumerate(code_agent_tools):
141
  with gr.Row():
142
  toolTextBox.append(gr.Textbox(show_label=False, visible=False, label=tool.name, value=tool.name).style())
143
  gr.Button(tool.name).click(
 
149
  faq = gr.Textbox(show_label=False, placeholder="Enter text and press enter").style(
150
  container=False)
151
 
152
+
 
 
 
153
  txt.submit(sendMessage, [chatbot, txt], [chatbot]).then(
154
  feedBack, [context, story, chatbot, txt], [chatbot, txt, context])
155
 
promopts.py CHANGED
@@ -50,320 +50,14 @@ Story: {input}
50
  {agent_scratchpad}"""
51
 
52
 
53
- DOMAIN_LAYER = """You are a software developer. Your task is to generate the domain layer tests and product code.
54
 
55
- ===TechStack
56
- Java17、reactor、lombok、Junit5、reactor test、Mockito
57
- ===END OF TechStack
58
 
59
- ===Architecture
60
- the domain layer inclue 2 componets:
61
- * Entity: This component is use to represents business concepts and encapsulates business rules.
62
- ---eaxmple code:
63
- public class Feature {{
64
- private FeatureId id;
65
- private FeatureDescription description;
66
 
67
- public record FeatureId(String featureKey) {{
68
-
69
- }}
70
 
71
- @Builder
72
- public record FeatureDescription(String name, String description, Boolean isEnable))) {{
73
-
74
- }}
75
- }}
76
- ---end of eaxmple code
77
- * Association: This component is use to define association between entities, which can represents the concept of a set of entity.
78
- ---eaxmple code:
79
- public interface Features {{
80
- Flux<Feature> findAll();
81
 
82
- Mono<Feature> findById(FeatureId id);
83
 
84
- Mono<Feature> save(Feature feature);
85
 
86
- Mono<Void> update(FeatureId id, FeatureDescription description);
87
 
88
- Mono<Void> delete(FeatureId id);
89
-
90
- Mono<Void> publish(FeatureId id);
91
-
92
- Mono<Void> disable(FeatureId id);
93
- }}
94
- ---end of eaxmple code
95
- ===END OF Architecture
96
-
97
- ===TestStrategy
98
- For the Entity, we can write unit test to ensure that the business rules related to Merchandise are correctly encapsulated.
99
- For the Association,do not write tests because it is has no impletation.
100
- ===END OF TestStrategy
101
-
102
- Use the following format:
103
- request: the request that you need to fulfill
104
-
105
- Entity:
106
- ```
107
- the Entity code that you write to fulfill the request, follow TechStack and Architecture
108
- ```
109
-
110
- Association:
111
- ```
112
- the Association code that you write to fulfill the request, follow TechStack and Architecture
113
- ```
114
-
115
- Test:
116
- ```
117
- the test code that you write to fulfill the request, follow TechStack Architecture and TestStrategy
118
- ```
119
-
120
- request: {input}"""
121
-
122
-
123
- DOMAIN_LAYER_PROMPT = PromptTemplate(input_variables=["input"], template=DOMAIN_LAYER,)
124
-
125
-
126
- PERSISTENT_LAYER = """You are a software developer. Your task is to generate the persistent layer tests and product code.
127
-
128
- ===TechStack
129
- Java17、reactor、lombok、Junit5、reactor test、Mockito、 Spring Data Reactive Couchbase、Testcontainers、Couchbase、WebClient
130
- ===END OF TechStack
131
-
132
- ===Architecture
133
- the persistent layer inclue 3 componets:
134
- * DbEntity: This component is use to define data structure that save to DB.
135
- ---eaxmple code:
136
- @Document
137
- public class FeatureDb {{
138
- @Version
139
- private long version;
140
-
141
- @Id
142
- @GeneratedValue(strategy = GenerationStrategy.UNIQUE)
143
- private String id;
144
-
145
- private String featureKey;
146
-
147
- private Feature.FeatureDescription description;
148
- }}
149
- ---end of eaxmple code
150
- * Repository: This component is use to define the interface to access DB.
151
- ---eaxmple code:
152
- public interface FeatureDbRepository extends ReactiveCrudRepository<FeatureDb, String> {{
153
- Mono<FeatureDb> findByFeatureKey(String featureKey);
154
- }}
155
- ---end of eaxmple code
156
- * Association Impletation: This component provide implementation of Association of domain layer, rely on Repository.
157
- ---eaxmple code:
158
- @Component
159
- @RequiredArgsConstructor
160
- public class FeaturesImpl implements Features{{
161
- private final FeatureDbRepository featureDbRepository;
162
-
163
- Flux<Feature> findAll() {{
164
- return featureDbRepository.findAll().map(FeatureDb::toFeature);
165
- }}
166
-
167
- Mono<Feature> save(Feature feature) {{
168
- return featureDbRepository.save(FeatureDb.fromFeature(feature)).map(FeatureDb::toFeature);
169
- }}
170
- }}
171
- ---end of eaxmple code
172
- ===END OF Architecture
173
-
174
- ===TestStrategy
175
- For the DbEntity And Repository, we can write component test to test the actual implementation of database operations, test class should extends RepositoryTestBase to use Testcontainers ability.
176
- ---eaxmple code:
177
- class FeatureDbRepositoryTest extends RepositoryTestBase {{
178
- @Autowired
179
- FeatureDbRepository repository;
180
-
181
- @BeforeEach
182
- void setUp() {{
183
- repository.deleteAll().block();
184
- }}
185
-
186
- @AfterEach
187
- void tearDown() {{
188
- repository.deleteAll().block();
189
- }}
190
-
191
- @Test
192
- void should_save_Feature_success() {{
193
- var featureKey = "featureKey1";
194
- repository.save(FeatureTestUtil.createFeatureDb(featureKey))
195
- .as(StepVerifier::create)
196
- .expectNextCount(1)
197
- .verifyComplete();
198
- }}
199
-
200
- @Test
201
- void should_add_same_featureKey_fail() {{
202
- var featureKey = "featureKey1";
203
- repository.save(FeatureTestUtil.createFeatureDb(featureKey)).block();
204
-
205
- repository.save(FeatureTestUtil.createFeatureDb(featureKey))
206
- .as(StepVerifier::create)
207
- .expectError()
208
- .verify();
209
- }}
210
- }}
211
- ---end of eaxmple code
212
- For Association Impletation,we writ unit test, and stub repository method with Mockito.
213
- ---eaxmple code:
214
- @ExtendWith(MockitoExtension.class)
215
- class FeatureImplTest {{
216
- @Mock
217
- FeatureDbRepository repository;
218
-
219
- Features features;
220
-
221
- @BeforeEach
222
- void setUp() {{
223
- features = new FeaturesImpl(repository);
224
- }}
225
-
226
- @Test
227
- void should_add_success() {{
228
- when(repository.save(any(FeatureDb.class))).thenAnswer(invocation -> {{
229
- FeatureDb featureDb = invocation.getArgument(0);
230
- return Mono.just(featureDb);
231
- }});
232
-
233
- features.add(createFeature("featureKey1"))
234
- .as(StepVerifier::create)
235
- .expectNextMatches(config -> config.getId().featureKey().equals("featureKey1")
236
- && config.getDescription().updatedAt() != null
237
- && config.getDescription().createdAt() != null
238
- )
239
- .verifyComplete();
240
- }}
241
-
242
- @Test
243
- void should_add_return_error_when_repository_save_error() {{
244
- Feature feature = createFeature("featureKey1");
245
-
246
- when(repository.save(any(FeatureDb.class))).thenReturn(Mono.error(new DuplicateKeyException("save error")));
247
-
248
- features.add(feature)
249
- .as(StepVerifier::create)
250
- .expectError()
251
- .verify();
252
- }}
253
- }}
254
-
255
-
256
- ===END OF TestStrategy
257
-
258
- Use the following format:
259
- request: the request that you need to fulfill include Entity and Association of domain layer
260
-
261
- DBEntity:
262
- ```
263
- the DBEntity code that you write to fulfill the request, follow TechStack and Architecture
264
- ```
265
-
266
- Repository:
267
- ```
268
- the Repository code that you write to fulfill the request, follow TechStack and Architecture
269
- ```
270
-
271
- Association Impletation:
272
- ```
273
- the Association Impletation code that you write to fulfill the request, follow TechStack and Architecture
274
- ```
275
-
276
- Test:
277
- ```
278
- the test code that you write to fulfill the request, follow TechStack Architecture and TestStrategy
279
- ```
280
-
281
- request: {input}"""
282
-
283
- PERSISTENT_LAYER_PROMPT = PromptTemplate(input_variables=["input"], template=PERSISTENT_LAYER,)
284
-
285
-
286
-
287
- API_LAYER = """You are a software developer. Your task is to generate the api layer tests and product code.
288
-
289
- ===TechStack
290
- Java17、reactor、lombok、Junit5、reactor test、Mockito、 Spring WebFlux、Spring Boot Test
291
- ===END OF TechStack
292
-
293
- ===Architecture
294
- the api layer inclue 2 componets:
295
- * DTO: This component is use to define data structure that api request and response.
296
- * Controller: This component is use to define the interface to access api.
297
- ---eaxmple code:
298
- @RestController
299
- @RequiredArgsConstructor
300
- @RequestMapping("/features")
301
- public class FeatureController {{
302
- private final Features features;
303
-
304
- @GetMapping()
305
- public Flux<Feature> findAll() {{
306
- return features.getAll();
307
- }}
308
-
309
- @PostMapping()
310
- public Mono<Feature> add(@RequestBody Feature feature) {{
311
- return features.add(feature);
312
- }}
313
- }}
314
- ---end of eaxmple code
315
- ===END OF Architecture
316
-
317
- ===TestStrategy
318
- For the Controller and DTO, we can write component test to test the actual implementation of api operations, test class rely on Association interface use WebFluxTest and WebTestClient ability.
319
- ---eaxmple code:
320
- @ExtendWith(SpringExtension.class)
321
- @WebFluxTest(value = FeatureFlagApi.class, properties = "spring.main.lazy-initialization=true")
322
- @ContextConfiguration(classes = TestConfiguration.class)
323
- class FeatureControllerTest extends ControllerTestBase {{
324
- @Autowired
325
- WebTestClient webClient;
326
-
327
- @MockBean
328
- Features features;
329
-
330
- @Test
331
- void should_getAll_success_when_no_records() {{
332
- when(features.getAll(Mockito.any())).thenReturn(Flux.empty());
333
-
334
- webClient.get()
335
- .uri("/features")
336
- .exchange()
337
- .expectStatus()
338
- .isOk()
339
- .expectBodyList(FeatureFlagResponse.class)
340
- .hasSize(0);
341
- }}
342
- }}
343
- ---end of eaxmple code
344
- ===END OF TestStrategy
345
-
346
- Use the following format:
347
- request: the request that you need to fulfill include Entity and Association of domain layer
348
-
349
- DTO:
350
- ```
351
- the DTO code that you write to fulfill the request, follow TechStack and Architecture
352
- ```
353
-
354
- Controller:
355
- ```
356
- the Controller code that you write to fulfill the request, follow TechStack and Architecture
357
- ```
358
-
359
- Test:
360
- ```
361
- the test code that you write to fulfill the request, follow TechStack Architecture and TestStrategy
362
- ```
363
-
364
- request: {input}"""
365
-
366
- API_LAYER_PROMPT = PromptTemplate(input_variables=["input"], template=API_LAYER,)
367
 
368
 
369
  code_generate_agent_template = """You are a tool picker.
 
50
  {agent_scratchpad}"""
51
 
52
 
 
53
 
 
 
 
54
 
 
 
 
 
 
 
 
55
 
 
 
 
56
 
 
 
 
 
 
 
 
 
 
 
57
 
 
58
 
 
59
 
 
60
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
61
 
62
 
63
  code_generate_agent_template = """You are a tool picker.