Skip to content

[wip]#100

Open
Sayan- wants to merge 1 commit intomainfrom
sayan/direct-to-metro
Open

[wip]#100
Sayan- wants to merge 1 commit intomainfrom
sayan/direct-to-metro

Conversation

@Sayan-
Copy link
Copy Markdown
Contributor

@Sayan- Sayan- commented Apr 21, 2026

example output:

────────────────────────────────────────────────────────────
1) Create a browser and inspect routing-relevant fields
────────────────────────────────────────────────────────────
[log_4d7f6a] sending request {
  method: 'post',
  url: 'https://api.onkernel.com/browsers',
  options: { method: 'post', path: '/browsers', body: {} },
  headers: {
    accept: 'application/json',
    authorization: '***',
    'content-type': 'application/json',
    'user-agent': 'Kernel/JS 0.50.0',
    'x-stainless-arch': 'arm64',
    'x-stainless-lang': 'js',
    'x-stainless-os': 'MacOS',
    'x-stainless-package-version': '0.50.0',
    'x-stainless-retry-count': '0',
    'x-stainless-runtime': 'node',
    'x-stainless-runtime-version': 'v25.2.1'
  }
}
[log_4d7f6a] post https://api.onkernel.com/browsers succeeded with status 200 in 467ms
[log_4d7f6a] response start {
  url: 'https://api.onkernel.com/browsers',
  status: 200,
  headers: {
    'cache-control': 'private, no-store',
    connection: 'keep-alive',
    'content-type': 'application/json',
    date: 'Tue, 21 Apr 2026 22:22:11 GMT',
    server: 'railway-edge',
    'transfer-encoding': 'chunked',
    'x-cache': 'MISS',
    'x-cache-hits': '0',
    'x-railway-cdn-edge': 'fastly/cache-bfi-krnt7300040-BFI',
    'x-railway-edge': 'railway/us-west2',
    'x-railway-request-id': 'BauIByBtQ2azvinB2prcFg',
    'x-ratelimit-limit': '250',
    'x-ratelimit-remaining': '249',
    'x-served-by': 'cache-bfi-krnt7300040-BFI'
  },
  durationMs: 467
}
[log_4d7f6a] response parsed {
  url: 'https://api.onkernel.com/browsers',
  status: 200,
  body: {
    base_url: 'https://proxy.yul-vigorous-sammet.onkernel.com:8443/browser/kernel',
    browser_live_view_url: 'https://proxy.yul-vigorous-sammet.onkernel.com:8443/browser/live/Ct3dK9pTIyFS',
    cdp_ws_url: 'wss://proxy.yul-vigorous-sammet.onkernel.com:8443/browser/cdp?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE4MDgzNDYxMzEsInNlc3Npb24iOnsiaWQiOiJ3NGw3dGttMGF3MmZyamxrZTVob2Jja3giLCJjZHBQb3J0Ijo5MjIyLCJjZHBXc1BhdGgiOiIiLCJpbnN0YW5jZU5hbWUiOiJicm93c2VyLWVudm95LXByb2R1Y3Rpb24tMTMtcHJvZm91bmQtd29sdmVyaW5lLTQ0MzgiLCJmcWRuIjoicHJvdWQtbGVhZi0zMW13NnMweC5wcm9kLXl1bC11bmlrcmFmdC0yLm9ua2VybmVsLmFwcCIsIm1ldHJvIjoiaHR0cHM6Ly9hcGkucHJvZC15dWwtdW5pa3JhZnQtMi5vbmtlcm5lbC5ydW4vdjEiLCJ1c2VySWQiOiJ5ZmEyd2RlaTluNHhvZTFwZHVhYmZ4dXMiLCJvcmdJZCI6ImlxMnRmMjUzbWlsOWptOWhmZjI3bDhyMiIsInN0ZWFsdGgiOmZhbHNlLCJoZWFkbGVzcyI6ZmFsc2UsImtlcm5lbEh0dHBTZXJ2ZXJQb3J0Ijo0NDQsInRpbWVvdXRTZWNvbmRzIjo2MCwiY3JlYXRlZEF0IjoiMjAyNi0wNC0yMVQyMjoyMjoxMS41NzIzMzI0NDZaIiwiaW1hZ2UiOiJvbmtlcm5lbC9rZXJuZWwtY3UtdjQwOjc5N2U4ZGIiLCJsaXZlU2x1ZyI6IkN0M2RLOXBUSXlGUyIsInByaXZhdGVJUCI6IjE3Mi4xNi4xMC4xNyJ9fQ.o03ve8phxMvr89Sv4jRkNzfBvDKPWqRLgvgTY5rv7YY',
    created_at: '2026-04-21T22:22:11.572332446Z',
    gpu: false,
    headless: false,
    kiosk_mode: false,
    session_id: 'w4l7tkm0aw2frjlke5hobckx',
    stealth: false,
    timeout_seconds: 60,
    webdriver_ws_url: 'wss://proxy.yul-vigorous-sammet.onkernel.com:8443/browser/webdriver/session?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE4MDgzNDYxMzEsInNlc3Npb24iOnsiaWQiOiJ3NGw3dGttMGF3MmZyamxrZTVob2Jja3giLCJjZHBQb3J0Ijo5MjIyLCJjZHBXc1BhdGgiOiIiLCJpbnN0YW5jZU5hbWUiOiJicm93c2VyLWVudm95LXByb2R1Y3Rpb24tMTMtcHJvZm91bmQtd29sdmVyaW5lLTQ0MzgiLCJmcWRuIjoicHJvdWQtbGVhZi0zMW13NnMweC5wcm9kLXl1bC11bmlrcmFmdC0yLm9ua2VybmVsLmFwcCIsIm1ldHJvIjoiaHR0cHM6Ly9hcGkucHJvZC15dWwtdW5pa3JhZnQtMi5vbmtlcm5lbC5ydW4vdjEiLCJ1c2VySWQiOiJ5ZmEyd2RlaTluNHhvZTFwZHVhYmZ4dXMiLCJvcmdJZCI6ImlxMnRmMjUzbWlsOWptOWhmZjI3bDhyMiIsInN0ZWFsdGgiOmZhbHNlLCJoZWFkbGVzcyI6ZmFsc2UsImtlcm5lbEh0dHBTZXJ2ZXJQb3J0Ijo0NDQsInRpbWVvdXRTZWNvbmRzIjo2MCwiY3JlYXRlZEF0IjoiMjAyNi0wNC0yMVQyMjoyMjoxMS41NzIzMzI0NDZaIiwiaW1hZ2UiOiJvbmtlcm5lbC9rZXJuZWwtY3UtdjQwOjc5N2U4ZGIiLCJsaXZlU2x1ZyI6IkN0M2RLOXBUSXlGUyIsInByaXZhdGVJUCI6IjE3Mi4xNi4xMC4xNyJ9fQ.o03ve8phxMvr89Sv4jRkNzfBvDKPWqRLgvgTY5rv7YY'
  },
  durationMs: 468
}
  session_id: w4l7tkm0aw2frjlke5hobckx
  base_url:   https://proxy.yul-vigorous-sammet.onkernel.com:8443/browser/kernel
  cdp_ws_url: wss://proxy.yul-vigorous-sammet.onkernel.com:8443/browser/cdp?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE4MDgzNDYxMzEsInNlc3Npb24iOnsiaWQiOiJ3NGw3dGttMGF3MmZyamxrZTVob2Jja3giLCJjZHBQb3J0Ijo5MjIyLCJjZHBXc1BhdGgiOiIiLCJpbnN0YW5jZU5hbWUiOiJicm93c2VyLWVudm95LXByb2R1Y3Rpb24tMTMtcHJvZm91bmQtd29sdmVyaW5lLTQ0MzgiLCJmcWRuIjoicHJvdWQtbGVhZi0zMW13NnMweC5wcm9kLXl1bC11bmlrcmFmdC0yLm9ua2VybmVsLmFwcCIsIm1ldHJvIjoiaHR0cHM6Ly9hcGkucHJvZC15dWwtdW5pa3JhZnQtMi5vbmtlcm5lbC5ydW4vdjEiLCJ1c2VySWQiOiJ5ZmEyd2RlaTluNHhvZTFwZHVhYmZ4dXMiLCJvcmdJZCI6ImlxMnRmMjUzbWlsOWptOWhmZjI3bDhyMiIsInN0ZWFsdGgiOmZhbHNlLCJoZWFkbGVzcyI6ZmFsc2UsImtlcm5lbEh0dHBTZXJ2ZXJQb3J0Ijo0NDQsInRpbWVvdXRTZWNvbmRzIjo2MCwiY3JlYXRlZEF0IjoiMjAyNi0wNC0yMVQyMjoyMjoxMS41NzIzMzI0NDZaIiwiaW1hZ2UiOiJvbmtlcm5lbC9rZXJuZWwtY3UtdjQwOjc5N2U4ZGIiLCJsaXZlU2x1ZyI6IkN0M2RLOXBUSXlGUyIsInByaXZhdGVJUCI6IjE3Mi4xNi4xMC4xNyJ9fQ.o03ve8phxMvr89Sv4jRkNzfBvDKPWqRLgvgTY5rv7YY

