mirror of
https://wget.la/https://github.com/leookun/cursor-byok
synced 2026-08-20 21:17:47 +08:00
Merge pull request #306 from ProtectCookies/main
fix(network): 修复长耗时请求被误报「Network disconnected」中断的问题
This commit is contained in:
@@ -125,8 +125,8 @@
|
||||
"refs": [
|
||||
{
|
||||
"file": "src/views/Config.vue",
|
||||
"line": 51,
|
||||
"column": 1
|
||||
"line": 50,
|
||||
"column": 48
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -149,8 +149,8 @@
|
||||
"refs": [
|
||||
{
|
||||
"file": "src/components/HomeMetricsCard.vue",
|
||||
"line": 338,
|
||||
"column": 1
|
||||
"line": 337,
|
||||
"column": 65
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -366,8 +366,8 @@
|
||||
"refs": [
|
||||
{
|
||||
"file": "src/views/Config.vue",
|
||||
"line": 65,
|
||||
"column": 1
|
||||
"line": 64,
|
||||
"column": 48
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -483,8 +483,8 @@
|
||||
"refs": [
|
||||
{
|
||||
"file": "src/components/ModelAdapterTestCard.vue",
|
||||
"line": 146,
|
||||
"column": 1
|
||||
"line": 145,
|
||||
"column": 7
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -531,8 +531,8 @@
|
||||
"refs": [
|
||||
{
|
||||
"file": "src/components/ModelAdapterTestCard.vue",
|
||||
"line": 125,
|
||||
"column": 1
|
||||
"line": 124,
|
||||
"column": 60
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -604,8 +604,8 @@
|
||||
},
|
||||
{
|
||||
"file": "src/components/CursorAccountCard.vue",
|
||||
"line": 188,
|
||||
"column": 1
|
||||
"line": 187,
|
||||
"column": 11
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -1473,8 +1473,8 @@
|
||||
"refs": [
|
||||
{
|
||||
"file": "src/components/HomeMetricsCard.vue",
|
||||
"line": 390,
|
||||
"column": 1
|
||||
"line": 389,
|
||||
"column": 65
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -1750,8 +1750,8 @@
|
||||
"refs": [
|
||||
{
|
||||
"file": "src/components/HomeMetricsCard.vue",
|
||||
"line": 342,
|
||||
"column": 1
|
||||
"line": 341,
|
||||
"column": 23
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -2666,8 +2666,8 @@
|
||||
"refs": [
|
||||
{
|
||||
"file": "src/components/CursorAccountCard.vue",
|
||||
"line": 170,
|
||||
"column": 1
|
||||
"line": 169,
|
||||
"column": 53
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -2777,8 +2777,8 @@
|
||||
"refs": [
|
||||
{
|
||||
"file": "src/views/Config.vue",
|
||||
"line": 77,
|
||||
"column": 1
|
||||
"line": 76,
|
||||
"column": 48
|
||||
}
|
||||
]
|
||||
},
|
||||
@@ -2854,8 +2854,8 @@
|
||||
"refs": [
|
||||
{
|
||||
"file": "src/components/CursorAccountCard.vue",
|
||||
"line": 173,
|
||||
"column": 1
|
||||
"line": 172,
|
||||
"column": 81
|
||||
}
|
||||
]
|
||||
},
|
||||
|
||||
@@ -691,6 +691,20 @@ func (host *Host) rebuildLocked(cfg serverconfig.Config) error {
|
||||
return nil
|
||||
}),
|
||||
),
|
||||
// The always-local extension probes NetworkService/IsConnected roughly 10s
|
||||
// after any slow request starts. A 404 here is treated as "network
|
||||
// disconnected" and aborts in-flight work (e.g. commit message
|
||||
// generation) even while the model is still streaming. Always answer OK.
|
||||
server.POST("/aiserver.v1.NetworkService/IsConnected",
|
||||
server.Name("network_is_connected"),
|
||||
server.ConnectUnary(),
|
||||
server.Local(upstream.MockProtoAction(routeDeps, upstream.CompatRouteConfig{
|
||||
Name: "network_is_connected",
|
||||
StatusCode: http.StatusOK,
|
||||
MockProtoType: "aiserver.v1.IsConnectedResponse",
|
||||
MockBuilder: upstream.EmptyMockBuilder,
|
||||
})),
|
||||
),
|
||||
server.Any("/aiserver.v1.NetworkService/*",
|
||||
server.Name("network_service"),
|
||||
server.HTTP(),
|
||||
|
||||
@@ -451,6 +451,8 @@ func newProtoMessage(typeName string) (proto.Message, error) {
|
||||
return &aiserverv1.SubmitLogsResponse{}, nil
|
||||
case "aiserver.v1.TrackEventsResponse":
|
||||
return &aiserverv1.TrackEventsResponse{}, nil
|
||||
case "aiserver.v1.IsConnectedResponse":
|
||||
return &aiserverv1.IsConnectedResponse{}, nil
|
||||
default:
|
||||
return nil, fmt.Errorf("unsupported proto message type %q", typeName)
|
||||
}
|
||||
|
||||
+26
-11
@@ -33,6 +33,14 @@ var cursorStateDisabledStatsigGates = []string{
|
||||
"disable_terminal_output_ui_streaming",
|
||||
}
|
||||
|
||||
// cursorStateEnabledStatsigGates forces gates to true. Disabling the network
|
||||
// change monitor stops the always-local extension from probing
|
||||
// NetworkService/IsConnected and aborting slow in-flight requests (such as
|
||||
// commit message generation) with "Network disconnected".
|
||||
var cursorStateEnabledStatsigGates = []string{
|
||||
"disable_network_change_monitor_local",
|
||||
}
|
||||
|
||||
// InjectCursorUserInfo synchronizes the Cursor user-level auth cache used by the
|
||||
// Settings page. It does not modify the installed Cursor app bundle.
|
||||
func InjectCursorUserInfo(email, token string) error {
|
||||
@@ -50,12 +58,13 @@ func InjectCursorUserInfo(email, token string) error {
|
||||
}
|
||||
|
||||
logger.Infof(
|
||||
"injectCursorUserInfo synced path=%s email=%s membership=%s subscription=%s disabled_statsig_gates=%s",
|
||||
"injectCursorUserInfo synced path=%s email=%s membership=%s subscription=%s disabled_statsig_gates=%s enabled_statsig_gates=%s",
|
||||
stateDBPath,
|
||||
values["cursorAuth/cachedEmail"],
|
||||
values["cursorAuth/stripeMembershipType"],
|
||||
values["cursorAuth/stripeSubscriptionStatus"],
|
||||
strings.Join(cursorStateDisabledStatsigGates, ","),
|
||||
strings.Join(cursorStateEnabledStatsigGates, ","),
|
||||
)
|
||||
return nil
|
||||
}
|
||||
@@ -120,7 +129,7 @@ func syncCursorAuthStateDB(path string, values map[string]string) error {
|
||||
}
|
||||
}
|
||||
|
||||
if err := disableCursorStatsigGates(ctx, tx); err != nil {
|
||||
if err := syncCursorStatsigGateOverrides(ctx, tx); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
@@ -131,7 +140,7 @@ func syncCursorAuthStateDB(path string, values map[string]string) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func disableCursorStatsigGates(ctx context.Context, tx *sql.Tx) error {
|
||||
func syncCursorStatsigGateOverrides(ctx context.Context, tx *sql.Tx) error {
|
||||
var raw []byte
|
||||
err := tx.QueryRowContext(ctx, "SELECT value FROM ItemTable WHERE key = ?", cursorStateStatsigBootstrapKey).Scan(&raw)
|
||||
if err != nil {
|
||||
@@ -154,9 +163,15 @@ func disableCursorStatsigGates(ctx context.Context, tx *sql.Tx) error {
|
||||
|
||||
hashUsed, _ := payload["hash_used"].(string)
|
||||
for _, gate := range cursorStateDisabledStatsigGates {
|
||||
disableCursorStatsigGate(featureGates, gate)
|
||||
setCursorStatsigGate(featureGates, gate, false, "local_disabled")
|
||||
if strings.EqualFold(hashUsed, "djb2") {
|
||||
disableCursorStatsigGate(featureGates, cursorStateDJB2Hash(gate))
|
||||
setCursorStatsigGate(featureGates, cursorStateDJB2Hash(gate), false, "local_disabled")
|
||||
}
|
||||
}
|
||||
for _, gate := range cursorStateEnabledStatsigGates {
|
||||
setCursorStatsigGate(featureGates, gate, true, "local_enabled")
|
||||
if strings.EqualFold(hashUsed, "djb2") {
|
||||
setCursorStatsigGate(featureGates, cursorStateDJB2Hash(gate), true, "local_enabled")
|
||||
}
|
||||
}
|
||||
|
||||
@@ -170,21 +185,21 @@ func disableCursorStatsigGates(ctx context.Context, tx *sql.Tx) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func disableCursorStatsigGate(featureGates map[string]any, key string) {
|
||||
func setCursorStatsigGate(featureGates map[string]any, key string, value bool, rule string) {
|
||||
gate, _ := featureGates[key].(map[string]any)
|
||||
if gate == nil {
|
||||
gate = map[string]any{
|
||||
"name": key,
|
||||
"rule_id": "local_disabled",
|
||||
"ruleID": "local_disabled",
|
||||
"group_name": "local_disabled",
|
||||
"groupName": "local_disabled",
|
||||
"rule_id": rule,
|
||||
"ruleID": rule,
|
||||
"group_name": rule,
|
||||
"groupName": rule,
|
||||
"id_type": "userID",
|
||||
"idType": "userID",
|
||||
}
|
||||
featureGates[key] = gate
|
||||
}
|
||||
gate["value"] = false
|
||||
gate["value"] = value
|
||||
}
|
||||
|
||||
func cursorStateDJB2Hash(value string) string {
|
||||
|
||||
@@ -17785,6 +17785,14 @@ message IsAllowedFreeTrialUsageResponse {
|
||||
bool is_allowed = 1;
|
||||
}
|
||||
|
||||
// Copied from: local:aiserver.v1.IsConnectedRequest
|
||||
message IsConnectedRequest {
|
||||
}
|
||||
|
||||
// Copied from: local:aiserver.v1.IsConnectedResponse
|
||||
message IsConnectedResponse {
|
||||
}
|
||||
|
||||
// Copied from: local:aiserver.v1.IsCursorPredictionEnabledRequest (var: An)
|
||||
message IsCursorPredictionEnabledRequest {
|
||||
}
|
||||
@@ -36919,6 +36927,11 @@ service MetricsService {
|
||||
rpc ReportGauge(ReportMetricsRequest) returns (ReportMetricsResponse) {}
|
||||
}
|
||||
|
||||
// Source: aiserver.v1.NetworkService
|
||||
service NetworkService {
|
||||
rpc IsConnected(IsConnectedRequest) returns (IsConnectedResponse) {}
|
||||
}
|
||||
|
||||
// Source: aiserver.v1.PerformanceEventService (var: i)
|
||||
service PerformanceEventService {
|
||||
rpc SubmitPerformanceEvents(SubmitPerformanceEventsRequest) returns (SubmitPerformanceEventsResponse) {}
|
||||
|
||||
Reference in New Issue
Block a user