Skip to content

Commit

Permalink
Make API key optional and Show activity logs of In Review Stories (#75)
Browse files Browse the repository at this point in the history
  • Loading branch information
rounak610 authored Jul 17, 2024
1 parent 7c6d661 commit 8e4446d
Show file tree
Hide file tree
Showing 12 changed files with 85 additions and 17 deletions.
6 changes: 5 additions & 1 deletion app/controllers/llm_api_key.go
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,11 @@ func (c *LLMAPIKeyController) CreateLLMAPIKey(context *gin.Context) {
}

for _, apiKey := range createLLMAPIKey.APIKeys {
err = c.llmAPIKeyService.CreateOrUpdateLLMAPIKey(orgId, apiKey.LLMModel, apiKey.LLMAPIKey)
if apiKey.LLMAPIKey == nil {
err = c.llmAPIKeyService.CreateOrUpdateLLMAPIKey(orgId, apiKey.LLMModel, "")
} else {
err = c.llmAPIKeyService.CreateOrUpdateLLMAPIKey(orgId, apiKey.LLMModel, *apiKey.LLMAPIKey)
}
if err != nil {
context.JSON(http.StatusInternalServerError, gin.H{"error": err.Error()})
return
Expand Down
2 changes: 1 addition & 1 deletion app/services/llm_api_key.go
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ type LLMAPIKeyService struct {
}

func (s *LLMAPIKeyService) CreateOrUpdateLLMAPIKey(organisationID uint, llmModel string, llmAPIKey string) error {
if llmModel == "" || llmAPIKey == "" {
if llmModel == "" {
return errors.New("missing required fields")
}
err := s.llm_api_key_repo.CreateOrUpdateLLMAPIKey(organisationID, llmModel, llmAPIKey)
Expand Down
4 changes: 2 additions & 2 deletions app/types/request/llm_api_key_request.go
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,6 @@ type CreateLLMAPIKeyRequest struct {
}

type LLMAPIKey struct {
LLMModel string `json:"llm_model" binding:"required"`
LLMAPIKey string `json:"llm_api_key" binding:"required"`
LLMModel string `json:"llm_model" binding:"required"`
LLMAPIKey *string `json:"llm_api_key"`
}
Original file line number Diff line number Diff line change
Expand Up @@ -152,6 +152,17 @@ func (e NextJsServerStartTestExecutor) Execute(step steps.ServerStartTestStep) e
fmt.Printf("Error updating story status: %s\n", err.Error())
return err
}
//creating activity log
err := e.activityLogService.CreateActivityLog(
step.Execution.ID,
step.ExecutionStep.ID,
"INFO",
"Design story completed successfully!",
)
if err!= nil {
fmt.Printf("Error creating activity log: %s\n", err.Error())
return err
}
fmt.Println("Story Status Updated to DONE")
return nil
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -164,7 +164,7 @@ func (openAICodeGenerator OpenAICodeGenerator) Execute(step steps.GenerateCodeSt
step.Execution.ID,
step.ExecutionStep.ID,
"INFO",
fmt.Sprintf("Action required: There's an issue with your LLM API Key. Ensure your API Key is correct. <a href='%s' style='color:%s; text-decoration:%s;'>Settings</a>", settingsUrl, "blue", "underline"),
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.GPT_4O, settingsUrl, "blue", "underline"),
)
if err != nil {
fmt.Printf("Error creating activity log: %s\n", err.Error())
Expand Down Expand Up @@ -198,7 +198,8 @@ func (openAICodeGenerator OpenAICodeGenerator) Execute(step steps.GenerateCodeSt
fmt.Printf("Error commiting code: %s\n", err.Error())
return err
}
return errors.New("LLM API Key not found in database")
errorString := fmt.Sprintf("LLM API Key for model %s not found in database", constants.GPT_4O)
return errors.New(errorString)
}
apiKey := llmAPIKey.LLMAPIKey
fmt.Println("_________API_KEY_________", apiKey)
Expand Down Expand Up @@ -257,7 +258,7 @@ func (openAICodeGenerator *OpenAICodeGenerator) GenerateCode(apiKey string, fram
step.Execution.ID,
step.ExecutionStep.ID,
"INFO",
fmt.Sprintf("Action required: There's an issue with your LLM API Key. Ensure your API Key is correct. <a href='%s' style='color:%s; text-decoration:%s'>Settings</a>", settingsUrl, "blue", "underline"),
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.GPT_4O, settingsUrl, "blue", "underline"),
)
if err != nil {
fmt.Printf("Error creating activity log: %s\n", err.Error())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,13 @@ import (
"ai-developer/app/services/s3_providers"
"ai-developer/app/utils"
"ai-developer/app/workflow_executors/step_executors/steps"
"errors"
"fmt"
"os"
"os/exec"
"path/filepath"
"strings"

"go.uber.org/zap"
)

Expand Down Expand Up @@ -124,10 +126,36 @@ func (openAiCodeGenerator OpenAiNextJsCodeGenerator) Execute(step steps.Generate
if openAiCodeGenerator.llmAPIKeyService == nil {
fmt.Println("_____NULL_____")
}
llmAPIKey, err := openAiCodeGenerator.llmAPIKeyService.GetLLMAPIKeyByModelName("claude-3", organisationId)
llmAPIKey, err := openAiCodeGenerator.llmAPIKeyService.GetLLMAPIKeyByModelName(constants.CLAUDE_3, organisationId)
if err != nil {
fmt.Println("Error getting claude api key: ", err)
}
if llmAPIKey == nil || llmAPIKey.LLMAPIKey == "" {
openAiCodeGenerator.logger.Info("_____claude API Key not found_____")
settingsUrl := config.Get("app.url").(string) + "/settings"
err := openAiCodeGenerator.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 err
}
//Update Execution Status and Story Status
if err := openAiCodeGenerator.storyService.UpdateStoryStatus(int(step.Story.ID), constants.InReviewLLMKeyNotFound); err != nil {
fmt.Printf("Error updating story status: %s\n", err.Error())
return err
}
//Update execution status to IN REVIEW
if err := openAiCodeGenerator.executionService.UpdateExecutionStatus(step.Execution.ID, constants.InReviewLLMKeyNotFound); err != nil {
fmt.Printf("Error updating execution step: %s\n", err.Error())
return err
}
errorString := fmt.Sprintf("LLM API Key for model %s not found in database", constants.CLAUDE_3)
return errors.New(errorString)
}
apiKey := llmAPIKey.LLMAPIKey
fmt.Println("_________API KEY_________", apiKey)

Expand All @@ -139,7 +167,7 @@ func (openAiCodeGenerator OpenAiNextJsCodeGenerator) Execute(step steps.Generate
step.Execution.ID,
step.ExecutionStep.ID,
"INFO",
fmt.Sprintf("Action required: There's an issue with your LLM API Key. Ensure your API Key is correct. <a href='%s' style='color:%s; text-decoration:%s'>Settings</a>", settingsUrl, "blue", "underline"),
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())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -86,7 +86,9 @@ func (e NextJsUpdateCodeFileExecutor) Execute(step steps.UpdateCodeFileStep) err
func (e *NextJsUpdateCodeFileExecutor) UpdateReGeneratedCodeFile(response Response, step steps.UpdateCodeFileStep) error {
var llmResponse map[string]interface{}
var filePath string
if strings.Contains(response.FileName, "app/") {
if response.FileName == "package.json" {
filePath = config.FrontendWorkspacePath(step.Project.HashID, step.Story.HashID) + "/" + response.FileName
} else if strings.Contains(response.FileName, "app/") {
filePath = config.FrontendWorkspacePath(step.Project.HashID, step.Story.HashID) + "/" + response.FileName
} else {
filePath = config.FrontendWorkspacePath(step.Project.HashID, step.Story.HashID) + "/app/" + response.FileName
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -82,7 +82,7 @@ func (e UpdateCodeFileExecutor) Execute(step steps.UpdateCodeFileStep) error {
} else if strings.HasPrefix(line, "|code|") || strings.HasPrefix(line, "|terminal|") {
isCode = true
} else if isCode {
if strings.TrimSpace(line) == "```" || strings.TrimSpace(line) == "```plaintext" || strings.TrimSpace(line) == "```bash" || strings.TrimSpace(line) == "```terminal" || strings.TrimSpace(line) == "```python" || strings.TrimSpace(line) == "```css" || strings.TrimSpace(line) == "```html" || strings.TrimSpace(line) == "```javascript" || strings.TrimSpace(line) == "```ini" {
if strings.TrimSpace(line) == "```" || strings.TrimSpace(line) == "```shell" || strings.TrimSpace(line) == "```plaintext" || strings.TrimSpace(line) == "```bash" || strings.TrimSpace(line) == "```terminal" || strings.TrimSpace(line) == "```python" || strings.TrimSpace(line) == "```css" || strings.TrimSpace(line) == "```html" || strings.TrimSpace(line) == "```javascript" || strings.TrimSpace(line) == "```ini" {
continue
}
currentContent = append(currentContent, line)
Expand Down
4 changes: 2 additions & 2 deletions gui/src/app/(programmer)/design_workbench/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -16,8 +16,8 @@ const DesignWorkBenchPage: React.FC = () => {
const activeDesignWorkbenchCondition = () => {
return (
storiesList &&
(storiesList.IN_PROGRESS || storiesList.DONE) &&
(storiesList.IN_PROGRESS.length > 0 || storiesList.DONE.length > 0)
(storiesList.IN_PROGRESS || storiesList.DONE || storiesList.IN_REVIEW) &&
(storiesList.IN_PROGRESS.length > 0 || storiesList.DONE.length > 0 || storiesList.IN_REVIEW.length > 0)
);
};

Expand Down
4 changes: 2 additions & 2 deletions gui/src/app/(programmer)/workbench/page.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -18,8 +18,8 @@ export default function WorkBench() {
const activeWorkbenchCondition = () => {
return (
storiesList &&
(storiesList.IN_PROGRESS || storiesList.DONE) &&
(storiesList.IN_PROGRESS.length > 0 || storiesList.DONE.length > 0)
(storiesList.IN_PROGRESS || storiesList.DONE || storiesList.IN_REVIEW) &&
(storiesList.IN_PROGRESS.length > 0 || storiesList.DONE.length > 0 || storiesList.IN_REVIEW.length > 0)
);
};

Expand Down
25 changes: 24 additions & 1 deletion gui/src/components/WorkBenchComponents/ActiveWorkbench.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,7 @@ const ActiveWorkbench: React.FC<ActiveWorkbenchProps> = ({
const completeStoriesList = [
...storiesList.IN_PROGRESS,
...storiesList.DONE,
...storiesList.IN_REVIEW
];

const story = completeStoriesList.find(
Expand Down Expand Up @@ -84,6 +85,10 @@ const ActiveWorkbench: React.FC<ActiveWorkbenchProps> = ({
return storiesList && storiesList.DONE && storiesList.DONE.length > 0;
};

const handleInReviewCheck = () => {
return storiesList && storiesList.IN_REVIEW && storiesList.IN_REVIEW.length > 0;
};

useEffect(() => {
let id = null;
if (typeof window !== 'undefined') {
Expand All @@ -107,7 +112,7 @@ const ActiveWorkbench: React.FC<ActiveWorkbenchProps> = ({
useEffect(() => {
if (
storiesList &&
(storiesList.IN_PROGRESS.length > 0 || storiesList.DONE.length > 0)
(storiesList.IN_PROGRESS.length > 0 || storiesList.DONE.length > 0 || storiesList.IN_REVIEW.length > 0)
)
handleSelectedStory();
}, [storiesList, selectedStoryId]);
Expand Down Expand Up @@ -173,6 +178,24 @@ const ActiveWorkbench: React.FC<ActiveWorkbenchProps> = ({
</CustomDropdown.Section>
)}

{handleInReviewCheck() && (
<CustomDropdown.Section
title={'IN REVIEW STORIES'}
showDivider
>
{storiesList.IN_REVIEW.map((story) => (
<CustomDropdown.Item
key={story.story_id.toString()}
onClick={() =>
handleItemSelect(story.story_id.toString())
}
>
<span>{story.story_name}</span>
</CustomDropdown.Item>
))}
</CustomDropdown.Section>
)}

{handleDoneCheck() && (
<CustomDropdown.Section title={'DONE STORIES'}>
{storiesList.DONE.map((story) => (
Expand Down
1 change: 0 additions & 1 deletion server.go
Original file line number Diff line number Diff line change
Expand Up @@ -506,7 +506,6 @@ func main() {
llmApiKeys := api.Group("/llm_api_key", middleware.AuthenticateJWT())
llmApiKeys.POST("", llm_api_key.CreateLLMAPIKey)
llmApiKeys.POST("/", llm_api_key.CreateLLMAPIKey)

llmApiKeys.GET("/:organisation_id", orgAuthMiddleware.Authorize(), llm_api_key.FetchAllLLMAPIKeyByOrganisationID)

// Wrap the socket.io server as Gin handlers for specific routes
Expand Down

0 comments on commit 8e4446d

Please sign in to comment.