────────────────────────────────────────────────────────────
2) Verify cache was populated by the create response
────────────────────────────────────────────────────────────
  cache entry: {
  baseURL: 'https://proxy.yul-vigorous-sammet.onkernel.com:8443/browser/kernel',
  jwt: 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE4MDgzNDYxMzEsInNlc3Npb24iOnsiaWQiOiJ3NGw3dGttMGF3MmZyamxrZTVob2Jja3giLCJjZHBQb3J0Ijo5MjIyLCJjZHBXc1BhdGgiOiIiLCJpbnN0YW5jZU5hbWUiOiJicm93c2VyLWVudm95LXByb2R1Y3Rpb24tMTMtcHJvZm91bmQtd29sdmVyaW5lLTQ0MzgiLCJmcWRuIjoicHJvdWQtbGVhZi0zMW13NnMweC5wcm9kLXl1bC11bmlrcmFmdC0yLm9ua2VybmVsLmFwcCIsIm1ldHJvIjoiaHR0cHM6Ly9hcGkucHJvZC15dWwtdW5pa3JhZnQtMi5vbmtlcm5lbC5ydW4vdjEiLCJ1c2VySWQiOiJ5ZmEyd2RlaTluNHhvZTFwZHVhYmZ4dXMiLCJvcmdJZCI6ImlxMnRmMjUzbWlsOWptOWhmZjI3bDhyMiIsInN0ZWFsdGgiOmZhbHNlLCJoZWFkbGVzcyI6ZmFsc2UsImtlcm5lbEh0dHBTZXJ2ZXJQb3J0Ijo0NDQsInRpbWVvdXRTZWNvbmRzIjo2MCwiY3JlYXRlZEF0IjoiMjAyNi0wNC0yMVQyMjoyMjoxMS41NzIzMzI0NDZaIiwiaW1hZ2UiOiJvbmtlcm5lbC9rZXJuZWwtY3UtdjQwOjc5N2U4ZGIiLCJsaXZlU2x1ZyI6IkN0M2RLOXBUSXlGUyIsInByaXZhdGVJUCI6IjE3Mi4xNi4xMC4xNyJ9fQ.o03ve8phxMvr89Sv4jRkNzfBvDKPWqRLgvgTY5rv7YY'
}

