From d29863aae03d7a58fb08ffad3721f79b40420f68 Mon Sep 17 00:00:00 2001 From: sawka Date: Fri, 29 Aug 2025 14:19:15 -0700 Subject: [PATCH] track if AI requests are local to see feature usage --- pkg/telemetry/telemetrydata/telemetrydata.go | 1 + pkg/waveai/waveai.go | 18 ++++++++++++++++++ 2 files changed, 19 insertions(+) diff --git a/pkg/telemetry/telemetrydata/telemetrydata.go b/pkg/telemetry/telemetrydata/telemetrydata.go index 52b163f0d8..d05c6ca5e5 100644 --- a/pkg/telemetry/telemetrydata/telemetrydata.go +++ b/pkg/telemetry/telemetrydata/telemetrydata.go @@ -77,6 +77,7 @@ type TEventProps struct { PanicType string `json:"debug:panictype,omitempty"` BlockView string `json:"block:view,omitempty"` AiBackendType string `json:"ai:backendtype,omitempty"` + AiLocal bool `json:"ai:local,omitempty"` WshCmd string `json:"wsh:cmd,omitempty"` WshHadError bool `json:"wsh:haderror,omitempty"` ConnType string `json:"conn:conntype,omitempty"` diff --git a/pkg/waveai/waveai.go b/pkg/waveai/waveai.go index 89c9bdfc4f..89f1afe9a5 100644 --- a/pkg/waveai/waveai.go +++ b/pkg/waveai/waveai.go @@ -6,6 +6,8 @@ package waveai import ( "context" "log" + "net/url" + "strings" "github.com/wavetermdev/waveterm/pkg/telemetry" "github.com/wavetermdev/waveterm/pkg/telemetry/telemetrydata" @@ -52,6 +54,20 @@ func IsCloudAIRequest(opts *wshrpc.WaveAIOptsType) bool { return opts.BaseURL == "" && opts.APIToken == "" } +func isLocalURL(baseURL string) bool { + if baseURL == "" { + return false + } + + u, err := url.Parse(baseURL) + if err != nil { + return false + } + + host := strings.ToLower(u.Hostname()) + return host == "localhost" || host == "127.0.0.1" || host == "0.0.0.0" || strings.HasPrefix(host, "192.168.") || strings.HasPrefix(host, "10.") || (strings.HasPrefix(host, "172.") && len(host) > 4) +} + func makeAIError(err error) wshrpc.RespOrErrorUnion[wshrpc.WaveAIPacketType] { return wshrpc.RespOrErrorUnion[wshrpc.WaveAIPacketType]{Error: err} } @@ -88,10 +104,12 @@ func RunAICommand(ctx context.Context, request wshrpc.WaveAIStreamRequest) chan log.Printf("no backend found for %s\n", request.Opts.APIType) return nil } + aiLocal := backendType != "wave" && isLocalURL(request.Opts.BaseURL) telemetry.GoRecordTEventWrap(&telemetrydata.TEvent{ Event: "action:runaicmd", Props: telemetrydata.TEventProps{ AiBackendType: backendType, + AiLocal: aiLocal, }, })