262 lines
6.3 KiB
Go
262 lines
6.3 KiB
Go
package plan
|
|
|
|
import (
|
|
"context"
|
|
"encoding/json"
|
|
"fmt"
|
|
"log"
|
|
"net/http"
|
|
"plandex-server/db"
|
|
"plandex-server/model"
|
|
"plandex-server/model/prompts"
|
|
"plandex-server/notify"
|
|
"plandex-server/types"
|
|
"plandex-server/utils"
|
|
|
|
shared "plandex-shared"
|
|
|
|
"github.com/sashabaranov/go-openai"
|
|
)
|
|
|
|
func (state *activeTellStreamState) genPlanDescription() (*db.ConvoMessageDescription, *shared.ApiError) {
|
|
auth := state.auth
|
|
plan := state.plan
|
|
planId := plan.Id
|
|
branch := state.branch
|
|
settings := state.settings
|
|
clients := state.clients
|
|
authVars := state.authVars
|
|
orgUserConfig := state.orgUserConfig
|
|
config := settings.GetModelPack().CommitMsg
|
|
|
|
activePlan := GetActivePlan(planId, branch)
|
|
if activePlan == nil {
|
|
go notify.NotifyErr(notify.SeverityError, fmt.Errorf("active plan not found for plan %s and branch %s", planId, branch))
|
|
|
|
return nil, &shared.ApiError{
|
|
Type: shared.ApiErrorTypeOther,
|
|
Status: http.StatusInternalServerError,
|
|
Msg: fmt.Sprintf("active plan not found for plan %s and branch %s", planId, branch),
|
|
}
|
|
}
|
|
|
|
baseModelConfig := config.GetBaseModelConfig(authVars, settings, orgUserConfig)
|
|
|
|
var sysPrompt string
|
|
var tools []openai.Tool
|
|
var toolChoice *openai.ToolChoice
|
|
|
|
if baseModelConfig.PreferredOutputFormat == shared.ModelOutputFormatXml {
|
|
sysPrompt = prompts.SysDescribeXml
|
|
} else {
|
|
sysPrompt = prompts.SysDescribe
|
|
tools = []openai.Tool{
|
|
{
|
|
Type: "function",
|
|
Function: &prompts.DescribePlanFn,
|
|
},
|
|
}
|
|
choice := openai.ToolChoice{
|
|
Type: "function",
|
|
Function: openai.ToolFunction{
|
|
Name: prompts.DescribePlanFn.Name,
|
|
},
|
|
}
|
|
toolChoice = &choice
|
|
}
|
|
|
|
messages := []types.ExtendedChatMessage{
|
|
{
|
|
Role: openai.ChatMessageRoleSystem,
|
|
Content: []types.ExtendedChatMessagePart{
|
|
{
|
|
Type: openai.ChatMessagePartTypeText,
|
|
Text: sysPrompt,
|
|
},
|
|
},
|
|
},
|
|
{
|
|
Role: openai.ChatMessageRoleAssistant,
|
|
Content: []types.ExtendedChatMessagePart{
|
|
{
|
|
Type: openai.ChatMessagePartTypeText,
|
|
Text: activePlan.CurrentReplyContent,
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
reqParams := model.ModelRequestParams{
|
|
Clients: clients,
|
|
Auth: auth,
|
|
AuthVars: authVars,
|
|
Plan: plan,
|
|
ModelConfig: &config,
|
|
Purpose: "Response summary",
|
|
Messages: messages,
|
|
ModelStreamId: state.modelStreamId,
|
|
ConvoMessageId: state.replyId,
|
|
SessionId: activePlan.SessionId,
|
|
Settings: settings,
|
|
OrgUserConfig: orgUserConfig,
|
|
}
|
|
|
|
if tools != nil {
|
|
reqParams.Tools = tools
|
|
}
|
|
if toolChoice != nil {
|
|
reqParams.ToolChoice = toolChoice
|
|
}
|
|
|
|
modelRes, err := model.ModelRequest(activePlan.Ctx, reqParams)
|
|
|
|
if err != nil {
|
|
go notify.NotifyErr(notify.SeverityError, fmt.Errorf("error during plan description model call: %v", err))
|
|
|
|
return nil, &shared.ApiError{
|
|
Type: shared.ApiErrorTypeOther,
|
|
Status: http.StatusInternalServerError,
|
|
Msg: fmt.Sprintf("error during plan description model call: %v", err),
|
|
}
|
|
}
|
|
|
|
log.Println("Plan description model call complete")
|
|
|
|
content := modelRes.Content
|
|
|
|
var commitMsg string
|
|
|
|
if baseModelConfig.PreferredOutputFormat == shared.ModelOutputFormatXml {
|
|
commitMsg = utils.GetXMLContent(content, "commitMsg")
|
|
if commitMsg == "" {
|
|
go notify.NotifyErr(notify.SeverityError, fmt.Errorf("no commitMsg tag found in XML response"))
|
|
|
|
return nil, &shared.ApiError{
|
|
Type: shared.ApiErrorTypeOther,
|
|
Status: http.StatusInternalServerError,
|
|
Msg: "No commitMsg tag found in XML response",
|
|
}
|
|
}
|
|
} else {
|
|
|
|
if content == "" {
|
|
fmt.Println("no describePlan function call found in response")
|
|
|
|
go notify.NotifyErr(notify.SeverityError, fmt.Errorf("no describePlan function call found in response"))
|
|
|
|
return nil, &shared.ApiError{
|
|
Type: shared.ApiErrorTypeOther,
|
|
Status: http.StatusInternalServerError,
|
|
Msg: "No describePlan function call found in response. The model failed to generate a valid response.",
|
|
}
|
|
}
|
|
|
|
var desc shared.ConvoMessageDescription
|
|
err = json.Unmarshal([]byte(content), &desc)
|
|
if err != nil {
|
|
fmt.Printf("Error unmarshalling plan description response: %v\n", err)
|
|
|
|
go notify.NotifyErr(notify.SeverityError, fmt.Errorf("error unmarshalling plan description response: %v", err))
|
|
|
|
return nil, &shared.ApiError{
|
|
Type: shared.ApiErrorTypeOther,
|
|
Status: http.StatusInternalServerError,
|
|
Msg: fmt.Sprintf("error unmarshalling plan description response: %v", err),
|
|
}
|
|
}
|
|
commitMsg = desc.CommitMsg
|
|
}
|
|
|
|
return &db.ConvoMessageDescription{
|
|
PlanId: planId,
|
|
CommitMsg: commitMsg,
|
|
}, nil
|
|
}
|
|
|
|
type GenCommitMsgForPendingResultsParams struct {
|
|
Auth *types.ServerAuth
|
|
Plan *db.Plan
|
|
Settings *shared.PlanSettings
|
|
Current *shared.CurrentPlanState
|
|
SessionId string
|
|
Ctx context.Context
|
|
Clients map[string]model.ClientInfo
|
|
AuthVars map[string]string
|
|
}
|
|
|
|
func GenCommitMsgForPendingResults(params GenCommitMsgForPendingResultsParams) (string, error) {
|
|
auth := params.Auth
|
|
plan := params.Plan
|
|
settings := params.Settings
|
|
current := params.Current
|
|
sessionId := params.SessionId
|
|
ctx := params.Ctx
|
|
clients := params.Clients
|
|
authVars := params.AuthVars
|
|
|
|
config := settings.GetModelPack().CommitMsg
|
|
|
|
s := ""
|
|
|
|
num := 0
|
|
for _, desc := range current.ConvoMessageDescriptions {
|
|
if desc.WroteFiles && desc.DidBuild && len(desc.BuildPathsInvalidated) == 0 && desc.AppliedAt == nil {
|
|
s += desc.CommitMsg + "\n"
|
|
num++
|
|
}
|
|
}
|
|
|
|
if num <= 1 {
|
|
return s, nil
|
|
}
|
|
|
|
prompt := "Pending changes:\n\n" + s
|
|
|
|
messages := []types.ExtendedChatMessage{
|
|
{
|
|
Role: openai.ChatMessageRoleSystem,
|
|
Content: []types.ExtendedChatMessagePart{
|
|
{
|
|
Type: openai.ChatMessagePartTypeText,
|
|
Text: prompts.SysPendingResults,
|
|
},
|
|
},
|
|
},
|
|
{
|
|
Role: openai.ChatMessageRoleUser,
|
|
Content: []types.ExtendedChatMessagePart{
|
|
{
|
|
Type: openai.ChatMessagePartTypeText,
|
|
Text: prompt,
|
|
},
|
|
},
|
|
},
|
|
}
|
|
|
|
modelRes, err := model.ModelRequest(ctx, model.ModelRequestParams{
|
|
Clients: clients,
|
|
AuthVars: authVars,
|
|
Auth: auth,
|
|
Plan: plan,
|
|
ModelConfig: &config,
|
|
Purpose: "Commit message",
|
|
Messages: messages,
|
|
SessionId: sessionId,
|
|
Settings: settings,
|
|
})
|
|
|
|
if err != nil {
|
|
fmt.Println("Generate commit message error:", err)
|
|
|
|
return "", err
|
|
}
|
|
|
|
content := modelRes.Content
|
|
|
|
if content == "" {
|
|
return "", fmt.Errorf("no response from model")
|
|
}
|
|
|
|
return content, nil
|
|
}
|