On-demand Scout service (replaces the nightly aggregator): - FastAPI agent-mesh service; card name "matchmaking-service" (HTTP /a2a/tasks + Redis-stream worker matching the sibling-service pattern) - run_search: parallel multi-board sweep (Naukri/blackfalcondata + Foundit + LinkedIn), city-filtered at the board, cheapest-per-result first - per-board adapters + normalizers -> ScoutJob with rich read-only details and offsite apply links; recall mode + MVQ guard - result cache for dev replay ($0); per-board cost knobs; retry-on-5xx - research/: engine design, board cost economics, India-actor shortlist, POC
44 lines
1.7 KiB
Python
44 lines
1.7 KiB
Python
"""tour.py — capture each Scout flow state by clicking through via CDP."""
|
|
import asyncio
|
|
|
|
from browser_use import BrowserSession
|
|
from browser_config import make_profile
|
|
|
|
CLICK = """(()=>{const t=%r.toLowerCase();
|
|
const el=[...document.querySelectorAll('button,a,[role=tab],[role=button]')]
|
|
.find(e=>(e.textContent||'').trim().toLowerCase().includes(t));
|
|
if(el){el.click();return (el.textContent||'').trim().slice(0,40)} return null})()"""
|
|
|
|
|
|
async def click(s, text):
|
|
cdp = await s.get_or_create_cdp_session()
|
|
r = await cdp.cdp_client.send.Runtime.evaluate(
|
|
params={"expression": CLICK % text, "returnByValue": True}, session_id=cdp.session_id)
|
|
return r.get("result", {}).get("value")
|
|
|
|
|
|
async def shot(s, path):
|
|
await s.take_screenshot(path=path, full_page=True)
|
|
print("shot", path)
|
|
|
|
|
|
async def main():
|
|
s = BrowserSession(browser_profile=make_profile(headless=True, persist=False))
|
|
await s.start()
|
|
try:
|
|
await s._cdp_set_viewport(width=1320, height=900)
|
|
except Exception as e:
|
|
print("viewport set skipped:", e)
|
|
await s.navigate_to("http://localhost:3001/scout")
|
|
await asyncio.sleep(5)
|
|
await shot(s, "/tmp/sc_2_configure.png") # default tab
|
|
print("Summary ->", await click(s, "Summary")); await asyncio.sleep(2.5); await shot(s, "/tmp/sc_1_summary.png")
|
|
print("Action ->", await click(s, "Action")); await asyncio.sleep(2.5); await shot(s, "/tmp/sc_3_idle.png")
|
|
print("Find ->", await click(s, "Find my matches")); await asyncio.sleep(1.6); await shot(s, "/tmp/sc_4_loading.png")
|
|
await asyncio.sleep(7.5); await shot(s, "/tmp/sc_5_deck.png") # loader → deck
|
|
await s.kill()
|
|
|
|
|
|
if __name__ == "__main__":
|
|
asyncio.run(main())
|