Skip to content

feat: add browser routing cache#99

Open
rgarcia wants to merge 12 commits intonextfrom
raf/browser-scoped-client
Open

feat: add browser routing cache#99
rgarcia wants to merge 12 commits intonextfrom
raf/browser-scoped-client

Conversation

@rgarcia
Copy link
Copy Markdown
Contributor

@rgarcia rgarcia commented Apr 13, 2026

Summary

  • add browserRouting client config plus a shared browserRouteCache for debugging and cache reuse
  • simplify src/lib/browser-routing.ts down to the cache + request interception flow used to route allowlisted browser subresources directly to the VM
  • keep the browser routing config concise by using subresources for the direct-to-VM allowlist
  • rename the example and focused tests to browser-routing terminology and remove the leftover priming/browser-scoped surface

Test plan

  • ./node_modules/.bin/jest tests/lib/browser-routing.test.ts --runInBand
  • ./node_modules/typescript/bin/tsc --noEmit

Note

Medium Risk
Changes core client request dispatch by optionally wrapping fetch to rewrite allowlisted /browsers/:id/:subresource/* calls to VM base_url with JWT injection and auth header stripping; routing/caching bugs could break browser subresource requests or leak requests to the wrong destination.

Overview
Adds browserRouting client config that, when enabled, wraps the client’s fetch to populate a shared BrowserRouteCache from JSON browser responses and rewrite allowlisted browser subresource requests from the API origin to the browser VM base_url (injecting jwt and removing Authorization).

Introduces Kernel.browserRouteCache (reused across withOptions) and a new browsers.fetch() API implemented via browser-fetch.ts to issue raw HTTP requests through the VM using the cached route. Includes a new example (examples/browser-routing.ts) and Jest coverage for cache warming, allowlist behavior, withOptions cache reuse, and cache-miss errors.

Reviewed by Cursor Bugbot for commit fdd3adf. 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 modifies client library code (browser session client) rather than API endpoints or Temporal workflows in packages/api/

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

Comment thread src/lib/kernel-browser-session.ts Outdated
Comment thread src/lib/kernel-browser-session.ts Outdated
Comment thread src/lib/browser-transport.ts Outdated
rgarcia added 4 commits April 21, 2026 13:09
Bind browser subresource calls to a browser session's base_url and expose raw HTTP through fetch so metro-routed access feels like normal JavaScript networking.

Made-with: Cursor
Fail fast when browser-scoped clients do not have a session base_url, route subresource calls through the browser session base directly, and clean up browser-vm wording.

Made-with: Cursor
Fail fast when browser-scoped clients are missing a browser session base_url, route subresource calls through the session base consistently, and keep lint output clean.

Made-with: Cursor
Replace the handwritten Node browser-scoped façade with deterministic generated bindings from the browser resource graph, and enforce regeneration during lint and build.

Made-with: Cursor
@rgarcia rgarcia force-pushed the raf/browser-scoped-client branch from c5731cb to e730af8 Compare April 21, 2026 17:09
Comment thread examples/browser-scoped.ts Outdated
const kernel = new Kernel();

const created = await kernel.browsers.create({});
const browser = kernel.forBrowser(created);
Copy link
Copy Markdown
Contributor

@Sayan- Sayan- Apr 21, 2026

Choose a reason for hiding this comment

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

I'm not opposed to this tbc but I spent a bit of time scheming up if we could do all these routing decisions right in the sdk without the users having to think about it. Something like a:

  • response interceptor -> cache base urls from creating / acquiring browsers
  • request interceptor -> dynamically route to base url depending on the operation

here's what opus vibed up as a poc #100

wdyt?

Route direct-to-VM browser requests through the shared client cache so the SDK no longer needs the generated browser session wrapper layer.

Made-with: Cursor
Comment thread src/lib/browser-routing.ts
Comment thread src/client.ts Outdated
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
@rgarcia rgarcia changed the title feat: add browser-scoped session client feat: add browser routing cache Apr 22, 2026
Comment thread src/lib/browser-routing.ts
rgarcia added 3 commits April 22, 2026 12:57
Shorten the browserRouting allowlist field to subresources so the direct-to-VM configuration reads more cleanly without changing behavior.

Made-with: Cursor
Keep the node browser-routing example showing both direct subresource routing and the cache-backed /curl/raw path.

Made-with: Cursor
Bring back the cache-backed browser fetch helper so raw HTTP stays on the SDK's language-native surface instead of falling through to manual /curl/raw requests.

Made-with: Cursor
Comment thread src/lib/browser-routing.ts Outdated
throw new KernelError(`browser.fetch unsupported HTTP method: ${method}`);
}
return methodLower as HTTPMethod;
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

normalizeMethod allows methods outside HTTPMethod type

Medium Severity

normalizeMethod accepts 'head' and 'options' in its allowed set and returns them cast as HTTPMethod, but the HTTPMethod type is defined as 'get' | 'post' | 'put' | 'patch' | 'delete' — it does not include those two methods. The as HTTPMethod cast hides this mismatch. When the result is passed into FinalRequestOptions.method, any downstream code relying on the HTTPMethod union will silently receive a value outside its domain.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit b09434e. Configure here.

Comment thread src/lib/browser-transport.ts Outdated
rgarcia added 3 commits April 22, 2026 13:19
Remove the unnecessary generated resource and dependency diffs from the node branch and keep BrowserRouteCache.set() as a direct assignment without trimming user input.

Made-with: Cursor
Tighten the browser routing files to the repo's formatter expectations so the node CI lint job passes cleanly again.

Made-with: Cursor
Split browser.fetch into its own helper, remove unused browser transport code, and simplify withOptions cache sharing so the routing layer stays easier to reason about.

Made-with: Cursor
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 2 potential issues.

There are 3 total unresolved issues (including 1 from previous review).

Fix All in Cursor

Bugbot Autofix is ON. A cloud agent has been kicked off to fix the reported issues. You can view the agent here.

Reviewed by Cursor Bugbot for commit fdd3adf. Configure here.

Comment thread src/lib/browser-fetch.ts

function joinURL(baseURL: string, path: string): string {
return `${baseURL.replace(/\/+$/, '')}${path.startsWith('/') ? path : `/${path}`}`;
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

Duplicate joinURL helper in two new files

Low Severity

Both browser-fetch.ts and browser-routing.ts define identical private joinURL functions with the same signature and implementation. This duplicated logic increases maintenance burden — a fix in one copy could easily be missed in the other. One shared utility would be cleaner.

Additional Locations (1)
Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit fdd3adf. Configure here.

Comment thread src/lib/browser-fetch.ts
throw new KernelError(`browser.fetch unsupported HTTP method: ${method}`);
}
return methodLower as HTTPMethod;
}
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

normalizeMethod allows methods outside HTTPMethod type union

Low Severity

normalizeMethod validates and passes through 'head' and 'options', then casts the result as HTTPMethod. However, HTTPMethod is defined as 'get' | 'post' | 'put' | 'patch' | 'delete' — it does not include those two methods. The as cast silently lies to the type system, which could mask issues if any downstream code narrows on HTTPMethod variants.

Fix in Cursor Fix in Web

Reviewed by Cursor Bugbot for commit fdd3adf. Configure here.

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