11
from metagpt.llm import LLM
13
CODE_REVIEW_SMALLEST_CONTEXT = """
19
this.board = this.createEmptyBoard();
26
for (let i = 0; i < 4; i++) {
27
board[i] = [0, 0, 0, 0];
33
this.board = this.createEmptyBoard();
41
for (let r = 0; r < 4; r++) {
42
for (let c = 0; c < 4; c++) {
43
if (this.board[r][c] === 0) {
44
emptyCells.push({ r, c });
48
if (emptyCells.length > 0) {
49
let randomCell = emptyCells[Math.floor(Math.random() * emptyCells.length)];
50
this.board[randomCell.r][randomCell.c] = Math.random() < 0.9 ? 2 : 4;
55
// This function will handle the logic for moving tiles
56
// in the specified direction and merging them
57
// It will also update the score and add a new random tile if the move is successful
58
// The actual implementation of this function is complex and would require
59
// a significant amount of code to handle all the cases for moving and merging tiles
60
// For the purposes of this example, we will not implement the full logic
61
// Instead, we will just call addRandomTile to simulate a move
74
return this.bestScore;
78
this.bestScore = score;
93
for (let c = 0; c < 4; c++) {
94
for (let r = 1; r < 4; r++) {
95
if (this.board[r][c] !== 0) {
97
while (row > 0 && this.board[row - 1][c] === 0) {
98
this.board[row - 1][c] = this.board[row][c];
99
this.board[row][c] = 0;
103
if (row > 0 && this.board[row - 1][c] === this.board[row][c]) {
104
this.board[row - 1][c] *= 2;
105
this.board[row][c] = 0;
106
this.score += this.board[row - 1][c];
114
// Implement logic for moving tiles down
115
// Similar to the 'up' case but iterating in reverse order
116
// and checking for merging in the opposite direction
119
// Implement logic for moving tiles left
120
// Similar to the 'up' case but iterating over columns first
121
// and checking for merging in the opposite direction
124
// Implement logic for moving tiles right
125
// Similar to the 'up' case but iterating over columns in reverse order
126
// and checking for merging in the opposite direction
131
this.addRandomTile();
137
FUNCTION_TO_MERMAID_CLASS = """
140
class UIDesign(Action):
141
#Class representing the UI Design action.
142
def __init__(self, name, context=None, llm=None):
143
super().__init__(name, context, llm) # 需要调用LLM进一步丰富UI设计的prompt
145
def parse_requirement(self, context: str):
146
#Parse UI Design draft from the context using regex.
147
pattern = r"## UI Design draft.*?\n(.*?)## Anything UNCLEAR"
148
return context, pattern
150
def parse_ui_elements(self, context: str):
151
#Parse Selected Elements from the context using regex.
152
pattern = r"## Selected Elements.*?\n(.*?)## HTML Layout"
153
return context, pattern
155
def parse_css_code(self, context: str):
156
pattern = r"```css.*?\n(.*?)## Anything UNCLEAR"
157
return context, pattern
159
def parse_html_code(self, context: str):
160
pattern = r"```html.*?\n(.*?)```"
161
return context, pattern
162
async def draw_icons(self, context, *args, **kwargs):
163
#Draw icons using SDEngine.
165
icon_prompts = self.parse_ui_elements(context)
166
icons = icon_prompts.split("\n")
167
icons = [s for s in icons if len(s.strip()) > 0]
169
for icon_prompt in icons:
171
prompt = engine.construct_payload(icon_prompt + ".<lora:WZ0710_AW81e-3_30e3b128d64T32_goon0.5>")
172
prompts_batch.append(prompt)
173
await engine.run_t2i(prompts_batch)
174
logger.info("Finish icon design using StableDiffusion API")
175
async def _save(self, css_content, html_content):
176
save_dir = CONFIG.workspace_path / "resources" / "codes"
177
if not os.path.exists(save_dir):
178
os.makedirs(save_dir, exist_ok=True)
179
# Save CSS and HTML content to files
180
css_file_path = save_dir / "ui_design.css"
181
html_file_path = save_dir / "ui_design.html"
182
with open(css_file_path, "w") as css_file:
183
css_file.write(css_content)
184
with open(html_file_path, "w") as html_file:
185
html_file.write(html_content)
186
async def run(self, requirements: list[Message], *args, **kwargs) -> ActionOutput:
187
#Run the UI Design action.
188
# fixme: update prompt (根据需求细化prompt)
189
context = requirements[-1].content
190
ui_design_draft = self.parse_requirement(context=context)
191
# todo: parse requirements str
192
prompt = PROMPT_TEMPLATE.format(context=ui_design_draft, format_example=FORMAT_EXAMPLE)
194
ui_describe = await self._aask_v1(prompt, "ui_design", OUTPUT_MAPPING)
195
logger.info(ui_describe.content)
196
logger.info(ui_describe.instruct_content)
197
css = self.parse_css_code(context=ui_describe.content)
198
html = self.parse_html_code(context=ui_describe.content)
199
await self._save(css_content=css, html_content=html)
200
await self.draw_icons(ui_describe.content)
207
"ClassView": "classDiagram\n class A {\n -int x\n +int y\n -int speed\n -int direction\n +__init__(x: int, y: int, speed: int, direction: int)\n +change_direction(new_direction: int) None\n +move() None\n }\n "
210
## nodes: "<node>: <type> # <comment>"
211
- ClassView: <class 'str'> # Generate the mermaid class diagram corresponding to source code in "context."
213
- Language: Please use the same language as the user input.
214
- Format: output wrapped inside [CONTENT][/CONTENT] as format example, nothing else.
216
Fill in the above nodes(ClassView) based on the format example.
220
## move function implementation
227
for (let c = 0; c < 4; c++) {
228
for (let r = 1; r < 4; r++) {
229
if (this.board[r][c] !== 0) {
231
while (row > 0 && this.board[row - 1][c] === 0) {
232
this.board[row - 1][c] = this.board[row][c];
233
this.board[row][c] = 0;
237
if (row > 0 && this.board[row - 1][c] === this.board[row][c]) {
238
this.board[row - 1][c] *= 2;
239
this.board[row][c] = 0;
240
this.score += this.board[row - 1][c];
248
for (let c = 0; c < 4; c++) {
249
for (let r = 2; r >= 0; r--) {
250
if (this.board[r][c] !== 0) {
252
while (row < 3 && this.board[row + 1][c] === 0) {
253
this.board[row + 1][c] = this.board[row][c];
254
this.board[row][c] = 0;
258
if (row < 3 && this.board[row + 1][c] === this.board[row][c]) {
259
this.board[row + 1][c] *= 2;
260
this.board[row][c] = 0;
261
this.score += this.board[row + 1][c];
269
for (let r = 0; r < 4; r++) {
270
for (let c = 1; c < 4; c++) {
271
if (this.board[r][c] !== 0) {
273
while (col > 0 && this.board[r][col - 1] === 0) {
274
this.board[r][col - 1] = this.board[r][col];
275
this.board[r][col] = 0;
279
if (col > 0 && this.board[r][col - 1] === this.board[r][col]) {
280
this.board[r][col - 1] *= 2;
281
this.board[r][col] = 0;
282
this.score += this.board[r][col - 1];
290
for (let r = 0; r < 4; r++) {
291
for (let c = 2; c >= 0; c--) {
292
if (this.board[r][c] !== 0) {
294
while (col < 3 && this.board[r][col + 1] === 0) {
295
this.board[r][col + 1] = this.board[r][col];
296
this.board[r][col] = 0;
300
if (col < 3 && this.board[r][col + 1] === this.board[r][col]) {
301
this.board[r][col + 1] *= 2;
302
this.board[r][col] = 0;
303
this.score += this.board[r][col + 1];
313
this.addRandomTile();
326
async def test_llm_code_review(llm):
328
"Please review the move function code above. Should it be refactor?",
329
"Please implement the move function",
330
"Please write a draft for the move function in order to implement it",
332
# prompt = CODE_REVIEW_SMALLEST_CONTEXT+ "\n\n" + MOVE_DRAFT + "\n\n" + choices[1]
333
# rsp = await llm.aask(prompt)
335
prompt = CODE_REVIEW_SMALLEST_CONTEXT + "\n\n" + MOVE_FUNCTION + "\n\n" + choices[0]
336
prompt = FUNCTION_TO_MERMAID_CLASS
338
_ = await llm.aask(prompt)
341
# if __name__ == "__main__":
342
# pytest.main([__file__, "-s"])