Skip to content

Add retries for json parsing error #86

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 56 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 44 commits
Commits
Show all changes
56 commits
Select commit Hold shift + click to select a range
09e4304
added template and prompt
rounak610 Jul 4, 2024
e94a988
changes in code for django template
rounak610 Jul 4, 2024
bb46786
Merge remote-tracking branch 'upstream/main'
rounak610 Jul 10, 2024
033cfc9
merge conflicts resolved
rounak610 Jul 10, 2024
4fc9caa
Merge branch 'main' of github.com:TransformerOptimus/SuperCoder # Ple…
rounak610 Jul 12, 2024
f3f47dc
Merge remote-tracking branch 'upstream/main'
rounak610 Jul 14, 2024
bd8ea52
Merge remote-tracking branch 'upstream/main'
rounak610 Jul 15, 2024
6f1df3e
Merge branch 'main' of github.com:TransformerOptimus/SuperCoder
rounak610 Jul 16, 2024
41049d1
fixes in django prompt
rounak610 Jul 16, 2024
a9b303f
resolve merge conflicts
rounak610 Jul 16, 2024
fe7a729
Merge branch 'main' of github.com:TransformerOptimus/SuperCoder
rounak610 Jul 16, 2024
80dfd37
Merge branch 'main' of github.com:TransformerOptimus/SuperCoder
rounak610 Jul 17, 2024
5cabd3a
fixes
rounak610 Jul 18, 2024
144ab4e
fixes
rounak610 Jul 18, 2024
43b35c1
fixes
rounak610 Jul 19, 2024
3839f2a
fixes
rounak610 Jul 19, 2024
fd98a04
removed unused loggers
rounak610 Jul 19, 2024
b3f6d00
Merge remote-tracking branch 'upstream/main'
rounak610 Jul 19, 2024
e6abe65
chnaged activity logs
rounak610 Jul 19, 2024
ef106c9
Merge remote-tracking branch 'upstream/main'
rounak610 Jul 19, 2024
b367470
fixes
rounak610 Jul 22, 2024
bb79997
fixes
rounak610 Jul 22, 2024
49a175d
fixes
rounak610 Jul 22, 2024
9befd0f
fixes
rounak610 Jul 22, 2024
b60f77b
Merge remote-tracking branch 'upstream/main'
rounak610 Jul 22, 2024
958391b
added retries in edit code
rounak610 Jul 22, 2024
da3e523
Merge remote-tracking branch 'upstream/main'
rounak610 Jul 22, 2024
50d0927
Merge branch 'main' into design_rebuild_fix
rounak610 Jul 22, 2024
5f26f68
resolved merge conflicts
rounak610 Jul 22, 2024
28a68af
resolved merge conflicts
rounak610 Jul 22, 2024
667b442
fixes
rounak610 Jul 22, 2024
166686f
fixes
rounak610 Jul 22, 2024
6535549
fixes
rounak610 Jul 22, 2024
c2854a2
minor fixes
rounak610 Jul 23, 2024
cd81b8a
fixes
rounak610 Jul 23, 2024
79edf24
fixes
rounak610 Jul 23, 2024
614b6b4
Merge remote-tracking branch 'upstream/main'
rounak610 Jul 23, 2024
28ac5fe
fixes
rounak610 Jul 24, 2024
d86c8bd
fixes
rounak610 Jul 24, 2024
744f650
fixes
rounak610 Jul 24, 2024
e3a891a
minor fix
rounak610 Jul 24, 2024
ec368c8
Merge remote-tracking branch 'upstream/main'
rounak610 Jul 24, 2024
8146648
Merge branch 'main' into design_rebuild_fix
rounak610 Jul 25, 2024
43f0a5b
merge conflicts resolved
rounak610 Jul 25, 2024
84607aa
fixes
rounak610 Jul 25, 2024
97a6b4b
fixes
rounak610 Jul 25, 2024
10e0f9c
fixes
rounak610 Jul 25, 2024
300267e
Merge remote-tracking branch 'upstream/main'
rounak610 Jul 25, 2024
98cb75f
Merge branch 'main' into design_rebuild_fix
rounak610 Jul 25, 2024
54987f8
fixes
rounak610 Jul 25, 2024
370d620
fixes
rounak610 Jul 25, 2024
fb75569
fixes
rounak610 Jul 25, 2024
40530c5
Update open_ai_next_js_code_generation_executor.go
rounak610 Jul 25, 2024
2644e20
added loggers
rounak610 Jul 26, 2024
9944783
fixes
rounak610 Jul 26, 2024
cb4f3ae
fixes
rounak610 Jul 26, 2024
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions app/models/types/errors.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,3 +11,5 @@ var ErrInvalidStory = errors.New("invalid story")
var ErrInvalidStoryStatusTransition = errors.New("invalid story status transition")

