| name | kimi-webbridge |
| description | Use this skill for browser and website tasks in Genii, including explicit
/webbridge requests. It drives the local Genii desktop runtime through
the genii-desktop OpenClaw tools, which proxy to Kimi WebBridge running next
to Chrome in the bot sandbox.
|
Kimi WebBridge for Genii Desktop
Use this skill for browser and website tasks, including explicit /webbridge
or /kimi-webbridge requests. It handles only the browser portion of a task.
In Genii, OpenClaw, Chrome, and Kimi WebBridge run in the same bot sandbox when
desktop is enabled. Use the genii-desktop tools listed below so progress,
health checks, and browser actions stay on the configured local path.
Health Check
For slow browser work, first say one concise, user-facing progress sentence,
such as "Opening the browser." Do not mention Kimi, WebBridge, or internal
browser driver/tool names in routine progress or ordinary blockers unless the
user explicitly asks for implementation or debugging details. Then call
desktop_progress_notice with driver:"kimi-webbridge" and the same generic
message, followed by desktop_session_status.
Proceed only when the result shows:
- a
session_id
webbridge.running: true
webbridge.extension_connected: true
If the desktop or extension is not healthy, report that browser automation is
unavailable, include the user-relevant stage, and stop. Keep raw driver and
status names in internal diagnostics unless the user explicitly asks for them.
Do not guess fixes. The operator can use the Genii debug UI to restart Desktop
or Gateway.
Tools
| Tool | Args | Use |
|---|
desktop_progress_notice | stage, message, driver | Emit a visible progress event before or between slow desktop steps |
desktop_session_status | none | Health check and desktop runtime id/live URL |
desktop_live_url | none | Return the noVNC desktop viewer URL |
web_navigate | url, newTab, group_title | Open a page in Chrome; defaults to reusing the active task tab |
web_find_tab | url, active | Reuse an already-open tab |
web_snapshot | none | Accessibility tree/text with element refs; first choice for reading/click targets |
web_click | selector | Click an @e ref from snapshot or a CSS selector |
web_fill | selector, value | Fill inputs and contenteditable fields |
web_evaluate | code | Run compact JavaScript in the page |
web_screenshot | format, quality, selector | Visual fallback; avoid full-page screenshots unless needed |
web_list_tabs | none | Inspect current tabs |
web_close_session | none | Close task tabs only when explicitly requested or needed to unblock the task |
Standard Flow
- Emit a progress notice with
desktop_progress_notice.
- Health check with
desktop_session_status.
- If the user says
/webbridge ..., treat the remainder as the browser task.
- Use
web_find_tab for pages that may already be open. Otherwise use
web_navigate with newTab:false or omit newTab so the active task tab
is reused.
- Use
web_snapshot to read page content and locate clickable elements.
- If
web_snapshot is empty or weak, wait briefly and retry once, then use
web_evaluate with compact JavaScript.
- Use
web_screenshot only when the visual state matters or DOM reads are
insufficient. Prefer small JPEG screenshots or element screenshots.
- Leave useful user-visible tabs open, but do not accumulate duplicate task
tabs or Chrome extension popup tabs. Only call
web_close_session or
web_close_tab if the user explicitly asks to close/clean up, or if stale
tabs block the current task.
Evaluate Rules
- Always return compact data. Prefer
JSON.stringify(data) or small arrays.
- Wrap code in an IIFE to avoid re-declaring variables between calls:
(() => {
const data = Array.from(document.querySelectorAll("article")).slice(0, 3);
return JSON.stringify(data.map((item) => item.innerText));
})()
- If you need to scroll, use
web_evaluate:
(() => {
window.scrollBy(0, Math.floor(window.innerHeight * 0.8));
return JSON.stringify({scrolled: true, y: window.scrollY});
})()
X / Twitter Profile Extraction
For requests like "vào X xem karpathy đăng 3 bài gần nhất":
web_find_tab for the profile URL, then web_navigate to the profile URL
with newTab:false if no matching tab is open.
- Wait briefly if the first snapshot is sparse.
- Use
web_snapshot first.
- Use
web_evaluate to extract visible post candidates:
(() => {
const posts = Array.from(document.querySelectorAll("article"))
.map((article) => {
const text = article.innerText || "";
const links = Array.from(article.querySelectorAll("a[href*='/status/']"))
.map((a) => new URL(a.getAttribute("href"), location.origin).href);
return { text, links: Array.from(new Set(links)) };
})
.filter((post) => post.text.trim() || post.links.length)
.slice(0, 8);
return JSON.stringify({ url: location.href, title: document.title, posts });
})()
- Open the first distinct status URLs one by one with
web_navigate using
newTab:false unless you explicitly need side-by-side comparison.
- On each status page, use
web_snapshot or web_evaluate to read the main
article text.
- Summarize only content actually read. If X shows a login wall, rate limit,
bot check, or empty timeline, say that explicitly with the observed URL and
title.
Do not answer "no posts found" after a single empty snapshot. Use the fallback
steps above first.
Failure Reporting
When blocked, include the failing stage and observed state:
- desktop health
- current URL/title if known
- whether snapshot was empty
- whether
document.querySelectorAll("article").length was zero
- whether X showed login/rate-limit/checkpoint text
This makes local debugging possible from the normal .jsonl transcript.