Typed chat: free hosted models -> local model (llama-server), no keyword rules; busy reply + Retry #7

Merged
leora merged 7 commits from feat/local-llm-backup into main 2026-10-08 22:18:21 +08:00
2 changed files with 6 additions and 2 deletions
Showing only changes of commit a2fd100587 - Show all commits

View File

@ -37,11 +37,13 @@ const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
const feeBps = (await (await fetch(BASE + "/api/status")).json()).fee_bps;
const money = (c) => "$" + (c / 100).toFixed(2);
// online checkout: first card that offers online payment
const pick = await page.evaluate(() => {
// online checkout: first card that offers online payment (earlier runs may have sold the online-payable bikes)
const findOnline = () => page.evaluate(() => {
const c = [...document.querySelectorAll("#stage .card")].find((c) => c.querySelector("button.btn:not(.cash)"));
return c && { id: c.dataset.listing, price: c.querySelector(".price").childNodes[0].textContent };
});
let pick = await findOnline();
if (!pick) { await ask("show me the bike tune-up service"); pick = await findOnline(); }
check("an online-payable listing is visible", !!pick, pick && pick.price);
const priceC = Math.round(parseFloat(pick.price.slice(1)) * 100), feeC = Math.round(priceC * feeBps / 10000);
await page.click(`.card[data-listing="${pick.id}"] button.btn:not(.cash)`);

View File

@ -40,6 +40,8 @@ const sleep = (ms) => new Promise((r) => setTimeout(r, ms));
// Guardrails: banner, badge and checkout fee lines must stay visible and >= 4.5:1 contrast.
async function guardrails(label) {
// open a checkout for the first online-payable item via the deterministic click path
// (earlier runs may have sold the online-payable bikes; then ask for something payable online)
if (!(await page.$("#stage .card button.btn:not(.cash)"))) await ask("show me the bike tune-up service");
await page.evaluate(() => { const b = [...document.querySelectorAll("#stage .card button.btn:not(.cash)")][0]; if (b) b.click(); });
const hasCheckout = await page.waitForSelector("[data-component=checkout]", { timeout: 15000 }).then(() => true, () => false);
const r = await page.evaluate(() => {