────────────────────────────────────────────────────────────
3) Call computer.clickMouse via metro-direct (watch debug log)
────────────────────────────────────────────────────────────
[log_57dd7e] sending request {
  method: 'post',
  url: 'https://api.onkernel.com/browsers/w4l7tkm0aw2frjlke5hobckx/computer/click_mouse',
  options: {
    method: 'post',
    path: '/browsers/w4l7tkm0aw2frjlke5hobckx/computer/click_mouse',
    body: { x: 10, y: 10 }
  },
  headers: {
    accept: '*/*',
    authorization: '***',
    'content-type': 'application/json',
    'user-agent': 'Kernel/JS 0.50.0',
    'x-stainless-arch': 'arm64',
    'x-stainless-lang': 'js',
    'x-stainless-os': 'MacOS',
    'x-stainless-package-version': '0.50.0',
    'x-stainless-retry-count': '0',
    'x-stainless-runtime': 'node',
    'x-stainless-runtime-version': 'v25.2.1'
  }
}
[log_57dd7e] post https://api.onkernel.com/browsers/w4l7tkm0aw2frjlke5hobckx/computer/click_mouse succeeded with status 200 in 2528ms
[log_57dd7e] response start {
  url: 'https://proxy.yul-vigorous-sammet.onkernel.com:8443/browser/kernel/computer/click_mouse?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE4MDgzNDYxMzEsInNlc3Npb24iOnsiaWQiOiJ3NGw3dGttMGF3MmZyamxrZTVob2Jja3giLCJjZHBQb3J0Ijo5MjIyLCJjZHBXc1BhdGgiOiIiLCJpbnN0YW5jZU5hbWUiOiJicm93c2VyLWVudm95LXByb2R1Y3Rpb24tMTMtcHJvZm91bmQtd29sdmVyaW5lLTQ0MzgiLCJmcWRuIjoicHJvdWQtbGVhZi0zMW13NnMweC5wcm9kLXl1bC11bmlrcmFmdC0yLm9ua2VybmVsLmFwcCIsIm1ldHJvIjoiaHR0cHM6Ly9hcGkucHJvZC15dWwtdW5pa3JhZnQtMi5vbmtlcm5lbC5ydW4vdjEiLCJ1c2VySWQiOiJ5ZmEyd2RlaTluNHhvZTFwZHVhYmZ4dXMiLCJvcmdJZCI6ImlxMnRmMjUzbWlsOWptOWhmZjI3bDhyMiIsInN0ZWFsdGgiOmZhbHNlLCJoZWFkbGVzcyI6ZmFsc2UsImtlcm5lbEh0dHBTZXJ2ZXJQb3J0Ijo0NDQsInRpbWVvdXRTZWNvbmRzIjo2MCwiY3JlYXRlZEF0IjoiMjAyNi0wNC0yMVQyMjoyMjoxMS41NzIzMzI0NDZaIiwiaW1hZ2UiOiJvbmtlcm5lbC9rZXJuZWwtY3UtdjQwOjc5N2U4ZGIiLCJsaXZlU2x1ZyI6IkN0M2RLOXBUSXlGUyIsInByaXZhdGVJUCI6IjE3Mi4xNi4xMC4xNyJ9fQ.o03ve8phxMvr89Sv4jRkNzfBvDKPWqRLgvgTY5rv7YY',
  status: 200,
  headers: { 'content-length': '0', date: 'Tue, 21 Apr 2026 22:22:14 GMT' },
  durationMs: 2528
}
[log_57dd7e] response parsed {
  url: 'https://proxy.yul-vigorous-sammet.onkernel.com:8443/browser/kernel/computer/click_mouse?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE4MDgzNDYxMzEsInNlc3Npb24iOnsiaWQiOiJ3NGw3dGttMGF3MmZyamxrZTVob2Jja3giLCJjZHBQb3J0Ijo5MjIyLCJjZHBXc1BhdGgiOiIiLCJpbnN0YW5jZU5hbWUiOiJicm93c2VyLWVudm95LXByb2R1Y3Rpb24tMTMtcHJvZm91bmQtd29sdmVyaW5lLTQ0MzgiLCJmcWRuIjoicHJvdWQtbGVhZi0zMW13NnMweC5wcm9kLXl1bC11bmlrcmFmdC0yLm9ua2VybmVsLmFwcCIsIm1ldHJvIjoiaHR0cHM6Ly9hcGkucHJvZC15dWwtdW5pa3JhZnQtMi5vbmtlcm5lbC5ydW4vdjEiLCJ1c2VySWQiOiJ5ZmEyd2RlaTluNHhvZTFwZHVhYmZ4dXMiLCJvcmdJZCI6ImlxMnRmMjUzbWlsOWptOWhmZjI3bDhyMiIsInN0ZWFsdGgiOmZhbHNlLCJoZWFkbGVzcyI6ZmFsc2UsImtlcm5lbEh0dHBTZXJ2ZXJQb3J0Ijo0NDQsInRpbWVvdXRTZWNvbmRzIjo2MCwiY3JlYXRlZEF0IjoiMjAyNi0wNC0yMVQyMjoyMjoxMS41NzIzMzI0NDZaIiwiaW1hZ2UiOiJvbmtlcm5lbC9rZXJuZWwtY3UtdjQwOjc5N2U4ZGIiLCJsaXZlU2x1ZyI6IkN0M2RLOXBUSXlGUyIsInByaXZhdGVJUCI6IjE3Mi4xNi4xMC4xNyJ9fQ.o03ve8phxMvr89Sv4jRkNzfBvDKPWqRLgvgTY5rv7YY',
  status: 200,
  body: '',
  durationMs: 2530
}
  metro-direct call: 2531 ms

────────────────────────────────────────────────────────────
4) Same call via the public API for comparison
────────────────────────────────────────────────────────────
  public-API   call: 1124 ms

────────────────────────────────────────────────────────────
5) Repeat both, 3x each, to get a steady-state read
────────────────────────────────────────────────────────────
[log_d3f00c] sending request {
  method: 'post',
  url: 'https://api.onkernel.com/browsers/w4l7tkm0aw2frjlke5hobckx/computer/click_mouse',
  options: {
    method: 'post',
    path: '/browsers/w4l7tkm0aw2frjlke5hobckx/computer/click_mouse',
    body: { x: 30, y: 30 }
  },
  headers: {
    accept: '*/*',
    authorization: '***',
    'content-type': 'application/json',
    'user-agent': 'Kernel/JS 0.50.0',
    'x-stainless-arch': 'arm64',
    'x-stainless-lang': 'js',
    'x-stainless-os': 'MacOS',
    'x-stainless-package-version': '0.50.0',
    'x-stainless-retry-count': '0',
    'x-stainless-runtime': 'node',
    'x-stainless-runtime-version': 'v25.2.1'
  }
}
[log_d3f00c] post https://api.onkernel.com/browsers/w4l7tkm0aw2frjlke5hobckx/computer/click_mouse succeeded with status 200 in 910ms
[log_d3f00c] response start {
  url: 'https://proxy.yul-vigorous-sammet.onkernel.com:8443/browser/kernel/computer/click_mouse?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE4MDgzNDYxMzEsInNlc3Npb24iOnsiaWQiOiJ3NGw3dGttMGF3MmZyamxrZTVob2Jja3giLCJjZHBQb3J0Ijo5MjIyLCJjZHBXc1BhdGgiOiIiLCJpbnN0YW5jZU5hbWUiOiJicm93c2VyLWVudm95LXByb2R1Y3Rpb24tMTMtcHJvZm91bmQtd29sdmVyaW5lLTQ0MzgiLCJmcWRuIjoicHJvdWQtbGVhZi0zMW13NnMweC5wcm9kLXl1bC11bmlrcmFmdC0yLm9ua2VybmVsLmFwcCIsIm1ldHJvIjoiaHR0cHM6Ly9hcGkucHJvZC15dWwtdW5pa3JhZnQtMi5vbmtlcm5lbC5ydW4vdjEiLCJ1c2VySWQiOiJ5ZmEyd2RlaTluNHhvZTFwZHVhYmZ4dXMiLCJvcmdJZCI6ImlxMnRmMjUzbWlsOWptOWhmZjI3bDhyMiIsInN0ZWFsdGgiOmZhbHNlLCJoZWFkbGVzcyI6ZmFsc2UsImtlcm5lbEh0dHBTZXJ2ZXJQb3J0Ijo0NDQsInRpbWVvdXRTZWNvbmRzIjo2MCwiY3JlYXRlZEF0IjoiMjAyNi0wNC0yMVQyMjoyMjoxMS41NzIzMzI0NDZaIiwiaW1hZ2UiOiJvbmtlcm5lbC9rZXJuZWwtY3UtdjQwOjc5N2U4ZGIiLCJsaXZlU2x1ZyI6IkN0M2RLOXBUSXlGUyIsInByaXZhdGVJUCI6IjE3Mi4xNi4xMC4xNyJ9fQ.o03ve8phxMvr89Sv4jRkNzfBvDKPWqRLgvgTY5rv7YY',
  status: 200,
  headers: { 'content-length': '0', date: 'Tue, 21 Apr 2026 22:22:16 GMT' },
  durationMs: 910
}
[log_d3f00c] response parsed {
  url: 'https://proxy.yul-vigorous-sammet.onkernel.com:8443/browser/kernel/computer/click_mouse?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE4MDgzNDYxMzEsInNlc3Npb24iOnsiaWQiOiJ3NGw3dGttMGF3MmZyamxrZTVob2Jja3giLCJjZHBQb3J0Ijo5MjIyLCJjZHBXc1BhdGgiOiIiLCJpbnN0YW5jZU5hbWUiOiJicm93c2VyLWVudm95LXByb2R1Y3Rpb24tMTMtcHJvZm91bmQtd29sdmVyaW5lLTQ0MzgiLCJmcWRuIjoicHJvdWQtbGVhZi0zMW13NnMweC5wcm9kLXl1bC11bmlrcmFmdC0yLm9ua2VybmVsLmFwcCIsIm1ldHJvIjoiaHR0cHM6Ly9hcGkucHJvZC15dWwtdW5pa3JhZnQtMi5vbmtlcm5lbC5ydW4vdjEiLCJ1c2VySWQiOiJ5ZmEyd2RlaTluNHhvZTFwZHVhYmZ4dXMiLCJvcmdJZCI6ImlxMnRmMjUzbWlsOWptOWhmZjI3bDhyMiIsInN0ZWFsdGgiOmZhbHNlLCJoZWFkbGVzcyI6ZmFsc2UsImtlcm5lbEh0dHBTZXJ2ZXJQb3J0Ijo0NDQsInRpbWVvdXRTZWNvbmRzIjo2MCwiY3JlYXRlZEF0IjoiMjAyNi0wNC0yMVQyMjoyMjoxMS41NzIzMzI0NDZaIiwiaW1hZ2UiOiJvbmtlcm5lbC9rZXJuZWwtY3UtdjQwOjc5N2U4ZGIiLCJsaXZlU2x1ZyI6IkN0M2RLOXBUSXlGUyIsInByaXZhdGVJUCI6IjE3Mi4xNi4xMC4xNyJ9fQ.o03ve8phxMvr89Sv4jRkNzfBvDKPWqRLgvgTY5rv7YY',
  status: 200,
  body: '',
  durationMs: 911
}
  metro-direct #1: 913 ms
  public-API   #1: 1171 ms
