feat: issue creation
This commit is contained in:
@ -13,7 +13,7 @@ var (
|
||||
|
||||
type Forge interface {
|
||||
GetProjects(ctx context.Context) ([]*model.Project, error)
|
||||
CreateIssue(ctx context.Context, projectID string, title string, content string) error
|
||||
CreateIssue(ctx context.Context, projectID string, title string, body string) (string, error)
|
||||
GetIssues(ctx context.Context, projectID string, issueIDs ...string) ([]*model.Issue, error)
|
||||
GetIssueTemplate(ctx context.Context, projectID string) (string, error)
|
||||
}
|
||||
|
@ -4,6 +4,7 @@ import (
|
||||
"context"
|
||||
"fmt"
|
||||
"log/slog"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
_ "embed"
|
||||
@ -39,6 +40,20 @@ type IssueManager struct {
|
||||
projectCache *cache.Cache[[]*model.Project]
|
||||
}
|
||||
|
||||
func (m *IssueManager) CreateIssue(ctx context.Context, user *model.User, projectID string, title string, body string) (string, error) {
|
||||
forge, err := m.getUserForge(ctx, user)
|
||||
if err != nil {
|
||||
return "", errors.WithStack(err)
|
||||
}
|
||||
|
||||
issueURL, err := forge.CreateIssue(ctx, projectID, title, body)
|
||||
if err != nil {
|
||||
return "", errors.WithStack(err)
|
||||
}
|
||||
|
||||
return issueURL, nil
|
||||
}
|
||||
|
||||
func (m *IssueManager) GetUserProjects(ctx context.Context, user *model.User) ([]*model.Project, error) {
|
||||
cacheKey := fmt.Sprintf("%s/%s", user.Provider, user.ID)
|
||||
|
||||
@ -62,15 +77,15 @@ func (m *IssueManager) GetUserProjects(ctx context.Context, user *model.User) ([
|
||||
return projects, nil
|
||||
}
|
||||
|
||||
func (m *IssueManager) GenerateIssue(ctx context.Context, user *model.User, projectID string, issueSummary string) (string, error) {
|
||||
func (m *IssueManager) GenerateIssue(ctx context.Context, user *model.User, projectID string, issueSummary string) (string, string, error) {
|
||||
systemPrompt, err := m.getIssueSystemPrompt(ctx, user, projectID)
|
||||
if err != nil {
|
||||
return "", errors.WithStack(err)
|
||||
return "", "", errors.WithStack(err)
|
||||
}
|
||||
|
||||
userPrompt, err := m.getIssueUserPrompt(ctx, user, projectID, issueSummary)
|
||||
if err != nil {
|
||||
return "", errors.WithStack(err)
|
||||
return "", "", errors.WithStack(err)
|
||||
}
|
||||
|
||||
messages := []llm.Message{
|
||||
@ -80,10 +95,22 @@ func (m *IssueManager) GenerateIssue(ctx context.Context, user *model.User, proj
|
||||
|
||||
res, err := m.llmClient.ChatCompletion(ctx, llm.WithMessages(messages...))
|
||||
if err != nil {
|
||||
return "", errors.WithStack(err)
|
||||
return "", "", errors.WithStack(err)
|
||||
}
|
||||
|
||||
return res.Message().Content(), nil
|
||||
body := res.Message().Content()
|
||||
|
||||
messages = append(messages, res.Message())
|
||||
messages = append(messages, llm.NewMessage(llm.RoleUser, "Generate a title for this issue. Keep it descriptive, simple and short. Do not write anything else."))
|
||||
|
||||
res, err = m.llmClient.ChatCompletion(ctx, llm.WithMessages(messages...))
|
||||
if err != nil {
|
||||
return "", "", errors.WithStack(err)
|
||||
}
|
||||
|
||||
title := toTitle(res.Message().Content())
|
||||
|
||||
return title, body, nil
|
||||
}
|
||||
|
||||
func (m *IssueManager) getIssueSystemPrompt(ctx context.Context, user *model.User, projectID string) (string, error) {
|
||||
@ -156,3 +183,8 @@ func NewIssueManager(llmClient llm.Client, forgeFactories ...ForgeFactory) *Issu
|
||||
projectCache: cache.New[[]*model.Project](time.Minute*5, (time.Minute*5)/2),
|
||||
}
|
||||
}
|
||||
|
||||
func toTitle(str string) string {
|
||||
str = strings.ToLower(str)
|
||||
return strings.ToUpper(string(str[0])) + str[1:]
|
||||
}
|
||||
|
@ -9,6 +9,7 @@ You are an expert software developer with extensive experience in writing clear
|
||||
- Expected behavior.
|
||||
- Actual behavior.
|
||||
- Any relevant error messages or logs.
|
||||
- Always use the user prompt context main language.
|
||||
|
||||
2. **Additional Context**:
|
||||
- Include any other relevant information that might help in understanding or resolving the issue/request.
|
||||
|
Reference in New Issue
Block a user