var ErrAnotherStoryAlreadyInProgress = errors.New("another story already in progress")

var ErrJsonParsingRetriesExceeded = errors.New("json parsing retries exceeded")
73 changes: 73 additions & 0 deletions app/prompts/nextjs/ai_frontend_developer_edit_code_retry.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,73 @@
You are tasked with updating the frontend code to resolve build errors. You will be given information about a specific file, the error description, the current code, and the project's directory structure. Your job is to propose a solution by either editing existing code or inserting new code.

Here's the file you need to work on:
<file_name>
{{FILE_NAME}}
</file_name>

The build error description is as follows:
<error_description>
{{ERROR_DESCRIPTION}}
</error_description>

Here's the current code in the file:
<current_code>
{{CURRENT_CODE}}
</current_code>

The directory structure of the project is:
<directory_structure>
{{DIRECTORY_STRUCTURE}}
</directory_structure>

Based on the error description and the current code, you must choose ONE of the following actions:

1. Edit code:
Replace the code in the given file path from `start_line` to `end_line` with `new_code`.

2. Add code:
Insert the code in the given file path below the `line_number`.

Provide your response in JSON format, following one of these structures:

For editing code:
{
"type": "edit",
"start_line": Starting Line number,
"end_line": Ending Line number,
"new_code": Code snippet
}

For inserting code:
{
"type": "insert",
"line_number": Line number,
"new_code": Code snippet
}