[log_7e40db] sending request {
  method: 'post',
  url: 'https://api.onkernel.com/browsers/w4l7tkm0aw2frjlke5hobckx/computer/click_mouse',
  options: {
    method: 'post',
    path: '/browsers/w4l7tkm0aw2frjlke5hobckx/computer/click_mouse',
    body: { x: 31, y: 31 }
  },
  headers: {
    accept: '*/*',
    authorization: '***',
    'content-type': 'application/json',
    'user-agent': 'Kernel/JS 0.50.0',
    'x-stainless-arch': 'arm64',
    'x-stainless-lang': 'js',
    'x-stainless-os': 'MacOS',
    'x-stainless-package-version': '0.50.0',
    'x-stainless-retry-count': '0',
    'x-stainless-runtime': 'node',
    'x-stainless-runtime-version': 'v25.2.1'
  }
}
[log_7e40db] post https://api.onkernel.com/browsers/w4l7tkm0aw2frjlke5hobckx/computer/click_mouse succeeded with status 200 in 857ms
[log_7e40db] response start {
  url: 'https://proxy.yul-vigorous-sammet.onkernel.com:8443/browser/kernel/computer/click_mouse?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE4MDgzNDYxMzEsInNlc3Npb24iOnsiaWQiOiJ3NGw3dGttMGF3MmZyamxrZTVob2Jja3giLCJjZHBQb3J0Ijo5MjIyLCJjZHBXc1BhdGgiOiIiLCJpbnN0YW5jZU5hbWUiOiJicm93c2VyLWVudm95LXByb2R1Y3Rpb24tMTMtcHJvZm91bmQtd29sdmVyaW5lLTQ0MzgiLCJmcWRuIjoicHJvdWQtbGVhZi0zMW13NnMweC5wcm9kLXl1bC11bmlrcmFmdC0yLm9ua2VybmVsLmFwcCIsIm1ldHJvIjoiaHR0cHM6Ly9hcGkucHJvZC15dWwtdW5pa3JhZnQtMi5vbmtlcm5lbC5ydW4vdjEiLCJ1c2VySWQiOiJ5ZmEyd2RlaTluNHhvZTFwZHVhYmZ4dXMiLCJvcmdJZCI6ImlxMnRmMjUzbWlsOWptOWhmZjI3bDhyMiIsInN0ZWFsdGgiOmZhbHNlLCJoZWFkbGVzcyI6ZmFsc2UsImtlcm5lbEh0dHBTZXJ2ZXJQb3J0Ijo0NDQsInRpbWVvdXRTZWNvbmRzIjo2MCwiY3JlYXRlZEF0IjoiMjAyNi0wNC0yMVQyMjoyMjoxMS41NzIzMzI0NDZaIiwiaW1hZ2UiOiJvbmtlcm5lbC9rZXJuZWwtY3UtdjQwOjc5N2U4ZGIiLCJsaXZlU2x1ZyI6IkN0M2RLOXBUSXlGUyIsInByaXZhdGVJUCI6IjE3Mi4xNi4xMC4xNyJ9fQ.o03ve8phxMvr89Sv4jRkNzfBvDKPWqRLgvgTY5rv7YY',
  status: 200,
  headers: { 'content-length': '0', date: 'Tue, 21 Apr 2026 22:22:18 GMT' },
  durationMs: 857
}
[log_7e40db] response parsed {
  url: 'https://proxy.yul-vigorous-sammet.onkernel.com:8443/browser/kernel/computer/click_mouse?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE4MDgzNDYxMzEsInNlc3Npb24iOnsiaWQiOiJ3NGw3dGttMGF3MmZyamxrZTVob2Jja3giLCJjZHBQb3J0Ijo5MjIyLCJjZHBXc1BhdGgiOiIiLCJpbnN0YW5jZU5hbWUiOiJicm93c2VyLWVudm95LXByb2R1Y3Rpb24tMTMtcHJvZm91bmQtd29sdmVyaW5lLTQ0MzgiLCJmcWRuIjoicHJvdWQtbGVhZi0zMW13NnMweC5wcm9kLXl1bC11bmlrcmFmdC0yLm9ua2VybmVsLmFwcCIsIm1ldHJvIjoiaHR0cHM6Ly9hcGkucHJvZC15dWwtdW5pa3JhZnQtMi5vbmtlcm5lbC5ydW4vdjEiLCJ1c2VySWQiOiJ5ZmEyd2RlaTluNHhvZTFwZHVhYmZ4dXMiLCJvcmdJZCI6ImlxMnRmMjUzbWlsOWptOWhmZjI3bDhyMiIsInN0ZWFsdGgiOmZhbHNlLCJoZWFkbGVzcyI6ZmFsc2UsImtlcm5lbEh0dHBTZXJ2ZXJQb3J0Ijo0NDQsInRpbWVvdXRTZWNvbmRzIjo2MCwiY3JlYXRlZEF0IjoiMjAyNi0wNC0yMVQyMjoyMjoxMS41NzIzMzI0NDZaIiwiaW1hZ2UiOiJvbmtlcm5lbC9rZXJuZWwtY3UtdjQwOjc5N2U4ZGIiLCJsaXZlU2x1ZyI6IkN0M2RLOXBUSXlGUyIsInByaXZhdGVJUCI6IjE3Mi4xNi4xMC4xNyJ9fQ.o03ve8phxMvr89Sv4jRkNzfBvDKPWqRLgvgTY5rv7YY',
  status: 200,
  body: '',
  durationMs: 858
}
  metro-direct #2: 858 ms
  public-API   #2: 1100 ms
