From 5659a6af9edc788f2acc92d94a723cc3bb57311f Mon Sep 17 00:00:00 2001 From: archandatta <35818003+archandatta@users.noreply.github.com> Date: Fri, 31 Jul 2026 20:33:17 +0000 Subject: [PATCH] Split platform-induced API calls out of the control telemetry category MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Every documented operation emitted api_call under `control`, so the platform's own traffic — recorder polling, profile save/restore, telemetry publishing — buried the agent's browser actions. Operations now carry `x-telemetry-category` in openapi.yaml and categorygen emits the operation -> category map alongside the event-type map, so a new endpoint without a classification fails generation. Browser-control calls keep emitting api_call under `control`; VM-management calls emit platform_api_call under a new `platform` category, which is opt-in and out of the default set. api_call data also gains an optional `code` field, recorded for executePlaywrightCode and clipped to 8 KB on a rune boundary, so the event says what actually ran. Co-Authored-By: Claude Opus 5 --- server/cmd/api/api/middleware.go | 44 +- server/cmd/api/api/middleware_test.go | 110 +++- server/cmd/api/api/playwright.go | 2 + server/cmd/api/api/telemetry.go | 3 + server/cmd/api/api/telemetry_test.go | 1 + server/e2e/e2e_otlp_storage_test.go | 7 +- server/lib/cdpmonitor/handlers.go | 2 +- server/lib/cdpmonitor/util.go | 35 +- server/lib/events/capture.go | 40 ++ server/lib/events/capture_test.go | 40 ++ server/lib/events/category_gen.go | 68 ++ server/lib/events/category_test.go | 47 ++ server/lib/events/event.go | 6 +- server/lib/oapi/oapi.go | 882 ++++++++++++++------------ server/openapi.yaml | 107 +++- server/scripts/categorygen/main.go | 126 +++- 16 files changed, 1061 insertions(+), 459 deletions(-) create mode 100644 server/lib/events/capture.go create mode 100644 server/lib/events/capture_test.go create mode 100644 server/lib/events/category_test.go diff --git a/server/cmd/api/api/middleware.go b/server/cmd/api/api/middleware.go index a558199a..e1196a18 100644 --- a/server/cmd/api/api/middleware.go +++ b/server/cmd/api/api/middleware.go @@ -19,6 +19,18 @@ type telemetryCtxKey struct{} type telemetryRequestCtx struct { operationID string + code string +} + +// RecordTelemetryCode attaches code submitted with the request to its api_call +// event, capped like every other captured string. It is a no-op when telemetry +// is off or the request is not one the middleware tracks. +func RecordTelemetryCode(ctx context.Context, code string) { + tc, ok := ctx.Value(telemetryCtxKey{}).(*telemetryRequestCtx) + if !ok { + return + } + tc.code = events.TruncateCaptured(code, events.CapturedFieldCap) } // Process-wide toggle for the api_call middleware. Flipped by @@ -35,9 +47,12 @@ func DisableTelemetryMiddleware() { telemetryMiddlewareEnabled.Store(false) } // TelemetryMiddlewareEnabled reports the current state. func TelemetryMiddlewareEnabled() bool { return telemetryMiddlewareEnabled.Load() } -// TelemetryHTTPMiddleware emits a BrowserApiCallEvent per documented operation, -// capturing the final status and wall-clock duration. publish is wired to -// TelemetrySession.Publish; the middleware ignores the returns. +// TelemetryHTTPMiddleware emits one event per documented operation, capturing +// the final status and wall-clock duration. Operations that drive the browser +// emit api_call under control; operations that manage the VM emit +// platform_api_call under platform, per the operation's x-telemetry-category in +// openapi.yaml. publish is wired to TelemetrySession.Publish; the middleware +// ignores the returns. func TelemetryHTTPMiddleware(publish func(events.Event) (events.Envelope, bool)) func(http.Handler) http.Handler { return func(next http.Handler) http.Handler { return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { @@ -55,16 +70,21 @@ func TelemetryHTTPMiddleware(publish func(events.Event) (events.Envelope, bool)) if tc.operationID == "" { return } - data, _ := json.Marshal(oapi.BrowserApiCallEventData{ + eventData := oapi.BrowserApiCallEventData{ RequestId: chiMiddleware.GetReqID(ctx), OperationId: tc.operationID, Status: ww.Status(), DurationMs: float32(time.Since(start).Microseconds()) / 1000.0, - }) + } + if tc.code != "" { + eventData.Code = &tc.code + } + data, _ := json.Marshal(eventData) + eventType, category := apiCallEvent(tc.operationID) publish(events.Event{ Ts: time.Now().UnixMicro(), - Type: "api_call", - Category: events.Control, + Type: eventType, + Category: category, Source: oapi.BrowserEventSource{Kind: oapi.KernelApi}, Data: data, }) @@ -72,6 +92,16 @@ func TelemetryHTTPMiddleware(publish func(events.Event) (events.Envelope, bool)) } } +// apiCallEvent resolves the event type and category for an operation. An +// operation missing from the generated map falls back to platform so an +// unclassified route cannot dilute the control stream. +func apiCallEvent(operationID string) (string, oapi.TelemetryEventCategory) { + if cat, ok := events.CategoryForOperation(operationID); ok && cat == events.Control { + return "api_call", events.Control + } + return "platform_api_call", events.Platform +} + // TelemetryStrictMiddleware records the matched OpenAPI operationId onto the // per-request scratch so TelemetryHTTPMiddleware can include it in the event. func TelemetryStrictMiddleware() oapi.StrictMiddlewareFunc { diff --git a/server/cmd/api/api/middleware_test.go b/server/cmd/api/api/middleware_test.go index 972967f4..b3d5719f 100644 --- a/server/cmd/api/api/middleware_test.go +++ b/server/cmd/api/api/middleware_test.go @@ -5,8 +5,10 @@ import ( "encoding/json" "net/http" "net/http/httptest" + "strings" "sync" "testing" + "unicode/utf8" chiMiddleware "github.com/go-chi/chi/v5/middleware" "github.com/stretchr/testify/assert" @@ -37,21 +39,23 @@ func (rp *recordingPublisher) snapshot() []events.Event { return out } -// Mirrors the oapi-codegen strict dispatcher: middleware chain -> inner -// handler -> response write. -func fakeStrictHandler(operationID string, status int, mws []oapi.StrictMiddlewareFunc) http.Handler { +// Mirrors the oapi-codegen strict dispatcher, running body inside the handler so +// a test can act on the request context the way a real handler does. +func fakeStrictHandlerFunc(operationID string, status int, body func(ctx context.Context)) http.Handler { inner := oapi.StrictHandlerFunc(func(ctx context.Context, w http.ResponseWriter, r *http.Request, request any) (any, error) { + body(ctx) return nil, nil }) - for _, mw := range mws { - inner = mw(inner, operationID) - } + inner = TelemetryStrictMiddleware()(inner, operationID) return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) { _, _ = inner(r.Context(), w, r, nil) w.WriteHeader(status) }) } +// noBody is the handler body for tests that only exercise the middleware. +func noBody(context.Context) {} + // Flips the package-level toggle on for the test, restoring prior state // via t.Cleanup. func withTelemetryMiddlewareEnabled(t *testing.T) { @@ -70,9 +74,9 @@ func withTelemetryMiddlewareEnabled(t *testing.T) { func TestTelemetryMiddleware_EmitsApiCallEventOnDocumentedRoute(t *testing.T) { withTelemetryMiddlewareEnabled(t) rp := &recordingPublisher{} - chain := chiHandler(t, rp.publish, "ProcessExec", http.StatusOK) + chain := chiHandler(t, rp.publish, "ClickMouse", http.StatusOK, noBody) - req := httptest.NewRequest(http.MethodPost, "/process/exec", nil) + req := httptest.NewRequest(http.MethodPost, "/computer/click_mouse", nil) rec := httptest.NewRecorder() chain.ServeHTTP(rec, req) @@ -88,18 +92,98 @@ func TestTelemetryMiddleware_EmitsApiCallEventOnDocumentedRoute(t *testing.T) { OperationID string `json:"operation_id"` Status int `json:"status"` DurationMs float64 `json:"duration_ms"` + Code *string `json:"code"` } require.NoError(t, json.Unmarshal(ev.Data, &data)) assert.NotEmpty(t, data.RequestID, "request_id should be set by chi RequestID middleware") - assert.Equal(t, "ProcessExec", data.OperationID) + assert.Equal(t, "ClickMouse", data.OperationID) assert.Equal(t, http.StatusOK, data.Status) assert.GreaterOrEqual(t, data.DurationMs, 0.0) + assert.Nil(t, data.Code, "code is only recorded by handlers that submit code") +} + +func TestTelemetryMiddleware_EmitsPlatformApiCallForVMOperations(t *testing.T) { + withTelemetryMiddlewareEnabled(t) + rp := &recordingPublisher{} + chain := chiHandler(t, rp.publish, "ProcessExec", http.StatusOK, noBody) + + req := httptest.NewRequest(http.MethodPost, "/process/exec", nil) + chain.ServeHTTP(httptest.NewRecorder(), req) + + captured := rp.snapshot() + require.Len(t, captured, 1) + assert.Equal(t, "platform_api_call", captured[0].Type) + assert.Equal(t, events.Platform, captured[0].Category) +} + +// An operation the generated map does not know about must not land in control, +// which is the stream callers read to see what the agent did. +func TestTelemetryMiddleware_UnknownOperationIsPlatform(t *testing.T) { + withTelemetryMiddlewareEnabled(t) + rp := &recordingPublisher{} + chain := chiHandler(t, rp.publish, "SomeRouteAddedLater", http.StatusOK, noBody) + + chain.ServeHTTP(httptest.NewRecorder(), httptest.NewRequest(http.MethodPost, "/whatever", nil)) + + captured := rp.snapshot() + require.Len(t, captured, 1) + assert.Equal(t, events.Platform, captured[0].Category) +} + +func TestTelemetryMiddleware_RecordsSubmittedCode(t *testing.T) { + withTelemetryMiddlewareEnabled(t) + rp := &recordingPublisher{} + code := "await page.goto('https://example.com')" + chain := chiHandler(t, rp.publish, "ExecutePlaywrightCode", http.StatusOK, func(ctx context.Context) { + RecordTelemetryCode(ctx, code) + }) + + chain.ServeHTTP(httptest.NewRecorder(), httptest.NewRequest(http.MethodPost, "/playwright/execute", nil)) + + captured := rp.snapshot() + require.Len(t, captured, 1) + assert.Equal(t, events.Control, captured[0].Category) + assert.False(t, captured[0].Truncated) + var data struct { + Code *string `json:"code"` + } + require.NoError(t, json.Unmarshal(captured[0].Data, &data)) + require.NotNil(t, data.Code) + assert.Equal(t, code, *data.Code) +} + +func TestTelemetryMiddleware_ClipsOversizedCode(t *testing.T) { + withTelemetryMiddlewareEnabled(t) + rp := &recordingPublisher{} + // Ends on a multi-byte rune straddling the cap so the clip has to back off. + oversized := strings.Repeat("x", events.CapturedFieldCap-1) + strings.Repeat("é", 10) + chain := chiHandler(t, rp.publish, "ExecutePlaywrightCode", http.StatusOK, func(ctx context.Context) { + RecordTelemetryCode(ctx, oversized) + }) + + chain.ServeHTTP(httptest.NewRecorder(), httptest.NewRequest(http.MethodPost, "/playwright/execute", nil)) + + captured := rp.snapshot() + require.Len(t, captured, 1) + var data struct { + Code string `json:"code"` + } + require.NoError(t, json.Unmarshal(captured[0].Data, &data)) + assert.True(t, strings.HasSuffix(data.Code, events.TruncatedSuffix), "clipped code is not marked: %q", data.Code[max(0, len(data.Code)-40):]) + assert.LessOrEqual(t, len(data.Code), events.CapturedFieldCap) + assert.True(t, utf8.ValidString(data.Code)) +} + +// RecordTelemetryCode is called from handlers that also serve requests the +// middleware is not tracking, so it must tolerate a bare context. +func TestRecordTelemetryCode_NoopWithoutRequestScratch(t *testing.T) { + RecordTelemetryCode(context.Background(), "await page.goto('https://example.com')") } func TestTelemetryMiddleware_CapturesNonOKStatus(t *testing.T) { withTelemetryMiddlewareEnabled(t) rp := &recordingPublisher{} - chain := chiHandler(t, rp.publish, "ProcessExec", http.StatusInternalServerError) + chain := chiHandler(t, rp.publish, "ProcessExec", http.StatusInternalServerError, noBody) req := httptest.NewRequest(http.MethodPost, "/process/exec", nil) rec := httptest.NewRecorder() @@ -131,7 +215,7 @@ func TestTelemetryMiddleware_SkipsUndocumentedRoutes(t *testing.T) { func TestTelemetryMiddleware_ShortCircuitsWhenDisabled(t *testing.T) { DisableTelemetryMiddleware() rp := &recordingPublisher{} - chain := chiHandler(t, rp.publish, "ProcessExec", http.StatusOK) + chain := chiHandler(t, rp.publish, "ProcessExec", http.StatusOK, noBody) req := httptest.NewRequest(http.MethodPost, "/process/exec", nil) rec := httptest.NewRecorder() @@ -142,9 +226,9 @@ func TestTelemetryMiddleware_ShortCircuitsWhenDisabled(t *testing.T) { // Builds the same middleware stack as main.go: RequestID -> HTTP middleware -> // strict dispatch -> inner handler. -func chiHandler(t *testing.T, publish func(events.Event) (events.Envelope, bool), operationID string, status int) http.Handler { +func chiHandler(t *testing.T, publish func(events.Event) (events.Envelope, bool), operationID string, status int, body func(ctx context.Context)) http.Handler { t.Helper() - inner := fakeStrictHandler(operationID, status, []oapi.StrictMiddlewareFunc{TelemetryStrictMiddleware()}) + inner := fakeStrictHandlerFunc(operationID, status, body) telemetry := TelemetryHTTPMiddleware(publish)(inner) return chiMiddleware.RequestID(telemetry) } diff --git a/server/cmd/api/api/playwright.go b/server/cmd/api/api/playwright.go index de7368ab..395a45ed 100644 --- a/server/cmd/api/api/playwright.go +++ b/server/cmd/api/api/playwright.go @@ -144,6 +144,8 @@ func (s *ApiService) ExecutePlaywrightCode(ctx context.Context, request oapi.Exe }, nil } + RecordTelemetryCode(ctx, request.Body.Code) + timeout := 60 * time.Second if request.Body.TimeoutSec != nil && *request.Body.TimeoutSec > 0 { timeout = time.Duration(*request.Body.TimeoutSec) * time.Second diff --git a/server/cmd/api/api/telemetry.go b/server/cmd/api/api/telemetry.go index 52dc6b1f..a31fcf40 100644 --- a/server/cmd/api/api/telemetry.go +++ b/server/cmd/api/api/telemetry.go @@ -221,6 +221,7 @@ func categoryFields(b *oapi.BrowserTelemetryCategoriesConfig) []categoryField { {events.Page, b.Page}, {events.Interaction, b.Interaction}, {events.Control, b.Control}, + {events.Platform, b.Platform}, {events.Connection, b.Connection}, {events.System, b.System}, {events.Screenshot, b.Screenshot}, @@ -332,6 +333,7 @@ func disabledConfig() oapi.BrowserTelemetryConfig { Page: off(), Interaction: off(), Control: off(), + Platform: off(), Connection: off(), System: off(), Screenshot: off(), @@ -363,6 +365,7 @@ func telemetryConfigToOAPI(cfg telemetry.TelemetryConfig) oapi.BrowserTelemetryC Page: enabled(events.Page), Interaction: enabled(events.Interaction), Control: enabled(events.Control), + Platform: enabled(events.Platform), Connection: enabled(events.Connection), System: enabled(events.System), Screenshot: enabled(events.Screenshot), diff --git a/server/cmd/api/api/telemetry_test.go b/server/cmd/api/api/telemetry_test.go index 5b7261cf..e5a7cbeb 100644 --- a/server/cmd/api/api/telemetry_test.go +++ b/server/cmd/api/api/telemetry_test.go @@ -29,6 +29,7 @@ func allCategoriesDisabled() *oapi.BrowserTelemetryCategoriesConfig { Page: off(), Interaction: off(), Control: off(), + Platform: off(), Connection: off(), System: off(), Screenshot: off(), diff --git a/server/e2e/e2e_otlp_storage_test.go b/server/e2e/e2e_otlp_storage_test.go index afd703cb..8610e07d 100644 --- a/server/e2e/e2e_otlp_storage_test.go +++ b/server/e2e/e2e_otlp_storage_test.go @@ -99,7 +99,8 @@ func (c *otlpMockCollector) snapshot() (auths, instanceName, eventNames []string } // enableControlExport turns on the control category (so api_call events flow) -// and OTLP export, then makes a few API calls to generate exportable events. +// and OTLP export, then makes a few browser-control calls to generate +// exportable events. func enableControlExport(t *testing.T, ctx context.Context, client *instanceoapi.ClientWithResponses) { t.Helper() tr := true @@ -113,9 +114,9 @@ func enableControlExport(t *testing.T, ctx context.Context, client *instanceoapi }) require.NoError(t, err) require.Equal(t, http.StatusCreated, resp.StatusCode(), "put telemetry: %s", string(resp.Body)) - // Each API call emits an api_call (control) event, which OTLP exports. + // Browser-control calls emit api_call (control) events, which OTLP exports. for i := 0; i < 3; i++ { - _, _ = client.GetTelemetryWithResponse(ctx) + _, _ = client.TakeScreenshotWithResponse(ctx, instanceoapi.TakeScreenshotJSONRequestBody{}) time.Sleep(50 * time.Millisecond) } } diff --git a/server/lib/cdpmonitor/handlers.go b/server/lib/cdpmonitor/handlers.go index f551cc03..c3eb684d 100644 --- a/server/lib/cdpmonitor/handlers.go +++ b/server/lib/cdpmonitor/handlers.go @@ -580,7 +580,7 @@ func (m *Monitor) fetchResponseBody(ctx context.Context, requestID, sessionID st } body = string(decoded) } - return truncateBody(body, bodyCapFor(state.mimeType)) + return events.TruncateCaptured(body, bodyCapFor(state.mimeType)) } func (m *Monitor) handleLoadingFailed(p cdpNetworkLoadingFailedParams, sessionID string) { diff --git a/server/lib/cdpmonitor/util.go b/server/lib/cdpmonitor/util.go index df03e44a..d1fde8fa 100644 --- a/server/lib/cdpmonitor/util.go +++ b/server/lib/cdpmonitor/util.go @@ -3,8 +3,8 @@ package cdpmonitor import ( "encoding/json" "strings" - "unicode/utf8" + "github.com/kernel/kernel-images/server/lib/events" oapi "github.com/kernel/kernel-images/server/lib/oapi" ) @@ -97,8 +97,8 @@ var structuredPrefixes = []string{ // Vendor types with +json, +xml, or +csv suffixes are also treated as structured, // matching the allow-list in isCapturedMIME. func bodyCapFor(mime string) int { - const fullCap = 8 * 1024 - const contextCap = 4 * 1024 + const fullCap = events.CapturedFieldCap + const contextCap = events.CapturedFieldCap / 2 for _, p := range structuredPrefixes { if strings.HasPrefix(mime, p) { return fullCap @@ -112,32 +112,3 @@ func bodyCapFor(mime string) int { } return contextCap } - -const truncatedSuffix = "...[truncated]" - -// truncateBody caps body at the given limit on a valid UTF-8 boundary. -// The result never splits a multi-byte rune. A truncation suffix is appended -// when the body is cut so callers can distinguish truncated from full content. -func truncateBody(body string, maxBody int) string { - if len(body) <= maxBody { - return body - } - if maxBody <= 0 { - return "" - } - // Reserve room for the truncation suffix within the limit. - cutAt := maxBody - len(truncatedSuffix) - if cutAt <= 0 { - return truncatedSuffix[:maxBody] - } - // Walk forward through complete runes, stopping before we exceed cutAt. - end := 0 - for end < cutAt { - _, size := utf8.DecodeRuneInString(body[end:]) - if end+size > cutAt { - break - } - end += size - } - return body[:end] + truncatedSuffix -} diff --git a/server/lib/events/capture.go b/server/lib/events/capture.go new file mode 100644 index 00000000..ba452a9e --- /dev/null +++ b/server/lib/events/capture.go @@ -0,0 +1,40 @@ +package events + +import "unicode/utf8" + +// TruncatedSuffix marks a captured string that was cut at its cap, so a +// consumer can tell a clipped value from a complete one. +const TruncatedSuffix = "...[truncated]" + +// CapturedFieldCap is the ceiling for a single captured string on an event: +// response bodies of structured types, and the source submitted to Playwright +// execution. It sits three orders of magnitude below maxS2RecordBytes so no one +// field can push an envelope past the record limit, which would null the whole +// payload rather than clip the field. +const CapturedFieldCap = 8 * 1024 + +// TruncateCaptured caps s at maxBytes on a rune boundary, so the result never +// splits a multi-byte character, and appends TruncatedSuffix when it cuts. +func TruncateCaptured(s string, maxBytes int) string { + if len(s) <= maxBytes { + return s + } + if maxBytes <= 0 { + return "" + } + // Reserve room for the suffix within the cap. + cutAt := maxBytes - len(TruncatedSuffix) + if cutAt <= 0 { + return TruncatedSuffix[:maxBytes] + } + // Walk forward through complete runes, stopping before we exceed cutAt. + end := 0 + for end < cutAt { + _, size := utf8.DecodeRuneInString(s[end:]) + if end+size > cutAt { + break + } + end += size + } + return s[:end] + TruncatedSuffix +} diff --git a/server/lib/events/capture_test.go b/server/lib/events/capture_test.go new file mode 100644 index 00000000..c25febfc --- /dev/null +++ b/server/lib/events/capture_test.go @@ -0,0 +1,40 @@ +package events + +import ( + "strings" + "testing" + "unicode/utf8" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" +) + +func TestTruncateCaptured(t *testing.T) { + t.Run("a value within the cap is untouched", func(t *testing.T) { + assert.Equal(t, "page.click('#login')", TruncateCaptured("page.click('#login')", CapturedFieldCap)) + }) + + t.Run("a value over the cap is marked", func(t *testing.T) { + got := TruncateCaptured(strings.Repeat("a", CapturedFieldCap+1), CapturedFieldCap) + require.True(t, strings.HasSuffix(got, TruncatedSuffix)) + assert.LessOrEqual(t, len(got), CapturedFieldCap) + }) + + t.Run("the cut never splits a character", func(t *testing.T) { + // Every rune is 3 bytes, so a byte-wise cut lands inside one. + got := TruncateCaptured(strings.Repeat("あ", 40), 41) + assert.True(t, utf8.ValidString(got), "result is not valid UTF-8: %q", got) + assert.LessOrEqual(t, len(got), 41) + }) + + t.Run("a cap too small for the marker yields only the marker", func(t *testing.T) { + assert.Equal(t, TruncatedSuffix[:4], TruncateCaptured("abcdefghij", 4)) + assert.Equal(t, "", TruncateCaptured("abcdefghij", 0)) + }) + + // The cap exists so one field cannot push an envelope past the record limit, + // which would null the whole payload instead of clipping the field. + t.Run("the field cap leaves room under the record limit", func(t *testing.T) { + assert.Less(t, CapturedFieldCap, maxS2RecordBytes) + }) +} diff --git a/server/lib/events/category_gen.go b/server/lib/events/category_gen.go index b02132f9..e7fa54b5 100644 --- a/server/lib/events/category_gen.go +++ b/server/lib/events/category_gen.go @@ -34,6 +34,7 @@ var categoryByType = map[string]oapi.TelemetryEventCategory{ "page_navigation": oapi.TelemetryEventCategory("page"), "page_navigation_settled": oapi.TelemetryEventCategory("page"), "page_tab_opened": oapi.TelemetryEventCategory("page"), + "platform_api_call": oapi.TelemetryEventCategory("platform"), "service_crashed": oapi.TelemetryEventCategory("system"), "system_oom_kill": oapi.TelemetryEventCategory("system"), } @@ -44,3 +45,70 @@ func CategoryForType(eventType string) (oapi.TelemetryEventCategory, bool) { c, ok := categoryByType[eventType] return c, ok } + +var categoryByOperationID = map[string]oapi.TelemetryEventCategory{ + "BatchComputerAction": oapi.TelemetryEventCategory("control"), + "ChromiumConfigure": oapi.TelemetryEventCategory("platform"), + "ClickMouse": oapi.TelemetryEventCategory("control"), + "CreateDirectory": oapi.TelemetryEventCategory("platform"), + "DeleteDirectory": oapi.TelemetryEventCategory("platform"), + "DeleteFile": oapi.TelemetryEventCategory("platform"), + "DeleteRecording": oapi.TelemetryEventCategory("platform"), + "DisableScaleToZero": oapi.TelemetryEventCategory("platform"), + "DownloadDirZip": oapi.TelemetryEventCategory("platform"), + "DownloadDirZstd": oapi.TelemetryEventCategory("platform"), + "DownloadRecording": oapi.TelemetryEventCategory("platform"), + "DragMouse": oapi.TelemetryEventCategory("control"), + "EnableScaleToZero": oapi.TelemetryEventCategory("platform"), + "ExecutePlaywrightCode": oapi.TelemetryEventCategory("control"), + "FileInfo": oapi.TelemetryEventCategory("platform"), + "GetMousePosition": oapi.TelemetryEventCategory("control"), + "GetTelemetry": oapi.TelemetryEventCategory("platform"), + "ListFiles": oapi.TelemetryEventCategory("platform"), + "ListRecorders": oapi.TelemetryEventCategory("platform"), + "LogsStream": oapi.TelemetryEventCategory("platform"), + "MarkRecording": oapi.TelemetryEventCategory("platform"), + "MoveMouse": oapi.TelemetryEventCategory("control"), + "MovePath": oapi.TelemetryEventCategory("platform"), + "PatchChromiumFlags": oapi.TelemetryEventCategory("platform"), + "PatchChromiumPolicies": oapi.TelemetryEventCategory("platform"), + "PatchDisplay": oapi.TelemetryEventCategory("platform"), + "PatchTelemetry": oapi.TelemetryEventCategory("platform"), + "PressKey": oapi.TelemetryEventCategory("control"), + "ProcessExec": oapi.TelemetryEventCategory("platform"), + "ProcessKill": oapi.TelemetryEventCategory("platform"), + "ProcessResize": oapi.TelemetryEventCategory("platform"), + "ProcessSpawn": oapi.TelemetryEventCategory("platform"), + "ProcessStatus": oapi.TelemetryEventCategory("platform"), + "ProcessStdin": oapi.TelemetryEventCategory("platform"), + "ProcessStdoutStream": oapi.TelemetryEventCategory("platform"), + "PublishTelemetryEvent": oapi.TelemetryEventCategory("platform"), + "PutTelemetry": oapi.TelemetryEventCategory("platform"), + "ReadClipboard": oapi.TelemetryEventCategory("control"), + "ReadFile": oapi.TelemetryEventCategory("platform"), + "Scroll": oapi.TelemetryEventCategory("control"), + "SetCursor": oapi.TelemetryEventCategory("control"), + "SetFilePermissions": oapi.TelemetryEventCategory("platform"), + "StartFsWatch": oapi.TelemetryEventCategory("platform"), + "StartRecording": oapi.TelemetryEventCategory("platform"), + "StopFsWatch": oapi.TelemetryEventCategory("platform"), + "StopRecording": oapi.TelemetryEventCategory("platform"), + "StreamFsEvents": oapi.TelemetryEventCategory("platform"), + "StreamTelemetryEvents": oapi.TelemetryEventCategory("platform"), + "TakeScreenshot": oapi.TelemetryEventCategory("control"), + "TypeText": oapi.TelemetryEventCategory("control"), + "UploadExtensionsAndRestart": oapi.TelemetryEventCategory("platform"), + "UploadFiles": oapi.TelemetryEventCategory("platform"), + "UploadZip": oapi.TelemetryEventCategory("platform"), + "UploadZstd": oapi.TelemetryEventCategory("platform"), + "WriteClipboard": oapi.TelemetryEventCategory("control"), + "WriteFile": oapi.TelemetryEventCategory("platform"), +} + +// CategoryForOperation returns the category an api_call event carries for +// the given operation, keyed by the generated handler name the event +// reports. ok is false for an unknown operation. +func CategoryForOperation(operationID string) (oapi.TelemetryEventCategory, bool) { + c, ok := categoryByOperationID[operationID] + return c, ok +} diff --git a/server/lib/events/category_test.go b/server/lib/events/category_test.go new file mode 100644 index 00000000..8745723f --- /dev/null +++ b/server/lib/events/category_test.go @@ -0,0 +1,47 @@ +package events + +import ( + "testing" + + "github.com/stretchr/testify/assert" + "github.com/stretchr/testify/require" + + oapi "github.com/kernel/kernel-images/server/lib/oapi" +) + +// The api_call/platform_api_call split is only meaningful if the operation map +// and the event-type map agree on which category each type carries. +func TestCategoryMapsAgreeOnAPICallSplit(t *testing.T) { + cat, ok := CategoryForType("api_call") + require.True(t, ok) + assert.Equal(t, Control, cat) + + cat, ok = CategoryForType("platform_api_call") + require.True(t, ok) + assert.Equal(t, Platform, cat) +} + +func TestCategoryForOperation(t *testing.T) { + require.NotEmpty(t, categoryByOperationID, "generator produced no operations") + + // Sampled rather than exhaustive: the spec is the source of truth for the + // full mapping, and restating all of it here would just be a second copy. + control, ok := CategoryForOperation("ExecutePlaywrightCode") + require.True(t, ok) + assert.Equal(t, Control, control) + + platform, ok := CategoryForOperation("StartRecording") + require.True(t, ok) + assert.Equal(t, Platform, platform) + + _, ok = CategoryForOperation("NotAnOperation") + assert.False(t, ok) +} + +// Every operation must land in one of the two api_call categories: any other +// category would produce an event type nothing publishes. +func TestOperationCategoriesAreAPICallCategories(t *testing.T) { + for operationID, cat := range categoryByOperationID { + assert.Contains(t, []oapi.TelemetryEventCategory{Control, Platform}, cat, "operation %s", operationID) + } +} diff --git a/server/lib/events/event.go b/server/lib/events/event.go index ab4f4270..904e4126 100644 --- a/server/lib/events/event.go +++ b/server/lib/events/event.go @@ -1,6 +1,6 @@ package events -//go:generate go run github.com/kernel/kernel-images/server/scripts/categorygen -openapi ../../openapi.yaml -out category_gen.go +//go:generate go run github.com/kernel/kernel-images/server/scripts/categorygen -openapi ../../openapi.yaml -handlers ../oapi/oapi.go -out category_gen.go import ( "encoding/json" @@ -18,6 +18,7 @@ const ( Page = oapi.TelemetryEventCategory("page") Interaction = oapi.TelemetryEventCategory("interaction") Control = oapi.TelemetryEventCategory("control") + Platform = oapi.TelemetryEventCategory("platform") Connection = oapi.TelemetryEventCategory("connection") System = oapi.TelemetryEventCategory("system") Screenshot = oapi.TelemetryEventCategory("screenshot") @@ -34,6 +35,7 @@ var UserCategories = []oapi.TelemetryEventCategory{ Page, Interaction, Control, + Platform, Connection, System, Screenshot, @@ -44,6 +46,8 @@ var UserCategories = []oapi.TelemetryEventCategory{ // per-category settings: the lightweight operational signals. CDP categories // (console/network/page/interaction) and screenshot are excluded so the default // never starts the CDP collector or emits high-volume streams; they are opt-in. +// Platform is excluded too: those calls are mostly platform-induced bookkeeping +// (recording, profile save) that drowns out the agent's own actions. var DefaultCategories = []oapi.TelemetryEventCategory{ Control, Connection, diff --git a/server/lib/oapi/oapi.go b/server/lib/oapi/oapi.go index 038414a3..ef7a89c2 100644 --- a/server/lib/oapi/oapi.go +++ b/server/lib/oapi/oapi.go @@ -1028,6 +1028,36 @@ func (e BrowserPageTabOpenedEventType) Valid() bool { } } +// Defines values for BrowserPlatformApiCallEventCategory. +const ( + Platform BrowserPlatformApiCallEventCategory = "platform" +) + +// Valid indicates whether the value is a known member of the BrowserPlatformApiCallEventCategory enum. +func (e BrowserPlatformApiCallEventCategory) Valid() bool { + switch e { + case Platform: + return true + default: + return false + } +} + +// Defines values for BrowserPlatformApiCallEventType. +const ( + PlatformApiCall BrowserPlatformApiCallEventType = "platform_api_call" +) + +// Valid indicates whether the value is a known member of the BrowserPlatformApiCallEventType enum. +func (e BrowserPlatformApiCallEventType) Valid() bool { + switch e { + case PlatformApiCall: + return true + default: + return false + } +} + // Defines values for BrowserServiceCrashedEventCategory. const ( BrowserServiceCrashedEventCategorySystem BrowserServiceCrashedEventCategory = "system" @@ -1449,6 +1479,7 @@ const ( PublishEventRequestCategoryMonitor PublishEventRequestCategory = "monitor" PublishEventRequestCategoryNetwork PublishEventRequestCategory = "network" PublishEventRequestCategoryPage PublishEventRequestCategory = "page" + PublishEventRequestCategoryPlatform PublishEventRequestCategory = "platform" PublishEventRequestCategoryScreenshot PublishEventRequestCategory = "screenshot" PublishEventRequestCategorySystem PublishEventRequestCategory = "system" ) @@ -1472,6 +1503,8 @@ func (e PublishEventRequestCategory) Valid() bool { return true case PublishEventRequestCategoryPage: return true + case PublishEventRequestCategoryPlatform: + return true case PublishEventRequestCategoryScreenshot: return true case PublishEventRequestCategorySystem: @@ -1491,6 +1524,7 @@ const ( TelemetryEventCategoryMonitor TelemetryEventCategory = "monitor" TelemetryEventCategoryNetwork TelemetryEventCategory = "network" TelemetryEventCategoryPage TelemetryEventCategory = "page" + TelemetryEventCategoryPlatform TelemetryEventCategory = "platform" TelemetryEventCategoryScreenshot TelemetryEventCategory = "screenshot" TelemetryEventCategorySystem TelemetryEventCategory = "system" ) @@ -1514,6 +1548,8 @@ func (e TelemetryEventCategory) Valid() bool { return true case TelemetryEventCategoryPage: return true + case TelemetryEventCategoryPlatform: + return true case TelemetryEventCategoryScreenshot: return true case TelemetryEventCategorySystem: @@ -1586,7 +1622,7 @@ type BatchComputerActionRequest struct { Actions []ComputerAction `json:"actions"` } -// BrowserApiCallEvent An HTTP call handled by the kernel-images-api server. +// BrowserApiCallEvent A call that drives the browser, handled by the kernel-images-api server: computer-control actions, Playwright code execution, screenshots and clipboard access. Calls that manage the VM instead emit `platform_api_call`. type BrowserApiCallEvent struct { Category BrowserApiCallEventCategory `json:"category"` @@ -1612,10 +1648,13 @@ type BrowserApiCallEventType string // BrowserApiCallEventData Per-call payload for `api_call` events. type BrowserApiCallEventData struct { + // Code Source submitted to `executePlaywrightCode`, capped at 8192 bytes like every other captured string. A capped value is cut on a character boundary and ends in `...[truncated]`. Absent for every other operation. + Code *string `json:"code,omitempty"` + // DurationMs Wall-clock duration of the handler in milliseconds. DurationMs float32 `json:"duration_ms"` - // OperationId OpenAPI operationId of the matched route (e.g. `processExec`, `takeScreenshot`). + // OperationId Matched route's operation, named as the server names its handler (e.g. `ProcessExec`, `TakeScreenshot`). OperationId string `json:"operation_id"` // RequestId Per-request identifier from the kernel-images-api request middleware. @@ -1648,7 +1687,7 @@ type BrowserCallStack struct { // Description Optional label for the stack trace (e.g. async cause). Description *string `json:"description,omitempty"` - // Parent Parent stack trace for async stacks. + // Parent CDP Runtime.StackTrace representing the JavaScript call stack at the time of an event. Fields use CDP naming conventions rather than snake_case to match the Chrome DevTools Protocol wire format. Parent *BrowserCallStack `json:"parent,omitempty"` } @@ -2431,7 +2470,7 @@ type BrowserNetworkRequestEventData struct { // FrameId CDP frame identifier within the target. FrameId *string `json:"frame_id,omitempty"` - // Headers Request headers. + // Headers HTTP headers map forwarded as-is from CDP without normalization. Values are typically strings but may be any JSON type. Headers BrowserHttpHeaders `json:"headers"` // InitiatorType CDP Initiator.type indicating what caused the request, passed through as-is from Chrome. Known values include script, parser, preload, and other. @@ -2504,7 +2543,7 @@ type BrowserNetworkResponseEventData struct { // FrameId CDP frame identifier within the target. FrameId *string `json:"frame_id,omitempty"` - // Headers Response headers. + // Headers HTTP headers map forwarded as-is from CDP without normalization. Values are typically strings but may be any JSON type. Headers BrowserHttpHeaders `json:"headers"` // LoaderId CDP document loader identifier, reset on each navigation. @@ -2947,6 +2986,30 @@ type BrowserPageTabOpenedEventData struct { Url string `json:"url"` } +// BrowserPlatformApiCallEvent A call that manages the browser VM rather than driving the browser, handled by the kernel-images-api server: recording lifecycle, filesystem and process management, telemetry and browser configuration. These are mostly platform-induced (e.g. profile save, replay capture) rather than agent actions. +type BrowserPlatformApiCallEvent struct { + Category BrowserPlatformApiCallEventCategory `json:"category"` + + // Data Per-call payload for `api_call` events. + Data *BrowserApiCallEventData `json:"data,omitempty"` + + // Source Provenance metadata identifying which producer emitted the event. + Source BrowserEventSource `json:"source"` + + // Truncated True if the data field was truncated due to size limits. + Truncated *bool `json:"truncated,omitempty"` + + // Ts Event timestamp in Unix microseconds. + Ts int64 `json:"ts"` + Type BrowserPlatformApiCallEventType `json:"type"` +} + +// BrowserPlatformApiCallEventCategory defines model for BrowserPlatformApiCallEvent.Category. +type BrowserPlatformApiCallEventCategory string + +// BrowserPlatformApiCallEventType defines model for BrowserPlatformApiCallEvent.Type. +type BrowserPlatformApiCallEventType string + // BrowserServiceCrashedEvent A managed service exited unexpectedly. Intentional stops (e.g. operator-initiated shutdown) do not produce this event — only unexpected exits and terminal restart-give-up transitions do. type BrowserServiceCrashedEvent struct { Category BrowserServiceCrashedEventCategory `json:"category"` @@ -3060,31 +3123,34 @@ type BrowserTargetType string // BrowserTelemetryCategoriesConfig Per-category telemetry capture settings for browser events. type BrowserTelemetryCategoriesConfig struct { - // Captcha Captcha solve attempt outcomes. + // Captcha Configuration for a single telemetry category. Captcha *BrowserTelemetryCategoryConfig `json:"captcha,omitempty"` - // Connection Client attach/detach lifecycle for the CDP proxy and live view. + // Connection Configuration for a single telemetry category. Connection *BrowserTelemetryCategoryConfig `json:"connection,omitempty"` - // Console Console output (log, warn, error) and uncaught exceptions. + // Console Configuration for a single telemetry category. Console *BrowserTelemetryCategoryConfig `json:"console,omitempty"` - // Control Agent-driven actions against the browser, such as inbound calls to the kernel-images-api server. + // Control Configuration for a single telemetry category. Control *BrowserTelemetryCategoryConfig `json:"control,omitempty"` - // Interaction User interaction events (clicks, keydowns, scroll). + // Interaction Configuration for a single telemetry category. Interaction *BrowserTelemetryCategoryConfig `json:"interaction,omitempty"` - // Network HTTP request/response metadata. + // Network Configuration for a single telemetry category. Network *BrowserTelemetryCategoryConfig `json:"network,omitempty"` - // Page Page lifecycle events (navigation, load, layout shifts, LCP). + // Page Configuration for a single telemetry category. Page *BrowserTelemetryCategoryConfig `json:"page,omitempty"` - // Screenshot Periodic base64-encoded viewport screenshots. High volume; off by default and opt-in. + // Platform Configuration for a single telemetry category. + Platform *BrowserTelemetryCategoryConfig `json:"platform,omitempty"` + + // Screenshot Configuration for a single telemetry category. Screenshot *BrowserTelemetryCategoryConfig `json:"screenshot,omitempty"` - // System Browser VM health, such as out-of-memory kills and managed-service crashes. + // System Configuration for a single telemetry category. System *BrowserTelemetryCategoryConfig `json:"system,omitempty"` } @@ -3094,7 +3160,7 @@ type BrowserTelemetryCategoryConfig struct { Enabled *bool `json:"enabled,omitempty"` } -// BrowserTelemetryConfig Telemetry configuration for a browser. Selection is opt-in. Omit the browser key (or send an empty object) to capture the default set: lightweight operational signals (control, connection, system, captcha). Within `browser`, only the categories you set enabled: true are captured; anything omitted is off. The CDP categories (console, network, page, interaction) and `screenshot` are off by default and must be opted into. A `browser` config with nothing enabled clears the telemetry configuration. The `monitor` category (CDP collector health) is not configurable here; it flows automatically whenever a CDP category is captured. +// BrowserTelemetryConfig Telemetry configuration for a browser. Selection is opt-in. Omit the browser key (or send an empty object) to capture the default set: lightweight operational signals (control, connection, system, captcha). Within `browser`, only the categories you set enabled: true are captured; anything omitted is off. The CDP categories (console, network, page, interaction), `screenshot` and `platform` are off by default and must be opted into. A `browser` config with nothing enabled clears the telemetry configuration. The `monitor` category (CDP collector health) is not configurable here; it flows automatically whenever a CDP category is captured. type BrowserTelemetryConfig struct { // Browser Per-category telemetry capture settings for browser events. Browser *BrowserTelemetryCategoriesConfig `json:"browser,omitempty"` @@ -3755,7 +3821,7 @@ type TelemetryState struct { // AppliedAt Wall-clock time at which the current configuration was applied. Omitted when telemetry is not configured. AppliedAt *time.Time `json:"applied_at,omitempty"` - // Config Telemetry configuration for a browser. Selection is opt-in. Omit the browser key (or send an empty object) to capture the default set: lightweight operational signals (control, connection, system, captcha). Within `browser`, only the categories you set enabled: true are captured; anything omitted is off. The CDP categories (console, network, page, interaction) and `screenshot` are off by default and must be opted into. A `browser` config with nothing enabled clears the telemetry configuration. The `monitor` category (CDP collector health) is not configurable here; it flows automatically whenever a CDP category is captured. + // Config Telemetry configuration for a browser. Selection is opt-in. Omit the browser key (or send an empty object) to capture the default set: lightweight operational signals (control, connection, system, captcha). Within `browser`, only the categories you set enabled: true are captured; anything omitted is off. The CDP categories (console, network, page, interaction), `screenshot` and `platform` are off by default and must be opted into. A `browser` config with nothing enabled clears the telemetry configuration. The `monitor` category (CDP collector health) is not configurable here; it flows automatically whenever a CDP category is captured. Config BrowserTelemetryConfig `json:"config"` // Seq Process-monotonic sequence number of the last published event. Does not reset across configuration changes. @@ -4742,6 +4808,34 @@ func (t *KnownBrowserTelemetryEvent) MergeBrowserApiCallEvent(v BrowserApiCallEv return err } +// AsBrowserPlatformApiCallEvent returns the union data inside the KnownBrowserTelemetryEvent as a BrowserPlatformApiCallEvent +func (t KnownBrowserTelemetryEvent) AsBrowserPlatformApiCallEvent() (BrowserPlatformApiCallEvent, error) { + var body BrowserPlatformApiCallEvent + err := json.Unmarshal(t.union, &body) + return body, err +} + +// FromBrowserPlatformApiCallEvent overwrites any union data inside the KnownBrowserTelemetryEvent as the provided BrowserPlatformApiCallEvent +func (t *KnownBrowserTelemetryEvent) FromBrowserPlatformApiCallEvent(v BrowserPlatformApiCallEvent) error { + v.Type = "platform_api_call" + b, err := json.Marshal(v) + t.union = b + return err +} + +// MergeBrowserPlatformApiCallEvent performs a merge with any union data inside the KnownBrowserTelemetryEvent, using the provided BrowserPlatformApiCallEvent +func (t *KnownBrowserTelemetryEvent) MergeBrowserPlatformApiCallEvent(v BrowserPlatformApiCallEvent) error { + v.Type = "platform_api_call" + b, err := json.Marshal(v) + if err != nil { + return err + } + + merged, err := runtime.JSONMerge(t.union, b) + t.union = merged + return err +} + // AsBrowserCdpConnectEvent returns the union data inside the KnownBrowserTelemetryEvent as a BrowserCdpConnectEvent func (t KnownBrowserTelemetryEvent) AsBrowserCdpConnectEvent() (BrowserCdpConnectEvent, error) { var body BrowserCdpConnectEvent @@ -5010,6 +5104,8 @@ func (t KnownBrowserTelemetryEvent) ValueByDiscriminator() (interface{}, error) return t.AsBrowserPageNavigationSettledEvent() case "page_tab_opened": return t.AsBrowserPageTabOpenedEvent() + case "platform_api_call": + return t.AsBrowserPlatformApiCallEvent() case "service_crashed": return t.AsBrowserServiceCrashedEvent() case "system_oom_kill": @@ -19258,382 +19354,384 @@ func (sh *strictHandler) StreamTelemetryEvents(w http.ResponseWriter, r *http.Re // Base64 encoded, gzipped, json marshaled Swagger object var swaggerSpec = []string{ - "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", - "AA==", + "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", } // GetSwagger returns the content of the embedded swagger specification file diff --git a/server/openapi.yaml b/server/openapi.yaml index aa693a1b..4c0d53aa 100644 --- a/server/openapi.yaml +++ b/server/openapi.yaml @@ -7,6 +7,7 @@ paths: post: summary: Start a screen recording. Only one recording per ID can be registered at a time. operationId: startRecording + x-telemetry-category: platform requestBody: required: false content: @@ -27,6 +28,7 @@ paths: post: summary: Execute a command synchronously operationId: processExec + x-telemetry-category: platform requestBody: required: true content: @@ -48,6 +50,7 @@ paths: post: summary: Execute a command asynchronously operationId: processSpawn + x-telemetry-category: platform requestBody: required: true content: @@ -69,6 +72,7 @@ paths: get: summary: Get process status operationId: processStatus + x-telemetry-category: platform parameters: - name: process_id in: path @@ -93,6 +97,7 @@ paths: get: summary: Stream process stdout over SSE operationId: processStdoutStream + x-telemetry-category: platform parameters: - name: process_id in: path @@ -123,6 +128,7 @@ paths: post: summary: Write to process stdin operationId: processStdin + x-telemetry-category: platform parameters: - name: process_id in: path @@ -153,6 +159,7 @@ paths: post: summary: Send signal to process operationId: processKill + x-telemetry-category: platform parameters: - name: process_id in: path @@ -183,6 +190,7 @@ paths: post: summary: Resize a PTY-backed process operationId: processResize + x-telemetry-category: platform parameters: - name: process_id in: path @@ -213,6 +221,7 @@ paths: post: summary: Stop the recording operationId: stopRecording + x-telemetry-category: platform requestBody: required: false content: @@ -237,6 +246,7 @@ paths: type: string pattern: "^[a-zA-Z0-9-]+$" operationId: downloadRecording + x-telemetry-category: platform responses: "200": description: Recording file @@ -276,6 +286,7 @@ paths: get: summary: List all recorders operationId: listRecorders + x-telemetry-category: platform responses: "200": description: List of recorders @@ -291,6 +302,7 @@ paths: post: summary: Delete a previously recorded video file operationId: deleteRecording + x-telemetry-category: platform requestBody: required: false content: @@ -315,6 +327,7 @@ paths: Records a named point in time during an active recording. At finalize the markers are injected into the output MP4 as chapter markers. operationId: markRecording + x-telemetry-category: platform requestBody: required: true content: @@ -342,6 +355,7 @@ paths: post: summary: Simulate a mouse click action on the host computer operationId: clickMouse + x-telemetry-category: control requestBody: required: true content: @@ -359,6 +373,7 @@ paths: post: summary: Move the mouse cursor to the specified coordinates on the host computer operationId: moveMouse + x-telemetry-category: control requestBody: required: true content: @@ -376,6 +391,7 @@ paths: post: summary: Capture a screenshot of the host computer operationId: takeScreenshot + x-telemetry-category: control requestBody: required: false content: @@ -398,6 +414,7 @@ paths: post: summary: Hide or show the cursor operationId: setCursor + x-telemetry-category: control requestBody: required: true content: @@ -419,6 +436,7 @@ paths: post: summary: Get the current mouse cursor position on the host computer operationId: getMousePosition + x-telemetry-category: control responses: "200": description: Current mouse position @@ -432,6 +450,7 @@ paths: post: summary: Type text on the host computer operationId: typeText + x-telemetry-category: control requestBody: required: true content: @@ -454,6 +473,7 @@ paths: the X11 keysym definitions at https://cgit.freedesktop.org/xorg/proto/x11proto/plain/keysymdef.h The server honors millisecond-level durations using fractional sleeps under the hood. operationId: pressKey + x-telemetry-category: control requestBody: required: true content: @@ -476,6 +496,7 @@ paths: When both horizontal and vertical deltas are provided, the server applies them sequentially (vertical then horizontal) and batches wheel events using `xdotool click --repeat N --delay 0