mirror of
https://wget.la/https://github.com/leookun/cursor-byok
synced 2026-08-17 03:27:02 +08:00
fix(prompt): persist cursor command replay context
This commit is contained in:
@@ -26,13 +26,10 @@ func BuildUserMessageReplayMessage(userMessage *agentv1.UserMessage) (Message, b
|
|||||||
|
|
||||||
func buildUserReplayMessage(text string, selectedContext *agentv1.SelectedContext) (Message, bool) {
|
func buildUserReplayMessage(text string, selectedContext *agentv1.SelectedContext) (Message, bool) {
|
||||||
images := buildSelectedImageContentParts(selectedContext)
|
images := buildSelectedImageContentParts(selectedContext)
|
||||||
sections := make([]string, 0, 5)
|
sections := make([]string, 0, 4)
|
||||||
if text != "" {
|
if text != "" {
|
||||||
sections = append(sections, formatMessageText(fmt.Sprintf("<user_query>\n%s\n</user_query>", text)))
|
sections = append(sections, formatMessageText(fmt.Sprintf("<user_query>\n%s\n</user_query>", text)))
|
||||||
}
|
}
|
||||||
if cursorCommands := buildSelectedCursorCommandsPromptSection(selectedContext); cursorCommands != "" {
|
|
||||||
sections = append(sections, cursorCommands)
|
|
||||||
}
|
|
||||||
if ideState := buildSelectedIDEStatePromptSection(selectedContext); ideState != "" {
|
if ideState := buildSelectedIDEStatePromptSection(selectedContext); ideState != "" {
|
||||||
sections = append(sections, ideState)
|
sections = append(sections, ideState)
|
||||||
}
|
}
|
||||||
@@ -65,6 +62,20 @@ func buildUserReplayMessage(text string, selectedContext *agentv1.SelectedContex
|
|||||||
}, true
|
}, true
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// BuildSelectedCursorCommandsReplayMessage renders command content for new history entries.
|
||||||
|
// Keeping this separate from BuildUserMessageReplayMessage prevents old user_message entries
|
||||||
|
// from changing their model-visible meaning after a backend upgrade.
|
||||||
|
func BuildSelectedCursorCommandsReplayMessage(userMessage *agentv1.UserMessage) (Message, bool) {
|
||||||
|
if userMessage == nil {
|
||||||
|
return Message{}, false
|
||||||
|
}
|
||||||
|
content := buildSelectedCursorCommandsPromptSection(userMessage.GetSelectedContext())
|
||||||
|
if content == "" {
|
||||||
|
return Message{}, false
|
||||||
|
}
|
||||||
|
return Message{Role: "user", Content: content}, true
|
||||||
|
}
|
||||||
|
|
||||||
func buildSelectedCursorCommandsPromptSection(selectedContext *agentv1.SelectedContext) string {
|
func buildSelectedCursorCommandsPromptSection(selectedContext *agentv1.SelectedContext) string {
|
||||||
if selectedContext == nil || len(selectedContext.GetCursorCommands()) == 0 {
|
if selectedContext == nil || len(selectedContext.GetCursorCommands()) == 0 {
|
||||||
return ""
|
return ""
|
||||||
|
|||||||
@@ -2,67 +2,9 @@ package promptengine
|
|||||||
|
|
||||||
import (
|
import (
|
||||||
"reflect"
|
"reflect"
|
||||||
"strings"
|
|
||||||
"testing"
|
"testing"
|
||||||
|
|
||||||
"cursor/gen/agentv1"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
func TestBuildUserMessageReplayMessageIncludesSelectedCursorCommands(t *testing.T) {
|
|
||||||
message, ok := BuildUserMessageReplayMessage(&agentv1.UserMessage{
|
|
||||||
Text: "/init",
|
|
||||||
SelectedContext: &agentv1.SelectedContext{
|
|
||||||
CursorCommands: []*agentv1.SelectedCursorCommand{
|
|
||||||
{Name: "init", Content: "Analyze the repository and create AGENTS.md."},
|
|
||||||
{Name: `review"<&`, Content: "Review the implementation."},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
if !ok {
|
|
||||||
t.Fatal("BuildUserMessageReplayMessage() returned ok=false")
|
|
||||||
}
|
|
||||||
|
|
||||||
want := strings.Join([]string{
|
|
||||||
"<user_query>\n/init\n</user_query>",
|
|
||||||
"<cursor_commands>\n" +
|
|
||||||
"<cursor_command name=\"init\">\nAnalyze the repository and create AGENTS.md.\n</cursor_command>\n\n" +
|
|
||||||
"<cursor_command name=\"review"<&\">\nReview the implementation.\n</cursor_command>\n" +
|
|
||||||
"</cursor_commands>",
|
|
||||||
}, "\n\n")
|
|
||||||
if message.Role != "user" || message.Content != want {
|
|
||||||
t.Fatalf("message = %#v, want content %q", message, want)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestBuildUserMessageReplayMessageSkipsEmptyCursorCommandsAndKeepsOrder(t *testing.T) {
|
|
||||||
message, ok := BuildUserMessageReplayMessage(&agentv1.UserMessage{
|
|
||||||
Text: "run commands",
|
|
||||||
SelectedContext: &agentv1.SelectedContext{
|
|
||||||
CursorCommands: []*agentv1.SelectedCursorCommand{
|
|
||||||
nil,
|
|
||||||
{Name: "empty", Content: " "},
|
|
||||||
{Content: "First command."},
|
|
||||||
{Name: "second", Content: "Second command."},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
if !ok {
|
|
||||||
t.Fatal("BuildUserMessageReplayMessage() returned ok=false")
|
|
||||||
}
|
|
||||||
|
|
||||||
first := strings.Index(message.Content, "First command.")
|
|
||||||
second := strings.Index(message.Content, "Second command.")
|
|
||||||
if first < 0 || second < 0 || first >= second {
|
|
||||||
t.Fatalf("cursor command order was not preserved: %q", message.Content)
|
|
||||||
}
|
|
||||||
if strings.Contains(message.Content, "empty") {
|
|
||||||
t.Fatalf("empty cursor command was not skipped: %q", message.Content)
|
|
||||||
}
|
|
||||||
if !strings.Contains(message.Content, "<cursor_command>\nFirst command.\n</cursor_command>") {
|
|
||||||
t.Fatalf("unnamed cursor command was not rendered safely: %q", message.Content)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestBuildReplayMessagesFromPendingAssistantOutputsKeepsTextAndToolCallInOneAssistantTurn(t *testing.T) {
|
func TestBuildReplayMessagesFromPendingAssistantOutputsKeepsTextAndToolCallInOneAssistantTurn(t *testing.T) {
|
||||||
raw := `{
|
raw := `{
|
||||||
"id":"1",
|
"id":"1",
|
||||||
|
|||||||
@@ -1,198 +0,0 @@
|
|||||||
package forwarder
|
|
||||||
|
|
||||||
import (
|
|
||||||
"testing"
|
|
||||||
|
|
||||||
"cursor/gen/agentv1"
|
|
||||||
)
|
|
||||||
|
|
||||||
func TestParseManualCompactionDirectiveSupportsCursorSummarize(t *testing.T) {
|
|
||||||
tests := []struct {
|
|
||||||
name string
|
|
||||||
text string
|
|
||||||
wantInstruction string
|
|
||||||
want bool
|
|
||||||
}{
|
|
||||||
{name: "compact removed", text: "/compact", want: false},
|
|
||||||
{name: "compact instruction removed", text: "/compact keep deployment details", want: false},
|
|
||||||
{name: "summarize", text: "/summarize", want: true},
|
|
||||||
{name: "summarize instruction", text: "/summarize keep failing tests", wantInstruction: "keep failing tests", want: true},
|
|
||||||
{name: "surrounding whitespace", text: " /summarize ", want: true},
|
|
||||||
{name: "similar command", text: "/summarized", want: false},
|
|
||||||
{name: "ordinary text", text: "please summarize this file", want: false},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, test := range tests {
|
|
||||||
t.Run(test.name, func(t *testing.T) {
|
|
||||||
instruction, ok := parseManualCompactionDirective(test.text)
|
|
||||||
if ok != test.want || instruction != test.wantInstruction {
|
|
||||||
t.Fatalf("parseManualCompactionDirective(%q) = (%q, %v), want (%q, %v)", test.text, instruction, ok, test.wantInstruction, test.want)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestParseManualCompactionRequestRecognizesCursorSummarizeCommand(t *testing.T) {
|
|
||||||
instruction, ok := parseManualCompactionRequest(&agentv1.UserMessage{
|
|
||||||
SelectedContext: &agentv1.SelectedContext{
|
|
||||||
CursorCommands: []*agentv1.SelectedCursorCommand{
|
|
||||||
{Name: "glass-action-summarize", Content: "/summarize"},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
if !ok || instruction != "" {
|
|
||||||
t.Fatalf("parseManualCompactionRequest() = (%q, %v), want empty instruction and true", instruction, ok)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestParseManualCompactionRequestIgnoresSummarizeMetadataWhenUserTextIsPresent(t *testing.T) {
|
|
||||||
instruction, ok := parseManualCompactionRequest(&agentv1.UserMessage{
|
|
||||||
Text: "why does /summarize not work?",
|
|
||||||
SelectedContext: &agentv1.SelectedContext{
|
|
||||||
CursorCommands: []*agentv1.SelectedCursorCommand{
|
|
||||||
{Name: "glass-action-summarize", Content: "/summarize"},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
if ok || instruction != "" {
|
|
||||||
t.Fatalf("parseManualCompactionRequest() = (%q, %v), want empty instruction and false", instruction, ok)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestParseManualCompactionRequestIgnoresOrdinaryCursorCommands(t *testing.T) {
|
|
||||||
instruction, ok := parseManualCompactionRequest(&agentv1.UserMessage{
|
|
||||||
Text: "review this implementation",
|
|
||||||
SelectedContext: &agentv1.SelectedContext{
|
|
||||||
CursorCommands: []*agentv1.SelectedCursorCommand{
|
|
||||||
nil,
|
|
||||||
{Name: "review", Content: "Review the implementation."},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
})
|
|
||||||
if ok || instruction != "" {
|
|
||||||
t.Fatalf("parseManualCompactionRequest() = (%q, %v), want empty instruction and false", instruction, ok)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestDecodeInboundIntentMapsRunRequestSummarizeActionToManualCompaction(t *testing.T) {
|
|
||||||
service := &Service{debug: newDebugRecorder("", nil, nil)}
|
|
||||||
intent, err := service.decodeInboundIntent(
|
|
||||||
"summarize-request",
|
|
||||||
newRunRequestMessage(newSummarizeConversationAction()),
|
|
||||||
"run_request",
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("decodeInboundIntent() error = %v", err)
|
|
||||||
}
|
|
||||||
if intent.Kind != "run" || !intent.StartsRun {
|
|
||||||
t.Fatalf("decodeInboundIntent() kind = %q, starts_run = %v, want run and true", intent.Kind, intent.StartsRun)
|
|
||||||
}
|
|
||||||
if intent.UserMessage != nil {
|
|
||||||
t.Fatalf("decodeInboundIntent() user_message = %#v, want nil", intent.UserMessage)
|
|
||||||
}
|
|
||||||
if !intent.ManualCompaction.Requested || intent.ManualCompaction.Instruction != "" {
|
|
||||||
t.Fatalf("decodeInboundIntent() manual_compaction = %#v, want requested with empty instruction", intent.ManualCompaction)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestResolveInboundManualCompactionSupportsStandaloneConversationAction(t *testing.T) {
|
|
||||||
directive := resolveInboundManualCompaction(&agentv1.AgentClientMessage{
|
|
||||||
Message: &agentv1.AgentClientMessage_ConversationAction{
|
|
||||||
ConversationAction: newSummarizeConversationAction(),
|
|
||||||
},
|
|
||||||
}, nil)
|
|
||||||
if !directive.Requested || directive.Instruction != "" {
|
|
||||||
t.Fatalf("resolveInboundManualCompaction() = %#v, want requested with empty instruction", directive)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestResolveInboundManualCompactionIgnoresOtherStandaloneActions(t *testing.T) {
|
|
||||||
directive := resolveInboundManualCompaction(&agentv1.AgentClientMessage{
|
|
||||||
Message: &agentv1.AgentClientMessage_ConversationAction{
|
|
||||||
ConversationAction: &agentv1.ConversationAction{
|
|
||||||
Action: &agentv1.ConversationAction_CancelAction{CancelAction: &agentv1.CancelAction{}},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}, nil)
|
|
||||||
if directive.Requested {
|
|
||||||
t.Fatalf("resolveInboundManualCompaction() = %#v, want not requested", directive)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestDecodeInboundIntentDoesNotMapOrdinaryRunActionsToManualCompaction(t *testing.T) {
|
|
||||||
tests := []struct {
|
|
||||||
name string
|
|
||||||
text string
|
|
||||||
}{
|
|
||||||
{name: "ordinary message", text: "review this implementation"},
|
|
||||||
{name: "compact command removed", text: "/compact"},
|
|
||||||
}
|
|
||||||
|
|
||||||
for _, test := range tests {
|
|
||||||
t.Run(test.name, func(t *testing.T) {
|
|
||||||
service := &Service{debug: newDebugRecorder("", nil, nil)}
|
|
||||||
intent, err := service.decodeInboundIntent(
|
|
||||||
"ordinary-request",
|
|
||||||
newRunRequestMessage(&agentv1.ConversationAction{
|
|
||||||
Action: &agentv1.ConversationAction_UserMessageAction{
|
|
||||||
UserMessageAction: &agentv1.UserMessageAction{
|
|
||||||
UserMessage: &agentv1.UserMessage{Text: test.text},
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}),
|
|
||||||
"run_request",
|
|
||||||
)
|
|
||||||
if err != nil {
|
|
||||||
t.Fatalf("decodeInboundIntent() error = %v", err)
|
|
||||||
}
|
|
||||||
if intent.ManualCompaction.Requested {
|
|
||||||
t.Fatalf("decodeInboundIntent() manual_compaction = %#v, want not requested", intent.ManualCompaction)
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestSummarizeConversationActionStartsRun(t *testing.T) {
|
|
||||||
if !conversationActionStartsRun(newSummarizeConversationAction()) {
|
|
||||||
t.Fatal("conversationActionStartsRun(summarize) = false, want true")
|
|
||||||
}
|
|
||||||
if conversationActionStartsRun(&agentv1.ConversationAction{
|
|
||||||
Action: &agentv1.ConversationAction_CancelAction{CancelAction: &agentv1.CancelAction{}},
|
|
||||||
}) {
|
|
||||||
t.Fatal("conversationActionStartsRun(cancel) = true, want false")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func TestStreamManualCompactionDirectiveUsesStructuredRequest(t *testing.T) {
|
|
||||||
stream := &ActiveStream{
|
|
||||||
LatestUserText: "visible user text",
|
|
||||||
ManualCompaction: manualCompactionDirective{
|
|
||||||
Requested: true,
|
|
||||||
Instruction: "keep decisions",
|
|
||||||
},
|
|
||||||
}
|
|
||||||
instruction, ok := streamManualCompactionDirective(stream)
|
|
||||||
if !ok || instruction != "keep decisions" {
|
|
||||||
t.Fatalf("streamManualCompactionDirective() = (%q, %v), want (%q, true)", instruction, ok, "keep decisions")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func newRunRequestMessage(action *agentv1.ConversationAction) *agentv1.AgentClientMessage {
|
|
||||||
conversationID := "test-conversation"
|
|
||||||
return &agentv1.AgentClientMessage{
|
|
||||||
Message: &agentv1.AgentClientMessage_RunRequest{
|
|
||||||
RunRequest: &agentv1.AgentRunRequest{
|
|
||||||
ConversationId: &conversationID,
|
|
||||||
Action: action,
|
|
||||||
},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
func newSummarizeConversationAction() *agentv1.ConversationAction {
|
|
||||||
return &agentv1.ConversationAction{
|
|
||||||
Action: &agentv1.ConversationAction_SummarizeAction{
|
|
||||||
SummarizeAction: &agentv1.SummarizeAction{},
|
|
||||||
},
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@@ -9,6 +9,8 @@ import (
|
|||||||
modeladapter "cursor/internal/backend/agent/model"
|
modeladapter "cursor/internal/backend/agent/model"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const promptContextSourceSelectedCursorCommands = "selected_cursor_commands"
|
||||||
|
|
||||||
func newPromptContextMessage(source string, message modeladapter.Message, persist bool) PromptContextMessage {
|
func newPromptContextMessage(source string, message modeladapter.Message, persist bool) PromptContextMessage {
|
||||||
context := PromptContextMessage{
|
context := PromptContextMessage{
|
||||||
Source: strings.TrimSpace(source),
|
Source: strings.TrimSpace(source),
|
||||||
|
|||||||
@@ -18,6 +18,10 @@ const (
|
|||||||
promptGuardSelectedFileChars = 16000
|
promptGuardSelectedFileChars = 16000
|
||||||
promptGuardSelectedFilesTotalChars = 64000
|
promptGuardSelectedFilesTotalChars = 64000
|
||||||
promptGuardSelectedFilesMaxCount = 12
|
promptGuardSelectedFilesMaxCount = 12
|
||||||
|
promptGuardCursorCommandNameChars = 256
|
||||||
|
promptGuardCursorCommandChars = 12000
|
||||||
|
promptGuardCursorCommandsTotalChars = 32000
|
||||||
|
promptGuardCursorCommandsMaxCount = 8
|
||||||
promptGuardRequestFileChars = 16000
|
promptGuardRequestFileChars = 16000
|
||||||
promptGuardRequestFilesTotalChars = 64000
|
promptGuardRequestFilesTotalChars = 64000
|
||||||
promptGuardRequestFilesMaxCount = 12
|
promptGuardRequestFilesMaxCount = 12
|
||||||
@@ -106,11 +110,42 @@ func guardSelectedContext(selectedContext *agentv1.SelectedContext) *agentv1.Sel
|
|||||||
return selectedContext
|
return selectedContext
|
||||||
}
|
}
|
||||||
cloned.Files = guardSelectedFiles(cloned.GetFiles())
|
cloned.Files = guardSelectedFiles(cloned.GetFiles())
|
||||||
|
cloned.CursorCommands = guardSelectedCursorCommands(cloned.GetCursorCommands())
|
||||||
cloned.SelectedSkills = guardAgentSkills(cloned.GetSelectedSkills())
|
cloned.SelectedSkills = guardAgentSkills(cloned.GetSelectedSkills())
|
||||||
cloned.ExtraContext = guardStringSlice(cloned.GetExtraContext(), "selected_context.extra_context", promptGuardRealtimeTextChars, promptGuardRealtimeTextChars, promptGuardAgentSkillsMaxCount)
|
cloned.ExtraContext = guardStringSlice(cloned.GetExtraContext(), "selected_context.extra_context", promptGuardRealtimeTextChars, promptGuardRealtimeTextChars, promptGuardAgentSkillsMaxCount)
|
||||||
return cloned
|
return cloned
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func guardSelectedCursorCommands(commands []*agentv1.SelectedCursorCommand) []*agentv1.SelectedCursorCommand {
|
||||||
|
if len(commands) == 0 {
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
result := make([]*agentv1.SelectedCursorCommand, 0, minInt(len(commands), promptGuardCursorCommandsMaxCount))
|
||||||
|
remaining := promptGuardCursorCommandsTotalChars
|
||||||
|
for _, command := range commands {
|
||||||
|
if command == nil || len(result) >= promptGuardCursorCommandsMaxCount {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
content := strings.TrimSpace(command.GetContent())
|
||||||
|
if content == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
limit := minInt(promptGuardCursorCommandChars, remaining)
|
||||||
|
if limit <= 0 {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
cloned, ok := proto.Clone(command).(*agentv1.SelectedCursorCommand)
|
||||||
|
if !ok || cloned == nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
cloned.Name = truncatePromptGuardText("selected_context.cursor_commands.name", strings.TrimSpace(cloned.GetName()), promptGuardCursorCommandNameChars)
|
||||||
|
cloned.Content = truncatePromptGuardText("selected_context.cursor_commands.content", content, limit)
|
||||||
|
remaining -= promptGuardRuneCount(cloned.GetContent())
|
||||||
|
result = append(result, cloned)
|
||||||
|
}
|
||||||
|
return result
|
||||||
|
}
|
||||||
|
|
||||||
func guardSelectedFiles(files []*agentv1.SelectedFile) []*agentv1.SelectedFile {
|
func guardSelectedFiles(files []*agentv1.SelectedFile) []*agentv1.SelectedFile {
|
||||||
if len(files) == 0 {
|
if len(files) == 0 {
|
||||||
return nil
|
return nil
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import (
|
|||||||
interactionbridge "cursor/internal/backend/agent/bridge/interaction"
|
interactionbridge "cursor/internal/backend/agent/bridge/interaction"
|
||||||
runtimecore "cursor/internal/backend/agent/core"
|
runtimecore "cursor/internal/backend/agent/core"
|
||||||
modeladapter "cursor/internal/backend/agent/model"
|
modeladapter "cursor/internal/backend/agent/model"
|
||||||
|
promptengine "cursor/internal/backend/agent/prompt"
|
||||||
protocol "cursor/internal/backend/agent/protocol"
|
protocol "cursor/internal/backend/agent/protocol"
|
||||||
)
|
)
|
||||||
|
|
||||||
@@ -2335,7 +2336,8 @@ func buildRunEntries(intent InboundIntent, effectiveMode agentv1.AgentMode, turn
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
if intent.UserMessage != nil {
|
if intent.UserMessage != nil {
|
||||||
payload, err := protojson.Marshal(normalizeUserMessageForStorage(intent.UserMessage))
|
normalized := normalizeUserMessageForStorage(intent.UserMessage)
|
||||||
|
payload, err := protojson.Marshal(normalized)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
return nil, err
|
return nil, err
|
||||||
}
|
}
|
||||||
@@ -2346,6 +2348,13 @@ func buildRunEntries(intent InboundIntent, effectiveMode agentv1.AgentMode, turn
|
|||||||
Kind: "user_message",
|
Kind: "user_message",
|
||||||
Payload: payload,
|
Payload: payload,
|
||||||
})
|
})
|
||||||
|
if commandMessage, ok := promptengine.BuildSelectedCursorCommandsReplayMessage(normalized); ok {
|
||||||
|
entries = append(entries, newPromptContextEntry(turnSeq, intent.RequestID, newPromptContextMessage(
|
||||||
|
promptContextSourceSelectedCursorCommands,
|
||||||
|
modeladapter.Message{Role: commandMessage.Role, Content: commandMessage.Content},
|
||||||
|
true,
|
||||||
|
)))
|
||||||
|
}
|
||||||
}
|
}
|
||||||
modeEntry, err := newModeMetadataEntry(turnSeq, intent.RequestID, effectiveMode, intent.HasExplicitMode, intent.ModeSource)
|
modeEntry, err := newModeMetadataEntry(turnSeq, intent.RequestID, effectiveMode, intent.HasExplicitMode, intent.ModeSource)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
|||||||
Reference in New Issue
Block a user