[log_e04fa6] sending request {
  method: 'post',
  url: 'https://api.onkernel.com/browsers/w4l7tkm0aw2frjlke5hobckx/computer/click_mouse',
  options: {
    method: 'post',
    path: '/browsers/w4l7tkm0aw2frjlke5hobckx/computer/click_mouse',
    body: { x: 32, y: 32 }
  },
  headers: {
    accept: '*/*',
    authorization: '***',
    'content-type': 'application/json',
    'user-agent': 'Kernel/JS 0.50.0',
    'x-stainless-arch': 'arm64',
    'x-stainless-lang': 'js',
    'x-stainless-os': 'MacOS',
    'x-stainless-package-version': '0.50.0',
    'x-stainless-retry-count': '0',
    'x-stainless-runtime': 'node',
    'x-stainless-runtime-version': 'v25.2.1'
  }
}
[log_e04fa6] post https://api.onkernel.com/browsers/w4l7tkm0aw2frjlke5hobckx/computer/click_mouse succeeded with status 200 in 831ms
[log_e04fa6] response start {
  url: 'https://proxy.yul-vigorous-sammet.onkernel.com:8443/browser/kernel/computer/click_mouse?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE4MDgzNDYxMzEsInNlc3Npb24iOnsiaWQiOiJ3NGw3dGttMGF3MmZyamxrZTVob2Jja3giLCJjZHBQb3J0Ijo5MjIyLCJjZHBXc1BhdGgiOiIiLCJpbnN0YW5jZU5hbWUiOiJicm93c2VyLWVudm95LXByb2R1Y3Rpb24tMTMtcHJvZm91bmQtd29sdmVyaW5lLTQ0MzgiLCJmcWRuIjoicHJvdWQtbGVhZi0zMW13NnMweC5wcm9kLXl1bC11bmlrcmFmdC0yLm9ua2VybmVsLmFwcCIsIm1ldHJvIjoiaHR0cHM6Ly9hcGkucHJvZC15dWwtdW5pa3JhZnQtMi5vbmtlcm5lbC5ydW4vdjEiLCJ1c2VySWQiOiJ5ZmEyd2RlaTluNHhvZTFwZHVhYmZ4dXMiLCJvcmdJZCI6ImlxMnRmMjUzbWlsOWptOWhmZjI3bDhyMiIsInN0ZWFsdGgiOmZhbHNlLCJoZWFkbGVzcyI6ZmFsc2UsImtlcm5lbEh0dHBTZXJ2ZXJQb3J0Ijo0NDQsInRpbWVvdXRTZWNvbmRzIjo2MCwiY3JlYXRlZEF0IjoiMjAyNi0wNC0yMVQyMjoyMjoxMS41NzIzMzI0NDZaIiwiaW1hZ2UiOiJvbmtlcm5lbC9rZXJuZWwtY3UtdjQwOjc5N2U4ZGIiLCJsaXZlU2x1ZyI6IkN0M2RLOXBUSXlGUyIsInByaXZhdGVJUCI6IjE3Mi4xNi4xMC4xNyJ9fQ.o03ve8phxMvr89Sv4jRkNzfBvDKPWqRLgvgTY5rv7YY',
  status: 200,
  headers: { 'content-length': '0', date: 'Tue, 21 Apr 2026 22:22:20 GMT' },
  durationMs: 831
}
[log_e04fa6] response parsed {
  url: 'https://proxy.yul-vigorous-sammet.onkernel.com:8443/browser/kernel/computer/click_mouse?jwt=eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJleHAiOjE4MDgzNDYxMzEsInNlc3Npb24iOnsiaWQiOiJ3NGw3dGttMGF3MmZyamxrZTVob2Jja3giLCJjZHBQb3J0Ijo5MjIyLCJjZHBXc1BhdGgiOiIiLCJpbnN0YW5jZU5hbWUiOiJicm93c2VyLWVudm95LXByb2R1Y3Rpb24tMTMtcHJvZm91bmQtd29sdmVyaW5lLTQ0MzgiLCJmcWRuIjoicHJvdWQtbGVhZi0zMW13NnMweC5wcm9kLXl1bC11bmlrcmFmdC0yLm9ua2VybmVsLmFwcCIsIm1ldHJvIjoiaHR0cHM6Ly9hcGkucHJvZC15dWwtdW5pa3JhZnQtMi5vbmtlcm5lbC5ydW4vdjEiLCJ1c2VySWQiOiJ5ZmEyd2RlaTluNHhvZTFwZHVhYmZ4dXMiLCJvcmdJZCI6ImlxMnRmMjUzbWlsOWptOWhmZjI3bDhyMiIsInN0ZWFsdGgiOmZhbHNlLCJoZWFkbGVzcyI6ZmFsc2UsImtlcm5lbEh0dHBTZXJ2ZXJQb3J0Ijo0NDQsInRpbWVvdXRTZWNvbmRzIjo2MCwiY3JlYXRlZEF0IjoiMjAyNi0wNC0yMVQyMjoyMjoxMS41NzIzMzI0NDZaIiwiaW1hZ2UiOiJvbmtlcm5lbC9rZXJuZWwtY3UtdjQwOjc5N2U4ZGIiLCJsaXZlU2x1ZyI6IkN0M2RLOXBUSXlGUyIsInByaXZhdGVJUCI6IjE3Mi4xNi4xMC4xNyJ9fQ.o03ve8phxMvr89Sv4jRkNzfBvDKPWqRLgvgTY5rv7YY',
  status: 200,
  body: '',
  durationMs: 833
}
  metro-direct #3: 834 ms
  public-API   #3: 1118 ms

