fix(forwarder): handle Cursor summarize actions

Map Cursor's protocol-level SummarizeAction to manual context compaction while keeping the legacy /compact directive disabled.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
DedSecer
2026-07-30 19:32:42 +08:00
co-authored by Cursor
parent 17f30a8852
commit 4451a6df3b
4 changed files with 295 additions and 5 deletions
+36
View File
@@ -672,6 +672,7 @@ func (service *Service) decodeInboundIntent(requestID string, message *agentv1.A
default:
return InboundIntent{}, fmt.Errorf("unsupported client message kind: %s", clientKind)
}
intent.ManualCompaction = resolveInboundManualCompaction(message, intent.UserMessage)
return intent, nil
}
@@ -751,6 +752,7 @@ func (service *Service) handleRunIntent(intent InboundIntent) error {
stream.mu.Lock()
stream.ThinkingEffort = strings.TrimSpace(intent.ThinkingEffort)
stream.SubagentModelOverrides = cloneSubagentModelOverrides(intent.SubagentModelOverrides)
stream.ManualCompaction = intent.ManualCompaction
stream.PendingProviderAction = providerActionNone
stream.PendingCompaction = nil
stream.PendingExecs = make(map[string]runtimecore.PendingExec)
@@ -788,6 +790,7 @@ func (service *Service) handleRunIntent(intent InboundIntent) error {
"subagent_model_override_count": len(intent.SubagentModelOverrides),
"subagent_model_overrides": subagentModelOverrideSummaries(intent.SubagentModelOverrides),
"latest_user_text": userMessageText(intent.UserMessage),
"manual_compaction_requested": intent.ManualCompaction.Requested,
})
if err := service.publishCheckpoint(intent.RequestID, intent.ConversationID); err != nil {
return err
@@ -2643,6 +2646,38 @@ func conversationActionIsResume(action *agentv1.ConversationAction) bool {
return ok
}
func inboundConversationAction(message *agentv1.AgentClientMessage) *agentv1.ConversationAction {
if message == nil {
return nil
}
if action := message.GetConversationAction(); action != nil {
return action
}
if runRequest := message.GetRunRequest(); runRequest != nil {
return runRequest.GetAction()
}
return nil
}
func conversationActionIsSummarize(action *agentv1.ConversationAction) bool {
if action == nil {
return false
}
_, ok := action.GetAction().(*agentv1.ConversationAction_SummarizeAction)
return ok
}
func resolveInboundManualCompaction(message *agentv1.AgentClientMessage, userMessage *agentv1.UserMessage) manualCompactionDirective {
instruction, requested := parseManualCompactionRequest(userMessage)
if conversationActionIsSummarize(inboundConversationAction(message)) {
requested = true
}
return manualCompactionDirective{
Requested: requested,
Instruction: instruction,
}
}
func conversationActionStartsRun(action *agentv1.ConversationAction) bool {
if action == nil {
return false
@@ -2650,6 +2685,7 @@ func conversationActionStartsRun(action *agentv1.ConversationAction) bool {
switch action.GetAction().(type) {
case *agentv1.ConversationAction_UserMessageAction,
*agentv1.ConversationAction_ResumeAction,
*agentv1.ConversationAction_SummarizeAction,
*agentv1.ConversationAction_StartPlanAction,
*agentv1.ConversationAction_ExecutePlanAction:
return true