Files
cursor-byok/internal/backend/agent/model/create_plan_progress.go
2026-06-30 10:38:52 +08:00

98 lines
2.3 KiB
Go

package modeladapter
import (
"strings"
"time"
"google.golang.org/protobuf/encoding/protojson"
"cursor/gen/agentv1"
runtimecore "cursor/internal/backend/agent/core"
)
func emitCreatePlanToolProgress(
sink func(ModelEvent) error,
provider string,
model string,
callID string,
rawArgs string,
argsTextDelta string,
lastSnapshot *string,
) error {
if sink == nil || lastSnapshot == nil {
return nil
}
trimmedCallID := strings.TrimSpace(callID)
if trimmedCallID == "" {
return nil
}
args, ok := createPlanArgsProgressSnapshot(rawArgs)
if !ok {
return nil
}
signatureBytes, err := protojson.MarshalOptions{UseProtoNames: true}.Marshal(args)
if err != nil {
return err
}
signature := string(signatureBytes)
if signature == "" || signature == *lastSnapshot {
return nil
}
*lastSnapshot = signature
if err := sink(ModelEvent{
Kind: ModelEventKindPartialToolCall,
OccurredAt: time.Now().UTC(),
Provider: provider,
Model: model,
ToolCallID: trimmedCallID,
ArgsTextDelta: argsTextDelta,
ToolCall: &agentv1.ToolCall{
Tool: &agentv1.ToolCall_CreatePlanToolCall{
CreatePlanToolCall: &agentv1.CreatePlanToolCall{
Args: args,
},
},
},
}); err != nil {
return err
}
return nil
}
func createPlanArgsProgressSnapshot(rawArgs string) (*agentv1.CreatePlanArgs, bool) {
trimmed := strings.TrimSpace(rawArgs)
if trimmed == "" {
return nil, false
}
if args, err := runtimecore.DecodeCreatePlanArgsJSON([]byte(trimmed)); err == nil && hasCreatePlanArgsProgress(args) {
return args, true
}
args := &agentv1.CreatePlanArgs{}
if value, found, _ := extractJSONStringFieldPrefix(trimmed, "plan"); found {
args.Plan = value
}
if value, found, _ := extractJSONStringFieldPrefix(trimmed, "overview"); found {
args.Overview = value
}
if value, found, complete := extractJSONStringFieldPrefix(trimmed, "name"); found && complete {
args.Name = strings.TrimSpace(value)
}
if !hasCreatePlanArgsProgress(args) {
return nil, false
}
return args, true
}
func hasCreatePlanArgsProgress(args *agentv1.CreatePlanArgs) bool {
if args == nil {
return false
}
return args.GetPlan() != "" ||
args.GetOverview() != "" ||
args.GetName() != "" ||
args.GetIsProject() ||
len(args.GetTodos()) > 0 ||
len(args.GetPhases()) > 0
}