────────────────────────────────────────────────────────────
6) Result
────────────────────────────────────────────────────────────
  metro-direct avg: 868 ms (samples: 913, 858, 834)
  public-API   avg: 1130 ms (samples: 1171, 1100, 1118)
  delta: 262 ms

OK

────────────────────────────────────────────────────────────
cleanup
────────────────────────────────────────────────────────────
  deleted w4l7tkm0aw2frjlke5hobckx
✨  Done in 11.50s.

Note

Medium Risk
Adds an opt-in fetch rewrite layer that changes how browser subresource requests are routed and authenticated (JWT query param vs Authorization), which could affect request correctness and error handling despite being disabled by default.

Overview
Introduces an opt-in “metro-direct” routing mode for browser subresource endpoints that transparently rewrites eligible GET/POST /browsers/{id}/{subresource}/... calls to the per-browser base_url with ?jwt=..., and strips the Authorization header.

Adds an in-memory BrowserRouteCache that is auto-populated by sniffing Browser-shaped JSON responses (e.g., browsers.create()), plus a fallback behavior that evicts cache entries and retries via the public API when metro responds with 401/403/404.

Includes a routing smoke-test script (examples/browser-routing-smoke.ts) and a new test suite covering URL rewriting, allowlist behavior, cache population, and retry/eviction logic.

