diff --git a/submissions/io.pilot.bowmark/submission.json b/submissions/io.pilot.bowmark/submission.json index 422d9d9..0217e08 100644 --- a/submissions/io.pilot.bowmark/submission.json +++ b/submissions/io.pilot.bowmark/submission.json @@ -2,7 +2,7 @@ "id": "io.pilot.bowmark", "version": "0.1.0", "namespace": "bowmark", - "description": "Pre-computed navigation recipes for public websites — parameterized URL shortcuts and short UI procedures verified by prior crawls. Call before any browser action (navigate, click, search, fill) to skip explore-and-discover and cut agent tokens.", + "description": "Navigation cheatsheets for public websites, so agents run cheaper, faster, and more accurately. Call bowmark.ask({site, task}) before any browser action to get a ready-to-run cheatsheet — a parameterized URL shortcut and/or a short UI procedure to execute open-loop — instead of exploring the DOM; then bowmark.report_outcome to keep the cheatsheets fresh.", "email": "alex@vulturelabs.io", "backend": { "base_url": "https://api.bowmark.ai", @@ -18,106 +18,49 @@ "methods": [ { "name": "bowmark.ask", - "description": "Look up a pre-computed navigation recipe for a (site, task) pair — call it BEFORE any browser action (navigate, click, search, fill, URL guess). Returns {status, id?, shortcut?, ui_procedure?, verify_more?, variants_assumed?, error?}. status=ok → execute open-loop: fill the `shortcut.template` {name} slots from your task and navigate if present, else run `ui_procedure.steps` in order; then call report_outcome with the returned `id`. Each step may carry `precondition`, `irreversible` (confirm with the user first), or `requires_user_input` (stop and ask the user — password/payment/personal data). If `verify_more:true`, do one cheap sanity check first. status=no_useful_data | site_not_supported | synth_invalid → miss (no id); browse manually. status=ambiguous_scope → retry with `scopeHint` = one of error.scope_options[].pattern. status=rate_limited → back off until error.retry_after (only NEW recipe synthesis is capped; cached recipes still answer). 503 embedder_unavailable/synth_unavailable → retry once after Retry-After. Skip for localhost / RFC1918 IPs and open-ended search with no destination. Put intent in `task`, never a URL.", + "description": "Give it a site and a plain-English task (e.g. 'find Apple's latest 10-K') and it returns a ready-to-run cheatsheet. Call it BEFORE any browser action on the open web, in place of exploring the page yourself. On status=ok you get an `id` plus a `shortcut` (a URL `template` with `{name}` slots you fill from your task, then navigate) and/or a `ui_procedure.steps` list to follow in order. Execute open-loop — don't snapshot the DOM to re-verify what the cheatsheet already documents — then call bowmark.report_outcome with the `id`. A step may be flagged `irreversible` (confirm with the user first) or `requires_user_input` (stop and ask the user — a password, payment, or personal detail). Non-ok statuses: `no_useful_data` | `site_not_supported` | `synth_invalid` → no cheatsheet, browse manually; `ambiguous_scope` → retry with `scopeHint`; `rate_limited` → back off until `error.retry_after` (only NEW cheatsheet synthesis is capped; known ones still answer); `503` → retry once after `Retry-After`. Skip for localhost / RFC1918 IPs and open-ended search with no destination. Put intent in `task`, never a URL.", "latency": "med", "http": { "verb": "POST", "path": "/v1/ask" }, "params": [ - { - "name": "site", - "type": "string", - "required": true, - "description": "Registrable domain, optionally followed by a product-surface path — 'google.com', 'docs.stripe.com', 'google.com/maps'. No scheme/port. A path is treated as an implicit scopeHint when it matches a known surface, letting you skip the ambiguous_scope round-trip.", - "in": "body" - }, - { - "name": "task", - "type": "string", - "required": true, - "description": "Plain-English intent, e.g. 'find Apple's latest 10-K'. Intent, NOT a URL or destination.", - "in": "body" - }, - { - "name": "variants", - "type": "string", - "required": false, - "description": "Optional behavior-facets object: {auth_state:'logged_out'|'logged_in', role:'owner'|'admin'|'member'|…, locale:'en-US', region:'EU', currency:'USD'}. Set auth_state:'logged_in' (+ role when privilege matters) to request the signed-in surface. Affects the cache key — omit when uncertain (you get the logged-out view). Echoed back on variants_assumed.", - "in": "body" - }, - { - "name": "scopeHint", - "type": "string", - "required": false, - "description": "Optional; only after a prior ambiguous_scope. Pass one of error.scope_options[].pattern verbatim (leading slash, no trailing).", - "in": "body" - } + {"name": "site", "type": "string", "required": true, "description": "Registrable domain, optionally followed by a product-surface path — 'google.com', 'docs.stripe.com', 'google.com/maps'. No scheme/port. A path is treated as an implicit scopeHint when it matches a known surface, letting you skip the ambiguous_scope round-trip.", "in": "body"}, + {"name": "task", "type": "string", "required": true, "description": "Plain-English intent, e.g. 'find Apple's latest 10-K'. Intent, NOT a URL or destination.", "in": "body"}, + {"name": "variants", "type": "string", "required": false, "description": "Optional behavior-facets object: {auth_state:'logged_out'|'logged_in', role:'owner'|'admin'|'member'|…, locale:'en-US', region:'EU', currency:'USD'}. Set auth_state:'logged_in' (+ role when privilege matters) to request the signed-in surface. Affects the cache key — omit when uncertain (you get the logged-out view). Echoed back on variants_assumed.", "in": "body"}, + {"name": "scopeHint", "type": "string", "required": false, "description": "Optional; only after a prior ambiguous_scope. Pass one of error.scope_options[].pattern verbatim (leading slash, no trailing).", "in": "body"} ] }, { "name": "bowmark.report_outcome", - "description": "Report how a recipe executed, once after running one from bowmark.ask. Honest reports trigger re-crawls that keep recipes healthy; skipping them silently degrades recipes for every future agent. Report the RECIPE's behavior, not the task result. success=true ONLY if every step ran as written (no retries, no JS-eval fallbacks, no extra clicks) — even if the answer was wrong. success=false on ANY deviation — even if you got the right answer another way. Don't call it for a miss envelope (no id) or if you never executed a step. Returns 201 with {id}.", + "description": "After running a cheatsheet from bowmark.ask, report whether every step ran exactly as written. Honest results keep the cheatsheets fresh: a failure triggers a re-crawl that repairs the path for the next agent. success=true ONLY if every step ran clean — no retries, no raw-JS fallback, no extra clicks — even if the answer turned out wrong. success=false on ANY deviation, even if you still got the answer another way. Don't call it for a miss (an ask with no `id`) or if you never executed a step. Returns 201 with {id}.", "latency": "fast", "http": { "verb": "POST", "path": "/v1/outcomes" }, "params": [ - { - "name": "envelope_id", - "type": "string", - "required": true, - "description": "The `id` from a status:ok ask envelope (uuid). Miss envelopes have no id — don't report those.", - "in": "body" - }, - { - "name": "success", - "type": "bool", - "required": true, - "description": "True ONLY if the recipe ran clean — every step as written, no retries, no JS-eval fallbacks, no extra clicks. False on ANY deviation, even if the user got the right answer another way.", - "in": "body" - }, - { - "name": "evidence", - "type": "string", - "required": true, - "description": "REQUIRED object describing how the RECIPE behaved (not the task outcome): {what_happened: string (required), error?: string, screenshot_id?: string}. Name which steps ran clean vs needed retries/substitutions/JS-eval/extra clicks — the re-crawl reads this to decide what to fix.", - "in": "body" - } + {"name": "envelope_id", "type": "string", "required": true, "description": "The `id` from a status:ok bowmark.ask response (uuid). A miss has no id — don't report those.", "in": "body"}, + {"name": "success", "type": "bool", "required": true, "description": "True ONLY if the cheatsheet ran clean — every step as written, no retries, no raw-JS fallback, no extra clicks. False on ANY deviation, even if you got the right answer another way.", "in": "body"}, + {"name": "evidence", "type": "string", "required": false, "description": "Optional object describing how the CHEATSHEET behaved (not the task result): {what_happened: string, error?: string, screenshot_id?: string}. Naming which steps were clean vs needed substitutions makes the re-crawl sharper.", "in": "body"} ] } ], "listing": { "display_name": "Bowmark", - "tagline": "Navigation cheatsheets for every website — recipes that skip explore-and-discover", - "app_description": "Bowmark gives a browsing agent **pre-computed navigation recipes** for public websites — a parameterized URL `shortcut` or a short `ui_procedure` of UI steps, each verified by prior crawls. Instead of exploring and discovering a site's structure on every task (snapshotting the DOM, guessing selectors, burning tokens), the agent calls `ask({ site, task })` once and executes the returned recipe open-loop. On known sites that means roughly **5x fewer tokens** and far less latency.\n\nManaged-key app: Pilot holds one shared Bowmark account behind the broker and meters each caller, so you install it **keyless** and never handle an API key. It's plain request/response REST — no websockets, no server-side browser, no async jobs. Your agent runs the recipe in its own browser; Bowmark only supplies the recipe.\n\n## Methods\n\n- **bowmark.ask** `{ site, task, variants?, scopeHint? }` — look up a recipe. On `status: ok` you get an `id` plus a `shortcut` (a URL `template` with `{name}` slots + `parameters`) and/or a `ui_procedure.steps` list (`action`, `locator`, `value`, and flags like `irreversible` / `requires_user_input`). Fill the slots from your task, execute open-loop, and don't snapshot the DOM to re-verify what the recipe documents.\n- **bowmark.report_outcome** `{ envelope_id, success, evidence }` — after running a recipe, report whether it executed cleanly. This feeds the re-crawl loop that keeps recipes healthy, so it matters: report `success:false` on any deviation (a retry, a JS-eval fallback, an extra click) even if you still got the answer.\n\n## Syntax & edge cases\n\n- `site` is a registrable domain, optionally with a product surface: `google.com`, `docs.stripe.com`, `google.com/maps` — a matching path acts as an implicit scope hint.\n- `task` is plain-English intent, never a URL.\n- Request the signed-in surface with `variants: { auth_state: \"logged_in\", role: \"owner\" }` (also `locale` / `region` / `currency`). The assumed facets come back on `variants_assumed`.\n- Statuses that aren't `ok`: `no_useful_data` / `site_not_supported` / `synth_invalid` → browse manually; `ambiguous_scope` → retry with `scopeHint`; `rate_limited` → back off until `error.retry_after` (only NEW recipe synthesis is capped — cached recipes still answer). On a `503` (`embedder_unavailable` / `synth_unavailable`), retry once after `Retry-After`.\n- Skip Bowmark for localhost, RFC1918 IPs, and open-ended search with no destination.", + "tagline": "Navigation cheatsheets for public websites, so agents run cheaper, faster, and more accurately.", + "app_description": "Bowmark gives agents a **pre-computed cheatsheet** for the task at hand. A cheatsheet is a compact, ready-to-run answer for one task on one site: a parameterized URL `shortcut` and/or a short `ui_procedure` of UI steps. Instead of burning tokens re-reading a site's DOM and guessing its way through the page, your agent calls `ask({ site, task })` and gets the exact path back. It spends less, finishes sooner, and lands on the right action the first time.\n\nManaged-key app: Pilot holds one shared Bowmark account behind the broker and meters each caller, so you install it **keyless** and never handle an API key. It's plain request/response REST — no websockets, no server-side browser, no async jobs. Your agent runs the cheatsheet in its own browser; Bowmark only supplies the path.\n\n## Methods\n\n- **bowmark.ask** `{ site, task }` — give it a site and a plain-English task and it returns the cheatsheet: a URL `shortcut` (a `template` with `{name}` slots you fill and navigate) and/or a `ui_procedure.steps` list to follow in order, plus an `id`. Call it before any browser action, in place of exploring the page yourself; execute the cheatsheet open-loop rather than re-reading the DOM.\n- **bowmark.report_outcome** `{ envelope_id, success }` — after running a cheatsheet, report whether every step ran exactly as written. Honest results keep the cheatsheets fresh: a failure triggers a re-crawl that repairs the path for the next agent, so report `success: false` on any deviation (a retry, a raw-JS fallback, an extra click) even if you still got the answer.\n\n## Syntax & edge cases\n\n- `site` is a registrable domain, optionally with a product surface: `google.com`, `docs.stripe.com`, `google.com/maps` — a matching path acts as an implicit scope hint.\n- `task` is plain-English **intent**, never a URL.\n- Request the signed-in surface with `variants: { auth_state: \"logged_in\", role: \"owner\" }` (also `locale` / `region` / `currency`); the assumed facets come back on `variants_assumed`.\n- A `ui_procedure` step may be flagged `irreversible` (confirm with the user first) or `requires_user_input` (stop and ask — a password, payment, or personal detail).\n- Non-`ok` statuses: `no_useful_data` / `site_not_supported` / `synth_invalid` → browse manually; `ambiguous_scope` → retry with `scopeHint` = one of `error.scope_options[].pattern`; `rate_limited` → back off until `error.retry_after` (only NEW cheatsheet synthesis is capped — known ones still answer). On a `503`, retry once after `Retry-After`.\n- Skip Bowmark for localhost, RFC1918 IPs, and open-ended search with no destination.", "license": "Proprietary", "homepage": "https://bowmark.ai", "source_url": "https://github.com/bowmark-ai/plugin", - "categories": [ - "web", - "browser", - "agents", - "automation" - ], - "keywords": [ - "browser", - "navigation", - "recipes", - "cheatsheets", - "websites", - "playwright", - "puppeteer", - "computer-use", - "scraping" - ] + "categories": ["web", "browser", "agents", "automation"], + "keywords": ["browser", "navigation", "cheatsheets", "recipes", "websites", "playwright", "puppeteer", "computer-use", "scraping"] }, "vendor": { "name": "Bowmark AI", "url": "https://bowmark.ai", "contact": "support@bowmark.ai", - "agent_usage": "Autonomous browsing agents call bowmark.ask before navigating a public site to fetch a known-good URL shortcut or UI procedure, skipping explore-and-discover and reducing token use ~5x. The recipe is executed by the agent's own browser; Bowmark only supplies the recipe.", - "capabilities": "ask (navigation-recipe lookup for a site+task, optional logged-in variant + scope hint)." + "agent_usage": "Autonomous browsing agents call bowmark.ask before navigating a public site to fetch a ready-to-run cheatsheet — a URL shortcut or short UI procedure — instead of exploring the DOM, then run it open-loop and call bowmark.report_outcome so failures trigger a re-crawl. The agent's own browser executes the path; Bowmark only supplies it.", + "capabilities": "ask (fetch a navigation cheatsheet for a site+task, optional logged-in variant + scope hint); report_outcome (report whether the cheatsheet ran clean, to keep it fresh)." } }