Guidelines for code editing and inserting:
- When editing, provide the code snippet from several lines before and after the actual edit to ensure proper context. Aim to edit complete sections of the code, covering at least 20-30 lines.
- If multiple edits are needed, choose line numbers that cover all necessary changes. In extreme cases, you may edit the entire file by setting start_line = 1 and end_line = last line of code.
- Do not include ```json and ``` in your response.
- Ensure that the proposed code is syntactically correct.
- Beware of any unescaped single quotes (') in the JSX code. Do not have unescaped single quotes in the code, use &apos; or &quot; or other appropriate methods instead.

Remember to provide only one edit or insert at a time. Your primary goal is to resolve the build error while maintaining the integrity of the code.

Present your solution in the JSON format described above, without any additional explanation or commentary.

The previous response was not valid JSON. Please provide the edit instructions in the specified JSON format. Here is the format:
For editing code:
{
"type": "edit",
"start_line": Starting Line number,
"end_line": Ending Line number,
"new_code": Code snippet
}

For inserting code:
{
"type": "insert",
"line_number": Line number,
"new_code": Code snippet
}
102 changes: 102 additions & 0 deletions app/prompts/nextjs/next_js_build_checker_retry.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,102 @@
You are an AI assistant tasked with analyzing the build logs of a website's frontend and determining if the build was successful. If not, you'll need to suggest an action to resolve the issue. You'll be provided with the following information:

<build_logs>
{{BUILD_LOGS}}
</build_logs>

<directory_structure>
{{DIRECTORY_STRUCTURE}}
</directory_structure>

Your task is to:
1. Analyze the build logs carefully.
2. Determine if the build was successful or not.
3. If the build was not successful, suggest one of the following actions:
a. Create a new file
b. Edit an existing file

To determine if the build was successful:
- Look for phrases like "Build successful", "Build completed", or similar indications of success.
- Check for error messages, warnings, or failed steps in the build process.
- Pay attention to the final lines of the build logs, as they often contain the build status.

If the build was not successful:
1. Identify the root cause of the failure based on the error messages in the build logs.
2. Consider the logs and directory structure when suggesting a solution.
3. Choose the most appropriate action (create, or edit) to resolve the issue.
4. Provide detailed information about the action, including file paths (relative to the root directory) or terminal commands.
5. Include line numbers from the build logs in your description if available.

Provide your response in the following JSON format:

For a successful build:
{
"build_successful": "Yes"
}

For an unsuccessful build:
{
"build_successful": "No",
"action": {
"type": "create|edit",
"file_path": "path/to/file",
"description": "Detailed description of the action and why it's needed"
}
}
Examples to clarify:
{
"build_successful": "No",
"action": {
"type": "create",
"file_path": "path/to/file",
"description": "Detailed description of the action and why it's needed"
}
}

{
"build_successful": "No",
"action": {
"type": "edit",
"file_path": "path/to/file",
"description": "Detailed description of the action and why it's needed"
}
}


Remember to analyze the build logs thoroughly and provide a clear, concise explanation of the issue and the proposed solution in the "description" field. Do not include the ```json and ``` markers in your response.

The previous response was not valid JSON. Please provide the edit instructions in the specified JSON format. Here is the format:
Provide your response in the following JSON format:

For a successful build:
{
"build_successful": "Yes"
}

For an unsuccessful build:
{
"build_successful": "No",
"action": {
"type": "create|edit",
"file_path": "path/to/file",
"description": "Detailed description of the action and why it's needed"
}
}
Examples to clarify:
{
"build_successful": "No",
"action": {
"type": "create",
"file_path": "path/to/file",
"description": "Detailed description of the action and why it's needed"
}
}

{
"build_successful": "No",
"action": {
"type": "edit",
"file_path": "path/to/file",
"description": "Detailed description of the action and why it's needed"
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,8 +14,8 @@ import (
"os/exec"
"path/filepath"
"strings"

"go.uber.org/zap"
"ai-developer/app/monitoring"
)

type NextJsServerStartTestExecutor struct {
Expand All @@ -26,6 +26,7 @@ type NextJsServerStartTestExecutor struct {
llmAPIKeyService *services.LLMAPIKeyService
storyService *services.StoryService
projectService *services.ProjectService
slackAlert *monitoring.SlackAlert
}

func NewNextJsServerStartTestExecutor(
Expand All @@ -36,6 +37,7 @@ func NewNextJsServerStartTestExecutor(
executionService *services.ExecutionService,
storyService *services.StoryService,
projectService *services.ProjectService,
slackAlert *monitoring.SlackAlert,
) *NextJsServerStartTestExecutor {
return &NextJsServerStartTestExecutor{
executionStepService: executionStepService,
Expand All @@ -45,6 +47,7 @@ func NewNextJsServerStartTestExecutor(
executionService: executionService,
storyService: storyService,
projectService: projectService,
slackAlert: slackAlert,
}
}

Expand Down Expand Up @@ -170,46 +173,68 @@ func (e NextJsServerStartTestExecutor) Execute(step steps.ServerStartTestStep) e

func (e NextJsServerStartTestExecutor) AnalyseBuildLogs(buildLogs, directoryPlan, apiKey string, step steps.ServerStartTestStep) (bool, map[string]interface{}, error) {
e.logger.Info("____Analyzing build logs____ ", zap.String("buildLogs", buildLogs))
messages, err := e.CreateMessage(buildLogs, directoryPlan)
if err != nil {
return false, nil, err
}
claudeClient:= llms.NewClaudeClient(apiKey)
response, err := claudeClient.ChatCompletion(messages)
if err != nil {
settingsUrl := config.Get("app.url").(string) + "/settings"
err = e.activityLogService.CreateActivityLog(
step.Execution.ID,
step.ExecutionStep.ID,
"INFO",
fmt.Sprintf("Action required: There's an issue with your LLM API Key. Ensure your API Key for %s is correct. <a href='%s' style='color:%s; text-decoration:%s;'>Settings</a>", constants.CLAUDE_3, settingsUrl, "blue", "underline"),
)
if err != nil {
fmt.Printf("Error creating activity log: %s\n", err.Error())
return false, nil, err
claudeClient := llms.NewClaudeClient(apiKey)
var jsonResponse map[string]interface{}
var response string

for retryCount := 1; retryCount < 6; retryCount++ {
messages, err := e.CreateMessage(buildLogs, directoryPlan, retryCount)
if err != nil{
fmt.Println("failed to create messages for llm")
return false, nil, err
}
//Update Execution Status and Story Status
if err = e.storyService.UpdateStoryStatus(int(step.Story.ID), constants.InReviewLLMKeyNotFound); err != nil {
fmt.Printf("Error updating story status: %s\n", err.Error())
return false, nil, err
response, err = claudeClient.ChatCompletion(messages)
if err != nil {
settingsUrl := config.Get("app.url").(string) + "/settings"
err = e.activityLogService.CreateActivityLog(
step.Execution.ID,
step.ExecutionStep.ID,
"INFO",
fmt.Sprintf("Action required: There's an issue with your LLM API Key. Ensure your API Key for %s is correct. <a href='%s' style='color:%s; text-decoration:%s;'>Settings</a>", constants.CLAUDE_3, settingsUrl, "blue", "underline"),
)
if err != nil {
fmt.Printf("Error creating activity log: %s\n", err.Error())
return false, nil, err
}
//Update Execution Status and Story Status
if err = e.storyService.UpdateStoryStatus(int(step.Story.ID), constants.InReviewLLMKeyNotFound); err != nil {
fmt.Printf("Error updating story status: %s\n", err.Error())
return false, nil, err
}
if err = e.executionService.UpdateExecutionStatus(step.Execution.ID, constants.InReviewLLMKeyNotFound); err != nil {
fmt.Printf("Error updating execution step: %s\n", err.Error())
return false, nil, err
}
fmt.Println("failed to generate code from llm")
if retryCount == 4 {
return false, nil, fmt.Errorf("failed to generate code from llm after 5 attempts: %w", err)
}
continue
}
if err = e.executionService.UpdateExecutionStatus(step.Execution.ID, constants.InReviewLLMKeyNotFound); err != nil {
fmt.Printf("Error updating execution step: %s\n", err.Error())
return false, nil, err
if err = json.Unmarshal([]byte(response), &jsonResponse); err != nil {
fmt.Println("failed to unmarshal response from Claude API, retrying...")
if retryCount == 5 {
err := e.slackAlert.SendAlert(
"Max retry limit reached while parsing JSON, error occurred while parsing build logs response",
map[string]string{
"story_id": fmt.Sprintf("%d", int64(step.Story.ID)),
"execution_id": fmt.Sprintf("%d", int64(step.Execution.ID)),
"execution_step_id": fmt.Sprintf("%d", int64(step.ExecutionStep.ID)),
"is_re_execution": fmt.Sprintf("%t", step.Execution.ReExecution),
})
if err != nil {
fmt.Printf("Error sending slack alert: %s\n", err.Error())
return false, nil, err
}
return false, nil, fmt.Errorf("failed to unmarshal response from Claude API after 5 attempts: %w", err)
}
continue
}
fmt.Println("failed to generate code from llm")
return false, nil, fmt.Errorf("failed to generate code from llm: %w", err)
}
var jsonResponse map[string]interface{}
if err = json.Unmarshal([]byte(response), &jsonResponse); err != nil {
fmt.Println("failed to unmarshal response from Claude API, Failed to parse response as JSON on attempt.")
return false, nil, fmt.Errorf("failed to unmarshal response from Claude API: %w", err)
break
}
fmt.Println("Response after extracting JSON: ", jsonResponse)

buildResponse, action := e.CheckBuildResponse(jsonResponse)
fmt.Println("Build Logs Check Response")
return buildResponse, action, nil

}

func (e NextJsServerStartTestExecutor) CheckBuildResponse(response map[string]interface{}) (bool, map[string]interface{}) {
Expand All @@ -230,8 +255,20 @@ func (e NextJsServerStartTestExecutor) CheckBuildResponse(response map[string]in
return false, action
}

func (e NextJsServerStartTestExecutor) CreateMessage(buildLogs string, directoryPlan string) ([]llms.ClaudeChatCompletionMessage, error) {
content, err := os.ReadFile("/go/prompts/nextjs/next_js_build_checker.txt")
func (e NextJsServerStartTestExecutor) CreateMessage(buildLogs string, directoryPlan string, attempts int) ([]llms.ClaudeChatCompletionMessage, error) {
var content []byte
var err error
if attempts > 1 {
content, err = os.ReadFile("/go/prompts/nextjs/next_js_build_checker_retry.txt")
if err!= nil {
return nil, fmt.Errorf("failed to load system prompt: %w", err)
}
} else {
content, err = os.ReadFile("/go/prompts/nextjs/next_js_build_checker.txt")
if err!= nil {
return nil, fmt.Errorf("failed to load system prompt: %w", err)
}
}
modifiedContent := strings.Replace(string(content), "{{BUILD_LOGS}}", buildLogs, -1)
modifiedContent = strings.Replace(string(modifiedContent), "{{DIRECTORY_STRUCTURE}}", directoryPlan, -1)
if err != nil {
Expand Down
Loading