Reviewed by Cursor Bugbot for commit 9aab517. Bugbot is set up for automated code reviews on this repo. Configure here.

@firetiger-agent
Copy link
Copy Markdown

Firetiger deploy monitoring skipped

This PR didn't match the auto-monitor filter configured on your GitHub connection:

Any PR that changes the kernel API. Monitor changes to API endpoints (packages/api/cmd/api/) and Temporal workflows (packages/api/lib/temporal) in the kernel repo

Reason: PR is marked [wip] with only test output in the body and no actual code changes provided; unable to assess if kernel API endpoints or Temporal workflows were modified.

To monitor this PR anyway, reply with @firetiger monitor this.

@Sayan- Sayan- mentioned this pull request Apr 21, 2026
2 tasks
Copy link
Copy Markdown

@cursor cursor Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cursor Bugbot has reviewed your changes and found 3 potential issues.

Fix All in Cursor

❌ Bugbot Autofix is OFF. To automatically fix reported issues with cloud agents, enable autofix in the Cursor dashboard.

Reviewed by Cursor Bugbot for commit 9aab517. Configure here.

Comment thread src/client.ts
inner: this.fetch,
cache: this.browserRouteCache,
});
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Routing fetch double-wraps on withOptions calls

Medium Severity

When browserRouting is enabled and withOptions() is called, the routing fetch gets double-wrapped. withOptions passes fetch: this.fetch (the already-wrapped routing fetch), while this._options still carries browserRouting: { enabled: true }. The new constructor then wraps the already-wrapped fetch with another createRoutingFetch layer. Each withOptions call adds another nested routing layer, each with its own separate BrowserRouteCache, causing duplicate response cloning/parsing and cache isolation.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 9aab517. Configure here.

*
* Usage (from the repo root):
*
* cd /Users/sayan/kernel/kernel-node-sdk
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hardcoded personal filesystem path in example file

Low Severity

The usage comment contains a hardcoded personal directory path (/Users/sayan/kernel/kernel-node-sdk). This leaks a developer's local filesystem layout and isn't useful for other developers.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 9aab517. Configure here.

);
cache.evict(match.id);
const fallback = await inner(input, init);
return sniffAndPopulateCache(fallback, cache);
Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Discarded metro-direct response body never consumed causing resource leak

Medium Severity

When the metro-direct call returns 401/403/404, the resp from that call is discarded without consuming or cancelling its body stream. The SDK itself explicitly cancels unconsumed response bodies before retrying (via Shims.CancelReadableStream(response.body) in makeRequest), but the routing fetch skips this step. Under high request volume, this can cause connection pool exhaustion as abandoned sockets wait to time out.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit 9aab517. Configure here.

@rgarcia
Copy link
Copy Markdown
Contributor

rgarcia commented Apr 22, 2026

Thanks for drawing this up. I considered this and I go back and forth, but I think the question comes down to how much magic we want to accept in the SDK. Looking at this now, it doesn't seem like a lot of magic, so I think I'm more inclined to do this approach. I will keep exploring this idea and also see if it's possible to do something architecturally similar in the other SDKs so that there's not too much to juggle in terms of concepts

rgarcia added a commit that referenced this pull request Apr 22, 2026
Trim the node browser routing changes down to the cache/interceptor shape from PR #100 and remove the leftover browser-scoped example and priming surface.

Made-with: Cursor
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants