Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
15 changes: 15 additions & 0 deletions src/chrome/src/agent/adapters.js
Original file line number Diff line number Diff line change
Expand Up @@ -16279,6 +16279,21 @@ const ADAPTERS = [
- Pre-orders / "Made to order" listings have a longer ship date — surface that to the user before buying.`,
},

// ─── Regional — Mercado Libre / Mercado Livre (LATAM) ────────────────
// Start with the AR, MX, and BR storefronts requested in CONTRIBUTING.md.
// Other country sites need separate localization research before inclusion.
{
name: 'mercado-libre',
category: 'general',
matches: (url) => /^https?:\/\/(?:[a-z0-9-]+\.)*(?:mercadolibre\.com\.(?:ar|mx)|mercadolivre\.com\.br)\//.test(url),
notes: `
- Multi-seller MARKETPLACE. As of 2026-07 the buy controls are AR/MX "Comprar ahora" / "Agregar al carrito" / "Otras opciones de compra"; BR "Comprar agora" / "Adicionar ao carrinho" / "Outras opções de compra". Use one locale's labels, never a blend of the two.
- Catalog pages (path contains /p/MLA…, /p/MLM…, /p/MLB…) group MANY sellers under one product: the buy box is ONE offer, and "Otras opciones de compra"/"Outras opções de compra" lists the rest at different prices and arrival dates — open it before quoting a price. Single-seller listings (articulo.mercadolibre.com.*, produto.mercadolivre.com.br, paths ending -_JM) have no such list.
- Shipping cost and arrival date are computed from the destination "código postal" (AR/MX) / "CEP" (BR) and differ per seller. Set it before stating either, and re-check in the cart.
- Buy-now hands off to a Mercado Pago host where this guidance stops applying — confirm the final total there.
- Search hosts (listado.mercadolibre.com.ar, listado.mercadolibre.com.mx, lista.mercadolivre.com.br) can redirect automation to /gz/account-verification. If that wall appears, STOP and ask the user to complete it manually — do not retry, bypass, or claim results were read.`,
},

// ─── Regional — Türkiye (TR) ──────────────────────────────────────────
// Regional adapters are the project's #1 wanted contribution (CONTRIBUTING.md);
// Türkiye is top of the priority list. Add more TR sites (trendyol,
Expand Down
15 changes: 15 additions & 0 deletions src/firefox/src/agent/adapters.js
Original file line number Diff line number Diff line change
Expand Up @@ -16277,6 +16277,21 @@ const ADAPTERS = [
- Pre-orders / "Made to order" listings have a longer ship date — surface that to the user before buying.`,
},

// ─── Regional — Mercado Libre / Mercado Livre (LATAM) ────────────────
// Start with the AR, MX, and BR storefronts requested in CONTRIBUTING.md.
// Other country sites need separate localization research before inclusion.
{
name: 'mercado-libre',
category: 'general',
matches: (url) => /^https?:\/\/(?:[a-z0-9-]+\.)*(?:mercadolibre\.com\.(?:ar|mx)|mercadolivre\.com\.br)\//.test(url),
notes: `
- Multi-seller MARKETPLACE. As of 2026-07 the buy controls are AR/MX "Comprar ahora" / "Agregar al carrito" / "Otras opciones de compra"; BR "Comprar agora" / "Adicionar ao carrinho" / "Outras opções de compra". Use one locale's labels, never a blend of the two.
- Catalog pages (path contains /p/MLA…, /p/MLM…, /p/MLB…) group MANY sellers under one product: the buy box is ONE offer, and "Otras opciones de compra"/"Outras opções de compra" lists the rest at different prices and arrival dates — open it before quoting a price. Single-seller listings (articulo.mercadolibre.com.*, produto.mercadolivre.com.br, paths ending -_JM) have no such list.
- Shipping cost and arrival date are computed from the destination "código postal" (AR/MX) / "CEP" (BR) and differ per seller. Set it before stating either, and re-check in the cart.
- Buy-now hands off to a Mercado Pago host where this guidance stops applying — confirm the final total there.
- Search hosts (listado.mercadolibre.com.ar, listado.mercadolibre.com.mx, lista.mercadolivre.com.br) can redirect automation to /gz/account-verification. If that wall appears, STOP and ask the user to complete it manually — do not retry, bypass, or claim results were read.`,
},

// ─── Regional — Türkiye (TR) ──────────────────────────────────────────
// Regional adapters are the project's #1 wanted contribution (CONTRIBUTING.md);
// Türkiye is top of the priority list. Add more TR sites (trendyol,
Expand Down
44 changes: 44 additions & 0 deletions test/run.js
Original file line number Diff line number Diff line change
Expand Up @@ -2387,6 +2387,50 @@ test('matches apple store pages', () => {
assert.equal(getActiveAdapter('https://secure.store.apple.com/shop/checkout')?.name, 'apple');
});

test('matches Mercado Libre LATAM storefronts and includes marketplace guidance', () => {
const trustedUrls = [
'https://mercadolibre.com.ar/',
'https://www.mercadolibre.com.ar/notebook/p/MLA123',
'https://listado.mercadolibre.com.ar/notebook',
'https://articulo.mercadolibre.com.ar/MLA-123-notebook-_JM',
'https://www.mercadolibre.com.mx/notebook/p/MLM123',
'https://listado.mercadolibre.com.mx/notebook',
'https://mercadolivre.com.br/',
'https://www.mercadolivre.com.br/notebook/p/MLB123',
'https://lista.mercadolivre.com.br/notebook',
'https://produto.mercadolivre.com.br/MLB-123-notebook-_JM',
];
for (const url of trustedUrls) {
assert.equal(getActiveAdapter(url)?.name, 'mercado-libre');
assert.equal(getActiveAdapterFx(url)?.name, 'mercado-libre');
}

const rejectedUrls = [
'https://mercadolibre.com.ar.phishing.example/notebook',
'https://mercadolivre.com.br.evil.example/notebook',
'https://example.com/mercadolibre.com.mx/notebook',
// Other country storefronts need their own localized research before inclusion.
'https://www.mercadolibre.cl/notebook',
];
for (const url of rejectedUrls) {
assert.notEqual(getActiveAdapter(url)?.name, 'mercado-libre');
assert.notEqual(getActiveAdapterFx(url)?.name, 'mercado-libre');
}

const adapter = getActiveAdapter('https://www.mercadolibre.com.mx/notebook/p/MLM123');
const firefoxAdapter = getActiveAdapterFx('https://www.mercadolivre.com.br/notebook/p/MLB123');
assert.match(adapter?.notes || '', /MARKETPLACE/);
assert.match(adapter?.notes || '', /Otras opciones de compra/);
assert.match(adapter?.notes || '', /Outras opções de compra/);
assert.match(adapter?.notes || '', /CEP/);
assert.match(adapter?.notes || '', /account-verification/);
// Checkout leaves the matched hosts, so the notes must hand the total off.
assert.match(adapter?.notes || '', /Mercado Pago/);
// Blended ES/PT labels match no real control on either storefront.
assert.doesNotMatch(adapter?.notes || '', /Agregar\/Adicionar|ahora\/agora|carrito\/carrinho/);
assert.equal(firefoxAdapter?.notes, adapter?.notes);
});

test('matches sahibinden.com and includes anti-bot guidance', () => {
assert.equal(getActiveAdapter('https://www.sahibinden.com/')?.name, 'sahibinden');
assert.equal(getActiveAdapter('https://sahibinden.com/kategori/vasita')?.name, 'sahibinden');
Expand Down
Loading