Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
32 commits
Select commit Hold shift + click to select a range
5eaeac3
small updates
miguelg719 Sep 19, 2025
a8fe6fb
changes
miguelg719 Sep 19, 2025
5b455df
render last reasoning
miguelg719 Sep 19, 2025
ff3ba00
add sdk to repo
miguelg719 Sep 26, 2025
bf699bf
fix build errors:
miguelg719 Sep 26, 2025
0ce9fec
error description
miguelg719 Sep 26, 2025
a82f7ef
adding stagehand package to next config
Kylejeong2 Sep 28, 2025
a079f57
update tailwind config ts ignore and exclude sdk from build process
Kylejeong2 Sep 28, 2025
2c165ea
updated sdk
miguelg719 Oct 6, 2025
1ea7c9c
probability based region routing (#13)
sameelarif Oct 6, 2025
993dc58
Revert "probability based region routing (#13)"
sameelarif Oct 6, 2025
fd6bf8b
redo region routing
sameelarif Oct 6, 2025
958d8c8
small updates
miguelg719 Sep 19, 2025
1fae745
changes
miguelg719 Sep 19, 2025
dc7bd03
render last reasoning
miguelg719 Sep 19, 2025
c76cd19
add sdk to repo
miguelg719 Sep 26, 2025
3200b83
adding stagehand package to next config
Kylejeong2 Sep 28, 2025
14f392f
update tailwind config ts ignore and exclude sdk from build process
Kylejeong2 Sep 28, 2025
cf2346a
updated sdk
miguelg719 Oct 6, 2025
96c4acf
probability based region routing (#13)
sameelarif Oct 6, 2025
face517
Revert "probability based region routing (#13)"
sameelarif Oct 6, 2025
1820eef
no inline import
sameelarif Oct 6, 2025
4620227
redo region routing
sameelarif Oct 6, 2025
11cc5b1
add suspense wrapper to home component for search params
Kylejeong2 Oct 6, 2025
f3d9381
pull from edge config
sameelarif Oct 6, 2025
9da2e38
Merge branch 'sameel/flags-new' into sameel/edge-config
sameelarif Oct 6, 2025
880651a
Merge branch 'main' into sameel/edge-config
sameelarif Oct 6, 2025
381115f
fix imports
sameelarif Oct 6, 2025
b45306d
Merge branch 'sameel/flags-new' of https://github.com/browserbase/pri…
sameelarif Oct 7, 2025
968f315
Merge branch 'sameel/flags-new' into sameel/edge-config
sameelarif Oct 7, 2025
33a83eb
Merge pull request #15 from browserbase/sameel/edge-config
sameelarif Oct 7, 2025
3cab49b
pull region dist. from edge config
sameelarif Oct 7, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
The table of contents is too big for display.
Diff view
Diff view
  •  
  •  
  •  
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -83,3 +83,5 @@ target/
# pnpm

test/
.vercel
.env*.local
2 changes: 1 addition & 1 deletion app/api/agent/stream/route.ts
Original file line number Diff line number Diff line change
Expand Up @@ -200,4 +200,4 @@ export async function GET(request: Request) {
"X-Accel-Buffering": "no",
},
});
}
}
219 changes: 149 additions & 70 deletions app/api/session/route.ts
Original file line number Diff line number Diff line change
@@ -1,106 +1,185 @@
import { NextResponse } from "next/server";
import Browserbase from "@browserbasehq/sdk";
import { getAll } from "@vercel/edge-config";
import { NextResponse } from "next/server";

type BrowserbaseRegion =
| "us-west-2"
| "us-east-1"
| "eu-central-1"
| "ap-southeast-1";

