Skip to content

fix(tool): route website tasks to opencli adapters before the browser - #1280

Merged
Astro-Han merged 4 commits into
devfrom
claude/opencli-routing
Jun 13, 2026
Merged

fix(tool): route website tasks to opencli adapters before the browser#1280
Astro-Han merged 4 commits into
devfrom
claude/opencli-routing

Conversation

@Astro-Han

@Astro-Han Astro-Han commented Jun 13, 2026

Copy link
Copy Markdown
Owner

Summary

Add resident-prompt routing so the agent reaches for the bundled OpenCLI site adapters before manually driving the embedded browser. Adapter-first for specific-site tasks, with an explicit fallback to the browser group.

  • pawwork.txt "# Browsing and operating websites": adapter-first routing keyed on action intents (check account, search, book, order, post, pull structured data), not site names (the manifest is dynamic — 162 sites / 1050 commands). Explicit fallback to the browser group on no match or adapter error, capped at one retry. A permission-denial stop so a declined OpenCLI/browser permission is never worked around with another tool. webfetch and the curl/wget guard kept.
  • shell.txt redirect: check opencli_search for a bundled adapter first, then fall back to the browser tools.
  • Contract tests pin the new ordering, fallback, one-retry cap, and permission-denial stop across both resident surfaces; system-prompt anchor added.

Copy + contract tests only. No execute() / runtime change.

Why

The OpenCLI adapters shipped in #(521b01e) as deferred tools — exposed only as a one-line opencli card inside tool_info — so the agent almost never discovered them. Worse, the resident prompt actively routed every website task to the competing browser group (the browsing section and the shell redirect both pointed only at the browser tools). So "check my 12306 account" → read browsing section → activate browser → hand-drive the page → never find the 12306/me adapter.

Same failure class as the earlier automate misroute (ae981f021e): a capable tool losing to a more familiar default because nothing in the resident prompt routes to it. That fix added a pawwork.txt routing section + shell.txt redirect + contract tests; this mirrors it for opencli.

