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
14 changes: 14 additions & 0 deletions src/chrome/src/agent/adapters.js
Original file line number Diff line number Diff line change
Expand Up @@ -16292,6 +16292,20 @@ const ADAPTERS = [
- Treat QR "扫码", password, SMS "短信", payment/real-name verification, a blank flights page, and HTTP 432 as blocking challenges. Do not retry or enter unprovided identity details; ask the user. For HTTP 432, pause and return through www.ctrip.com's "机票" entry.
- On the review page, remove only unrequested chargeable extras; preserve beneficial coupons and check their restrictions. Re-read travelers, contact, itinerary, terms, currency, and total; get explicit confirmation before "提交订单".
- Report success only with "订单号" plus "预订成功" or the applicable "出票成功" status. Pending confirmation, a payment redirect, or an itinerary held for payment is incomplete.`,
},
{
name: 'traveloka',
category: 'general',
matches: (url) => /^https?:\/\/(?:www\.)?traveloka\.com\//.test(url),
notes: `
- Observed 2026-08: an automated visit can return HTTP 405 with "Human Verification", "Let's confirm you are human", and a "Begin" control instead of inventory. Stop and ask the user to complete it manually; do not retry, bypass it, or report that no trips or rooms exist.
- Choose the requested product before entering details: "Flights" and "Hotels" have different search, traveler/guest, payment, and fulfillment rules. Re-read locale, language, and currency, then set exact cities or properties, local dates, rooms or travelers, and one-way/round-trip intent.
- For a flight, verify airports, local departure/arrival dates and times, operating and marketing carrier for a code-share, stops, connection requirements, cabin, and fare rules. A round trip built from two one-way tickets can create separate bookings and separate payments with independent change, cancellation, and disruption handling.
- Compare the selected offer's supplier and final payable amount, not a headline or crossed-out fare. Read included baggage, taxes, fees, currency, refund/change conditions, and all ancillaries such as seats, meals, insurance, or extra baggage; keep unrequested paid additions out of the order.
- For a hotel, verify the exact property and room, occupancy, bed, meals, inclusions, taxes, supplier charges, check-in/out, and policy. "Pay Now" and "Pay at Hotel" differ in payment timing and possible hotel-side charges; read the cancellation deadline, refundability, and no-show consequence for the selected room.
- On order review, re-read every traveler/guest name, required document data, contact, itinerary or stay, supplier, add-ons, policy, payment timing, currency, and total. Never invent identity details, and require explicit confirmation before creating the booking or making payment.
- After payment, obtain the voucher, e-ticket, or booking confirmation and verify the supplier's confirmation state. Use that booking's own policy and Help flow for a refund or reschedule; eligibility, fees, method, timing, and any Traveloka balance depend on the fare/room and supplier.
- Report success only from "Bookings" with a booking ID and explicit confirmed/ticketed status for every product or leg. Search results, a selected offer, payment redirect, pending supplier confirmation, or an unconfirmed itinerary are incomplete.`,
},
{
name: 'dianping',
Expand Down
14 changes: 14 additions & 0 deletions src/firefox/src/agent/adapters.js
Original file line number Diff line number Diff line change
Expand Up @@ -16290,6 +16290,20 @@ const ADAPTERS = [
- Treat QR "扫码", password, SMS "短信", payment/real-name verification, a blank flights page, and HTTP 432 as blocking challenges. Do not retry or enter unprovided identity details; ask the user. For HTTP 432, pause and return through www.ctrip.com's "机票" entry.
- On the review page, remove only unrequested chargeable extras; preserve beneficial coupons and check their restrictions. Re-read travelers, contact, itinerary, terms, currency, and total; get explicit confirmation before "提交订单".
- Report success only with "订单号" plus "预订成功" or the applicable "出票成功" status. Pending confirmation, a payment redirect, or an itinerary held for payment is incomplete.`,
},
{
name: 'traveloka',
category: 'general',
matches: (url) => /^https?:\/\/(?:www\.)?traveloka\.com\//.test(url),
notes: `
- Observed 2026-08: an automated visit can return HTTP 405 with "Human Verification", "Let's confirm you are human", and a "Begin" control instead of inventory. Stop and ask the user to complete it manually; do not retry, bypass it, or report that no trips or rooms exist.
- Choose the requested product before entering details: "Flights" and "Hotels" have different search, traveler/guest, payment, and fulfillment rules. Re-read locale, language, and currency, then set exact cities or properties, local dates, rooms or travelers, and one-way/round-trip intent.
- For a flight, verify airports, local departure/arrival dates and times, operating and marketing carrier for a code-share, stops, connection requirements, cabin, and fare rules. A round trip built from two one-way tickets can create separate bookings and separate payments with independent change, cancellation, and disruption handling.
- Compare the selected offer's supplier and final payable amount, not a headline or crossed-out fare. Read included baggage, taxes, fees, currency, refund/change conditions, and all ancillaries such as seats, meals, insurance, or extra baggage; keep unrequested paid additions out of the order.
- For a hotel, verify the exact property and room, occupancy, bed, meals, inclusions, taxes, supplier charges, check-in/out, and policy. "Pay Now" and "Pay at Hotel" differ in payment timing and possible hotel-side charges; read the cancellation deadline, refundability, and no-show consequence for the selected room.
- On order review, re-read every traveler/guest name, required document data, contact, itinerary or stay, supplier, add-ons, policy, payment timing, currency, and total. Never invent identity details, and require explicit confirmation before creating the booking or making payment.
- After payment, obtain the voucher, e-ticket, or booking confirmation and verify the supplier's confirmation state. Use that booking's own policy and Help flow for a refund or reschedule; eligibility, fees, method, timing, and any Traveloka balance depend on the fare/room and supplier.
- Report success only from "Bookings" with a booking ID and explicit confirmed/ticketed status for every product or leg. Search results, a selected offer, payment redirect, pending supplier confirmation, or an unconfirmed itinerary are incomplete.`,
},
{
name: 'dianping',
Expand Down
42 changes: 42 additions & 0 deletions test/run.js
Original file line number Diff line number Diff line change
Expand Up @@ -2866,6 +2866,48 @@ test('matches Ctrip travel surfaces and includes Chinese booking guidance', () =
assert.equal(firefoxAdapter?.notes, adapter?.notes);
});

test('matches Traveloka consumer pages and distinguishes booking and fulfillment states', () => {
const trustedUrls = [
'https://traveloka.com/en-id/',
'https://www.traveloka.com/en-id/flight',
'https://www.traveloka.com/en-id/hotel',
'https://www.traveloka.com/en-id/help',
];
for (const url of trustedUrls) {
assert.equal(getActiveAdapter(url)?.name, 'traveloka');
assert.equal(getActiveAdapterFx(url)?.name, 'traveloka');
}

const rejectedUrls = [
'https://partner.traveloka.com/',
'https://careers.traveloka.com/',
'https://affiliate.traveloka.com/',
'https://traveloka.com.phishing.example/en-id/flight',
'https://example.com/?next=https://www.traveloka.com/en-id/hotel',
];
for (const url of rejectedUrls) {
assert.notEqual(getActiveAdapter(url)?.name, 'traveloka');
assert.notEqual(getActiveAdapterFx(url)?.name, 'traveloka');
}

const adapter = getActiveAdapter('https://www.traveloka.com/en-id/flight');
const firefoxAdapter = getActiveAdapterFx('https://traveloka.com/en-id/hotel');
assert.match(adapter?.notes || '', /2026-08/);
assert.match(adapter?.notes || '', /Human Verification.*Let's confirm you are human.*Begin/s);
assert.match(adapter?.notes || '', /Flights.*Hotels/s);
assert.match(adapter?.notes || '', /code-share.*separate bookings.*separate payments/s);
assert.match(adapter?.notes || '', /baggage.*taxes.*fees/s);
assert.match(adapter?.notes || '', /Pay Now.*Pay at Hotel/s);
assert.match(adapter?.notes || '', /cancellation.*no-show/s);
assert.match(adapter?.notes || '', /ancillaries/);
assert.match(adapter?.notes || '', /explicit confirmation/);
assert.match(adapter?.notes || '', /voucher.*e-ticket.*booking confirmation/s);
assert.match(adapter?.notes || '', /refund.*reschedule/s);
assert.match(adapter?.notes || '', /Bookings.*booking ID.*status/s);
assert.equal((adapter?.notes || '').trim().split('\n').filter((line) => line.startsWith('- ')).length, 8);
assert.equal(firefoxAdapter?.notes, adapter?.notes);
});

test('matches Qunar travel surfaces and distinguishes search, supplier, order, and ticket states', () => {
const trustedUrls = [
'https://qunar.com/', 'https://www.qunar.com/', 'https://flight.qunar.com/',
Expand Down
Loading