// Exact timezone matches for east coast cities
const exactTimezoneMap: Record<string, BrowserbaseRegion> = {
"America/New_York": "us-east-1",
"America/Detroit": "us-east-1",
"America/Toronto": "us-east-1",
"America/Montreal": "us-east-1",
"America/Boston": "us-east-1",
"America/Chicago": "us-east-1",
// Timezone abbreviation to region mapping
const timezoneAbbreviationMap: Record<string, BrowserbaseRegion> = {
// US East Coast
EST: "us-east-1",
EDT: "us-east-1",

// US West Coast
PST: "us-west-2",
PDT: "us-west-2",

// US Mountain/Central - route to appropriate region
MST: "us-west-2",
MDT: "us-west-2",
CST: "us-east-1",
CDT: "us-east-1",

// Europe
GMT: "eu-central-1",
BST: "eu-central-1",
CET: "eu-central-1",
CEST: "eu-central-1",
EET: "eu-central-1",
EEST: "eu-central-1",
WET: "eu-central-1",
WEST: "eu-central-1",

// Asia-Pacific
JST: "ap-southeast-1", // Japan Standard Time
KST: "ap-southeast-1", // Korea Standard Time
IST: "ap-southeast-1", // India Standard Time
AEST: "ap-southeast-1", // Australian Eastern Standard Time
AEDT: "ap-southeast-1", // Australian Eastern Daylight Time
AWST: "ap-southeast-1", // Australian Western Standard Time
NZST: "ap-southeast-1", // New Zealand Standard Time
NZDT: "ap-southeast-1", // New Zealand Daylight Time
};

// Prefix-based region mapping
const prefixToRegion: Record<string, BrowserbaseRegion> = {
America: "us-west-2",
US: "us-west-2",
Canada: "us-west-2",
Europe: "eu-central-1",
Africa: "eu-central-1",
Asia: "ap-southeast-1",
Australia: "ap-southeast-1",
Pacific: "ap-southeast-1",
// Default fallback distributions if edge config is not available
const defaultDistributions: Record<
BrowserbaseRegion,
Record<BrowserbaseRegion, number>
> = {
"us-west-2": {
"us-west-2": 100,
"us-east-1": 0,
"eu-central-1": 0,
"ap-southeast-1": 0,
},
"us-east-1": {
"us-east-1": 100,
"us-west-2": 0,
"eu-central-1": 0,
"ap-southeast-1": 0,
},
"eu-central-1": {
"eu-central-1": 100,
"us-west-2": 0,
"us-east-1": 0,
"ap-southeast-1": 0,
},
"ap-southeast-1": {
"ap-southeast-1": 100,
"us-west-2": 0,
"us-east-1": 0,
"eu-central-1": 0,
},
};

// Offset ranges to regions (inclusive bounds)
const offsetRanges: {
min: number;
max: number;
region: BrowserbaseRegion;
}[] = [
{ min: -24, max: -4, region: "us-west-2" }, // UTC-24 to UTC-4
{ min: -3, max: 4, region: "eu-central-1" }, // UTC-3 to UTC+4
{ min: 5, max: 24, region: "ap-southeast-1" }, // UTC+5 to UTC+24
];

function getClosestRegion(timezone?: string): BrowserbaseRegion {
try {
if (!timezone) {
return "us-west-2"; // Default if no timezone provided
}
function selectRegionWithProbability(
baseRegion: BrowserbaseRegion,
distributions: Record<BrowserbaseRegion, Record<BrowserbaseRegion, number>>
): BrowserbaseRegion {
const distribution = distributions[baseRegion];
if (!distribution) {
return baseRegion;
}

const random = Math.random() * 100; // Generate random number between 0-100

// Check exact matches first
if (timezone in exactTimezoneMap) {
return exactTimezoneMap[timezone];
let cumulativeProbability = 0;
for (const [region, probability] of Object.entries(distribution)) {
cumulativeProbability += probability;
if (random < cumulativeProbability) {
return region as BrowserbaseRegion;
}
}

// Fallback to base region if something goes wrong
return baseRegion;
}

// Check prefix matches
const prefix = timezone.split("/")[0];
if (prefix in prefixToRegion) {
return prefixToRegion[prefix];
function getRegionFromTimezoneAbbr(timezoneAbbr?: string): BrowserbaseRegion {
try {
if (!timezoneAbbr) {
return "us-west-2"; // Default if no timezone provided
}

// Use offset-based fallback
const date = new Date();
// Create a date formatter for the given timezone
const formatter = new Intl.DateTimeFormat("en-US", { timeZone: timezone });
// Get the timezone offset in minutes
const timeString = formatter.format(date);
const testDate = new Date(timeString);
const hourOffset = (testDate.getTime() - date.getTime()) / (1000 * 60 * 60);

const matchingRange = offsetRanges.find(
(range) => hourOffset >= range.min && hourOffset <= range.max
);
// Direct lookup from timezone abbreviation
const region = timezoneAbbreviationMap[timezoneAbbr.toUpperCase()];
if (region) {
return region;
}

return matchingRange?.region ?? "us-west-2";
// Fallback to us-west-2 for unknown abbreviations
return "us-west-2";
} catch {
return "us-west-2";
}
}

interface EdgeConfig {
advancedStealth: boolean | undefined;
proxies: boolean | undefined;
regionDistribution:
| Record<BrowserbaseRegion, Record<BrowserbaseRegion, number>>
| undefined;
}

async function createSession(timezone?: string) {
const bb = new Browserbase({
apiKey: process.env.BROWSERBASE_API_KEY!,
});

const browserSettings: Browserbase.Sessions.SessionCreateParams.BrowserSettings = {
viewport: {
width: 2560,
height: 1440,
},
// @ts-expect-error - os is not a valid property
os: "windows",
blockAds: true,
advancedStealth: true
};

console.log("timezone ", timezone);
console.log("getClosestRegion(timezone)", getClosestRegion(timezone));
const config = await getAll<EdgeConfig>();

const {
advancedStealth: advancedStealthConfig,
proxies: proxiesConfig,
regionDistribution: distributionsConfig,
} = config;

const advancedStealth: boolean = advancedStealthConfig ?? false;
const proxies: boolean = proxiesConfig ?? true;

// Build browserSettings conditionally
const browserSettings: Browserbase.Sessions.SessionCreateParams.BrowserSettings =
{
viewport: {
width: 2560,
height: 1440,
},
blockAds: true,
advancedStealth,
// Only set os if advancedStealth is true
...(advancedStealth
? {
os: "mac",
}
: {
os: "linux",
}),
};

// Use timezone abbreviation to determine base region
const closestRegion = getRegionFromTimezoneAbbr(timezone);

// Get distributions from config or use default
const distributions = distributionsConfig ?? defaultDistributions;

// Apply probability routing for potential load balancing
const finalRegion = selectRegionWithProbability(closestRegion, distributions);

console.log("timezone abbreviation:", timezone);
console.log("mapped to region:", closestRegion);
console.log("final region after probability routing:", finalRegion);

const session = await bb.sessions.create({
projectId: process.env.BROWSERBASE_PROJECT_ID!,
proxies: true,
proxies,
browserSettings,
keepAlive: true,
region: getClosestRegion(timezone),
region: finalRegion,
});
return {
session,
Expand Down
2 changes: 1 addition & 1 deletion app/components/BrowserSessionContainer.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -318,4 +318,4 @@ const BrowserSessionContainer: React.FC<BrowserSessionContainerProps> = ({
);
};

export default BrowserSessionContainer;
export default BrowserSessionContainer;
2 changes: 1 addition & 1 deletion app/components/ChatFeed.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -373,4 +373,4 @@ export default function ChatFeed({
</main>
</motion.div>
);
}
}
6 changes: 3 additions & 3 deletions app/components/NavBar.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -31,7 +31,7 @@ export default function NavBar({
>
<div className="flex items-center gap-2">
<a
href="https://www.browserbase.com/cua/google"
href="https://browserbase.com/computer-use"
target="_blank"
rel="noopener noreferrer"
className="flex items-center gap-3 hover:opacity-90 transition-opacity duration-200"
Expand All @@ -50,7 +50,7 @@ export default function NavBar({
</div>
<div className="flex items-center gap-2">
<a
href="https://www.browserbase.com/cua/google"
href="https://browserbase.com/computer-use"
target="_blank"
rel="noopener noreferrer"
>
Expand All @@ -69,7 +69,7 @@ export default function NavBar({
</a>
{showGitHubButton && (
<a
href="https://github.com/browserbase/google-cua-browser"
href="https://github.com/browserbase/cua-browser"
target="_blank"
rel="noopener noreferrer"
>
Expand Down
Loading