This direction and final shape were pressure-tested by an independent fresh-eye review and a Codex consult — both converged on: prompt-only is the right altitude (don't un-defer the tools), key on action intents not site names, two tiers not three, and pin the rule with contract tests.

Related Issue

None.

Human Review Status

Pending

Review Focus

  • The new copy in pawwork.txt — is the adapter→browser fallback order and the permission-denial stop unambiguous to a weak model?
  • That the two failure branches stay distinct: adapter error → browser; user permission denial → stop (do not reroute).

Risk Notes

Resident system-prompt behavior change: the agent will now spend one opencli_search turn on specific-site tasks before falling back to the browser. Mitigated by keying on action intents so pure one-page reads still go to webfetch. No runtime, permission, or packaging surface touched. UI checklist item left unticked: no visible UI or copy-in-app changed (this is the agent system prompt, not user-facing copy).

How To Verify

bun test test/tool/registry.test.ts test/session/system.test.ts test/tool/shell-prompt.test.ts test/tool/opencli-tools.test.ts — 73 pass, 0 fail (280 expects)
bun run typecheck (packages/opencode) — clean (tsgo --noEmit)

Screenshots or Recordings

N/A — no visible UI change.

Checklist

  • Type labelbug.
  • Routing labelsharness (prompts + tool descriptions).
  • Priority labelP2.
  • Human Review Status above is set to Pending.
  • I linked the related issue, or stated in Summary why there is no issue.
  • I described the review focus and any meaningful risks.
  • I replaced the example block in How To Verify with the real verification steps and the key result for each.
  • I did not introduce unrelated refactors, dependencies, generated files, or file changes beyond the stated scope.
  • (conditional) I manually checked visible UI or copy changes when needed, with screenshots or recordings. Leave unticked only if no visible UI or copy changed.
  • (conditional) I considered macOS and Windows impact for platform, packaging, updater, signing, paths, shell, or permissions changes. Leave unticked only if no platform/packaging surface was touched.
  • (conditional) I called out docs, release notes, dependencies, permissions, credentials, deletion behavior, generated content, or local file changes when relevant.
  • I reviewed the final diff for unrelated changes and suspicious dependency changes.
  • I am targeting dev, and my PR title and commit messages use Conventional Commits in English.

Follow-up (out of scope)

Navigate-time discovery — when the browser navigates to a domain that has a bundled adapter, surface the matching adapter from the browser tool result so the model is pulled back even if it ignored the resident routing. Prompt routing is best-effort (the model can ignore it); a navigate-time hook is the structural backstop. Deferred here because it touches the tool execution path and needs its own tests.

Summary by CodeRabbit

  • Documentation
    • Website interaction guidance now prioritizes site-specific OpenCLI adapters first, then falls back to browser tools; includes explicit ordering and exposure guidance, a one-retry cap, a stop rule when permissions are denied, and a one-shot read-only webfetch recommendation.
  • Tests
    • Expanded tests to validate adapter-first routing, tool-exposure ordering, the one-retry cap, and the permission stop rule.

The bundled OpenCLI site adapters (162 sites, 1050 commands) are deferred
tools, exposed only as a one-line `opencli` card inside tool_info, so the agent
almost never discovered them. Worse, the resident prompt actively routed every
website task to the competing `browser` group: the "# Browsing and operating
websites" section and the shell.txt redirect both pointed only at the browser
tools. Same failure class as the earlier automate misroute (ae981f0) — a
capable tool losing to a more familiar default because nothing in the resident
prompt routes to it.

Changes (copy + contract tests only; no execute() change):
- pawwork.txt browsing section: adapter-first routing keyed on action intents
  (check account, search, book, order, post, pull structured data), not site
  names (the manifest is dynamic). Explicit fallback to the browser group on no
  match or adapter error, capped at one retry. A permission-denial stop so a
  declined OpenCLI/browser permission is never worked around with another tool.
  webfetch and the curl/wget guard kept.
- shell.txt redirect: check opencli_search for a bundled adapter first, then
  fall back to the browser tools.
- Contract tests pin the new ordering, fallback, one-retry cap, and
  permission-denial stop across both resident surfaces (registry.test.ts), plus
  a system-prompt anchor (system.test.ts). The old browser-only routing
  assertion is replaced.

Verification:
- bun test test/tool/registry.test.ts test/session/system.test.ts
  test/tool/shell-prompt.test.ts test/tool/opencli-tools.test.ts — 73 pass.
- bun run typecheck (packages/opencode) — clean.

Follow-up (out of scope): navigate-time discovery — surface a matching adapter
from the browser tool result when navigating to a domain that has one, so the
model is pulled back even if it ignored the resident routing.
@Astro-Han Astro-Han added bug Something isn't working P2 Medium priority harness Model harness, prompts, tool descriptions, and session mechanics labels Jun 13, 2026
@coderabbitai

coderabbitai Bot commented Jun 13, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

No actionable comments were generated in the recent review. 🎉

ℹ️ Recent review info
⚙️ Run configuration

Configuration used: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro Plus

Run ID: 7151a364-e492-4d0b-b8c5-2bb62153e4fe

📥 Commits

Reviewing files that changed from the base of the PR and between 0f267a2 and 339ccaa.

📒 Files selected for processing (4)
  • packages/opencode/src/session/prompt/pawwork.txt
  • packages/opencode/src/tool/shell.txt
  • packages/opencode/src/tool/tool-info.ts
  • packages/opencode/test/tool/registry.test.ts
✅ Files skipped from review due to trivial changes (1)
  • packages/opencode/src/tool/shell.txt
🚧 Files skipped from review as they are similar to previous changes (2)
  • packages/opencode/src/session/prompt/pawwork.txt
  • packages/opencode/test/tool/registry.test.ts

📝 Walkthrough

Walkthrough

This PR shifts website-browsing routing from browser-first to adapter-first: the system now searches for site-specific OpenCLI adapters before falling back to browser tools, includes a stop rule preventing tool-switching after permission denial, and updates corresponding test assertions.

Changes

Adapter-First Browsing Routing

Layer / File(s) Summary
Browsing routing instructions
packages/opencode/src/session/prompt/pawwork.txt, packages/opencode/src/tool/shell.txt, packages/opencode/src/tool/tool-info.ts
System prompt and tool guidance now direct OpenCLI adapter search first via tool_info + opencli_search/opencli_run, falling back to browser tools when no adapter applies or when adapters are denied. User permission denials stop further tool-switching for that action. webfetch is tightened to one-shot read-only. Shell guidance updated to prefer adapter search before browser tools.
Browsing routing contract tests
packages/opencode/test/session/system.test.ts, packages/opencode/test/tool/registry.test.ts
System prompt test asserts opencli tool group via tool_info. Registry tests verify shell layer checks opencli_search first, system prompt validates explicit opencli/browser tool-group exposure, inclusion of opencli_search/opencli_run, one-retry cap per adapter, ordering (opencli before browser fallback), and permission-denial stop rule.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

  • Astro-Han/pawwork#1272: Implements the OpenCLI adapter tooling and routing surface that this PR's prompt instructions and tests now expect for website browsing.
  • Astro-Han/pawwork#358: Related prior updates to prompt permission control-flow and stop-rule semantics used by the updated tests.
  • Astro-Han/pawwork#142: Introduced the unified pawwork.txt prompt file that this PR further refines for adapter-first routing.

Poem

🐰 Hops to adapters, sniffing each site,
OpenCLI first, then browser if light.
If permissions close, we politely cease,
One-shot fetches, no simulated grease.
Carrots and code—a tidy browsing feast.

🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Title check ✅ Passed The title clearly and concisely describes the main change: prioritizing OpenCLI adapters before the browser for website tasks.
Description check ✅ Passed The description comprehensively covers all required template sections: summary, rationale, issue linkage, review focus, risks, verification steps, and completed checklist.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch claude/opencli-routing

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint install failed. For unrecoverable errors, disable the tool in CodeRabbit configuration.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

@github-actions github-actions Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Suggested priority: P2 (includes non-doc, non-test paths outside the low-risk bucket).

P1/P0 are reserved for maintainer confirmation. Please relabel manually if this is a release blocker, security issue, data-loss risk, or updater/runtime failure.

@gemini-code-assist gemini-code-assist Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request updates the web browsing and operation guidelines to prioritize purpose-built site adapters via the opencli tool group (opencli_search and opencli_run) before falling back to the embedded browser tool group. It also introduces rules for handling permission denials and limiting adapter retries, and updates the corresponding shell usage notes and tests. Feedback was provided to clarify an ambiguous reference to "these tools" in the prompt guidelines to prevent models from mistakenly using forbidden tools like curl or wget.

Important

The consumer version of Gemini Code Assist on GitHub is being sunset. Starting June 18, 2026, new organization installations will be blocked, and all code review activity will officially cease on July 17, 2026.
For more details on the timeline and next steps, please review the Help Documentation.

Comment thread packages/opencode/src/session/prompt/pawwork.txt Outdated
Codex review (P1): the `browser` group card in tool-info.ts is a resident
surface shown every turn in tool_info's listing, and it still told the model to
"use for any task that needs to browse, read, or operate a website" — directly
contradicting the new adapter-first routing and re-creating the same misroute
the PR fixes. Reword the browser card to fallback semantics (general browsing,
visual checks, sites without an adapter; check the opencli group first) and the
opencli card to prefer adapters over the browser when one matches.

Codex review (P2): harden the browsing routing contract test — assert the
shell redirect can't drift back to browser-first, the adapter-first ordering
(opencli_search before the browser fallback), and that the browser group card
no longer carries the conflicting "any website task" steer.

Verification:
- bun test test/tool/registry.test.ts test/session/system.test.ts
  test/tool/tool-info.test.ts test/tool/opencli-tools.test.ts
  test/tool/shell-prompt.test.ts — 104 pass.
- bun run typecheck (packages/opencode) — clean.
@Astro-Han

Copy link
Copy Markdown
Owner Author

Codex review round (xhigh, web search on)

Verdict: prompt-only is the right altitude — no need for the heavier navigate-time interception now. But codex caught a missed resident surface and a test gap. Both fixed in 4ceecc3e67.

  • [P1] browser tool_info group card still routed every website task to the browser. GROUP_CARDS.browser in tool-info.ts is shown every turn in tool_info's listing and said "use for any task that needs to browse, read, or operate a website" — a third resident surface contradicting the adapter-first routing, recreating the exact misroute this PR fixes. I only changed pawwork.txt and shell.txt in the first commit. Fixed: browser card → fallback semantics (general browsing, visual checks, sites without an adapter; check the opencli group first); opencli card → prefer adapters over the browser when one matches.
  • [P2] contract test was positive-substring-only. It couldn't catch a re-added browser-first sentence or the conflicting card. Hardened: assert the shell redirect can't drift back to browser-first, the adapter-first ordering (opencli_search before the browser fallback), and that the browser card no longer carries the "any website task" steer.

Re-verified after the fix: bun test registry + system + tool-info + opencli-tools + shell-prompt — 104 pass; bun run typecheck clean.

Confirmed out-of-scope (codex agreed): navigate-time discovery as the structural backstop — see the Follow-up section in the PR body.

Three P3 copy-ambiguity fixes from code review (copy + contract tests only):

- pawwork.txt: "without trying these tools first" had an unclear referent (a
  weak model could read it as curl/wget or webfetch) — name the tools:
  "trying the `opencli` or `browser` tool groups first".
- pawwork.txt: drop the ambiguous "blocked" from the adapter-failure fallback
  (it could be conflated with a user permission denial) and make the
  permission-denial stop an explicit contrast: "is not an adapter failure to
  route around".
- shell.txt: the redirect triggered on "a specific site" (broader than the
  system prompt's action-intent routing); re-key it on acting on a site
  (sign in, search, book, post, pull data) and carve out one-shot reads to
  webfetch so it stays in step.

Contract test updated to pin the new action-intent trigger, the
permission-vs-adapter-failure distinction, and the named "try first" pointer,
with regression guards against the old visit-based and ambiguous phrasings.

Verification:
- bun test test/tool/registry.test.ts test/session/system.test.ts
  test/tool/tool-info.test.ts test/tool/opencli-tools.test.ts
  test/tool/shell-prompt.test.ts — 104 pass.
- bun run typecheck (packages/opencode) — clean.
@Astro-Han

Copy link
Copy Markdown
Owner Author

Code review round 2 — P3 copy fixes (339ccaa5eb)

All three P3 copy-ambiguity findings verified as real (they target exactly this PR's goal: weak-model reading reliability) and fixed. Copy + contract tests only.

  • Ambiguous these tools → named the tools: "never declare a web task impossible without trying the opencli or browser tool groups first".
  • blocked conflatable with permission denial → dropped blocked from the adapter-failure fallback ("unavailable, errors, or returns unusable output") and made the permission stop an explicit contrast: "A user denying an OpenCLI or browser permission is not an adapter failure to route around: stop and tell them…".
  • shell.txt trigger broader than the system prompt → re-keyed the redirect on acting on a site ("To act on a specific site (sign in, search, book, post, pull data)…") with a one-shot-read → webfetch carve-out, matching the prompt's action-intent routing.

Contract test now pins the action-intent trigger, the permission-vs-adapter-failure distinction, and the named "try first" pointer, with regression guards against the old visit-based and ambiguous phrasings.

Re-verified: bun test registry + system + tool-info + opencli-tools + shell-prompt — 104 pass (375 expects); bun run typecheck clean.

On the dev-dep-audit failure

Not introduced by this PR and not a merge gate. The advisory is a pre-existing esbuild issue (GHSA-gv7w-rqvm-qjhr) in transitive dev deps (drizzle-kit / electron-vite / vite); bun audit --audit-level=high reports the same 1 high against the unchanged lockfile, and dev has no required-status-check gate configured. Resolving it is a separate dependency bump, out of scope here.

@Astro-Han
Astro-Han merged commit 5f2f656 into dev Jun 13, 2026
33 checks passed
@Astro-Han
Astro-Han deleted the claude/opencli-routing branch June 13, 2026 15:48
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

bug Something isn't working harness Model harness, prompts, tool descriptions, and session mechanics P2 Medium priority

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant