Repository navigation
feat(web): self-inject web::fetch guidance via pre-generate hook - #385
Conversation
The web worker now contributes its web::fetch usage guidance to the agent system prompt through a harness::hook::pre-generate hook (web::inject-guidance), mirroring workflow::inject-guidance. It is presence-gated: injected only while the web worker is connected, and dropped when it disconnects. - web: add web::inject-guidance pre_generate hook with a single canonical WEB_GUIDANCE string, plus the presence-gated bind machinery ported from the workflow worker (bind only once harness::hook::pre-generate exists); bump 1.2.0 - harness: remove all hardcoded web::* citations from the prompt variants — the HTTP-mandate block is deleted, and the SDK-reference instruction is reworded to drop the web::fetch naming - harness: drop the workflow dependency from iii.worker.yaml (workflow is optional and self-attaches; web stays a hard dep so its injected guidance is present) Claude-Session: https://claude.ai/code/session_015P3MFVnbz8DVFSjtfpUosR
Both surfaced while investigating a web::fetch 404 on https://iii.dev/docs/sdk-reference/browser-sdk.md: 1. The SDK reference docs moved. The language SDK pages are now at iii.dev/docs/api-reference/sdk-<lang> (node/python/rust/browser); the old sdk-reference/<lang>-sdk paths 404 with or without .md — that was the reported error, not the .md suffix. Update the URLs in all prompt variants and the sdk_doc_gate test. The engine-protocol doc (sdk-reference/engine-sdk) is unchanged. Verified the new .md URLs return 200 text/markdown. 2. The web::fetch mandate was removed from the prompts (it is now injected by web::inject-guidance) but its test (web_fetch_localhost_mandate) still asserted the old prompt text and was failing. Relocate the assertion to the web worker (web_fetch_mandate_present) where the guidance now lives. Claude-Session: https://claude.ai/code/session_015P3MFVnbz8DVFSjtfpUosR
CI runs `cargo fmt --all -- --check`; wrap the multi-arg assertion to satisfy it. Claude-Session: https://claude.ai/code/session_015P3MFVnbz8DVFSjtfpUosR
|
The latest updates on your projects. Learn more about Vercel for GitHub.
|
skill-check — worker0 verified, 30 skipped (no docs/).
Four for four. Nicely done. |
|
Warning Review limit reached
Next review available in: 45 minutes Enable usage-based reviews in Billing to review now. Otherwise, wait until the next included review is available. How can I continue?After more reviews become available, a review can be triggered using the To avoid repeated limits, reduce automatic review volume by pausing incremental auto-reviews earlier, using label-based review opt-in, excluding WIP or generated PR titles, or requesting reviews manually when the PR is ready. If your team needs uninterrupted high-volume reviews, an organization admin can enable usage-based reviews. How do review limits work?CodeRabbit enforces per-developer PR review limits for each organization. Most developers receive the normal plan review availability. For paid Pro and Pro+ PR reviews, CodeRabbit uses adaptive limits for sustained high-volume activity. When a developer's recent PR review activity reaches the 95th percentile or higher among CodeRabbit users, additional reviews become available more gradually as earlier reviews age out of the rolling window. Please refer docs for additional details. Review details⚙️ Run configurationConfiguration used: Organization UI Review profile: CHILL Plan: Pro Run ID: 📒 Files selected for processing (1)
📝 WalkthroughWalkthroughPrompt files across the harness update SDK documentation URLs to new api-reference paths and remove hardcoded web::fetch HTTP-request instructions. A new web::inject-guidance pre-generate hook is added to the web worker, injecting fetch guidance into the system prompt, with new harness hook binding logic, registration wiring, and a version bump. ChangesPrompt SDK doc URL and web::fetch guidance removal
Web worker inject-guidance hook and harness binding
Estimated code review effort: 3 (Moderate) | ~25 minutes Sequence Diagram(s)sequenceDiagram
participant Main as web/main.rs
participant Config as configuration::setup_harness_hooks
participant Engine
participant Hook as inject_guidance::handle
Main->>Config: setup_harness_hooks(iii)
Config->>Engine: subscribe to engine::workers-available / functions-available
Config->>Engine: probe engine::triggers::list (warm-start)
Engine-->>Config: harness::hook::pre-generate present?
alt hook trigger ready
Config->>Engine: register_trigger web::on-config-change (fail_open)
else not ready
Engine-->>Config: engine::*-available event fires later
Config->>Engine: retry register_trigger
end
Engine->>Hook: PreGenerateEvent (system_prompt)
Hook->>Hook: enrich(base) appends WEB_GUIDANCE
Hook-->>Engine: mutations.system_prompt
Possibly related PRs
Suggested reviewers: Poem
🚥 Pre-merge checks | ✅ 5✅ Passed checks (5 passed)
✨ Finishing Touches🧪 Generate unit tests (beta)
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. Comment |
Version bumps are handled separately from feature PRs; revert web to 1.1.4. Claude-Session: https://claude.ai/code/session_015P3MFVnbz8DVFSjtfpUosR
There was a problem hiding this comment.
Actionable comments posted: 2
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.
Inline comments:
In `@web/src/configuration.rs`:
- Around line 96-127: The binding state in try_bind_harness_hooks is marked too
early, before the hook is actually observable in the engine. Move the bound=true
claim to after bind() succeeds and the hook is confirmed active, using the
existing try_bind_harness_hooks and bind flow so a dropped asynchronous
registration does not leave the AtomicBool stuck true. If the bind is accepted
but not visible, keep the retry path reachable by only setting bound once the
hook is truly in place.
In `@web/src/functions/inject_guidance.rs`:
- Around line 26-36: The hook event deserialization in
PreGenerateEvent/GenerateContext is too permissive because serde defaults turn a
missing or renamed generate.system_prompt into an empty string, which later
causes inject_guidance to overwrite the prompt with WEB_GUIDANCE alone. Remove
the defaulting behavior on the nested generate/system_prompt fields and update
inject_guidance to preserve the existing system prompt when the event payload is
missing or malformed, or fail the hook explicitly instead of replacing the
prompt.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Organization UI
Review profile: CHILL
Plan: Pro
Run ID: 67e134f3-06b0-4982-b64f-2b675bd24fa9
⛔ Files ignored due to path filters (1)
web/Cargo.lockis excluded by!**/*.lock
📒 Files selected for processing (12)
harness/iii.worker.yamlharness/prompts/anthropic.txtharness/prompts/cli.txtharness/prompts/default.txtharness/prompts/gpt.txtharness/prompts/kimi.txtharness/src/prompt/tests.rsweb/Cargo.tomlweb/src/configuration.rsweb/src/functions/inject_guidance.rsweb/src/functions/mod.rsweb/src/main.rs
web::inject-guidance defaulted a missing/renamed generate.system_prompt to "" and returned it as the mutation, replacing the whole agent system prompt with the guidance alone. Now emit no system_prompt mutation when the base is empty, so the harness preserves its assembled prompt (per HookRunner::run_pre_generate, it overwrites only when the mutation carries system_prompt). Addresses CodeRabbit review on #385. Claude-Session: https://claude.ai/code/session_015P3MFVnbz8DVFSjtfpUosR
Resolves against the prompt-evaluation work that landed in #595, which edited the same sections this branch moves out of the identity prompt. - `default.txt` keeps this branch's trimmed identity. The `curl` prohibition is dropped with it: the web worker has injected that rule through its own pre-generate hook since #385, so the line was a stale duplicate that also fired on rigs without the web worker installed. - #595's dispatch doctrine (audit every resolved resource selector before dispatching; derive a per-run namespace suffix and confirm the namespace is absent) moves into `harness/skills/orchestration.md`, which now owns spawn and reaction mechanics. - #595 also corrected the reaction session semantics: an ordinary event reaction MUST omit `metadata.session_id`, and every event then creates a fresh distinct child under the resolved console root. The playbook still carried the older rule, that omitting it delivers back into the registering chat, so it was describing behaviour the runtime no longer has. Same for `once`, which is a top-level registration field and is standing by default on join predecessor edges. - The three tests #595 added assert that doctrine against the identity prompt. They now assert it against the orchestration playbook, which is where the text lives after this branch.
What
Make the
webworker own and inject its ownweb::fetchusage guidance into theagent system prompt, mirroring how
workflow::inject-guidancealready works. Theharness prompt stops hardcoding
web::*.Why
Today the harness hardcodes
web::fetchguidance across its prompt variants. Theworkflowworker already solved this the right way: aharness::hook::pre-generatehook appends its guidance only while the worker is connected — presence-gated,
single canonical copy, no drift across variants. This brings
webto parity.Changes
web — self-injecting guidance (
v1.2.0)web::inject-guidancepre_generate hook (web/src/functions/inject_guidance.rs)with a single canonical
WEB_GUIDANCEstring.configuration.rs(binds onlyonce
harness::hook::pre-generateexists;on_error: fail_openso a missing guidanceline never blocks a turn), wired from
main.rsviasetup_harness_hooks.webis connected, dropped when itdisconnects.
harness — stop citing
web::*web::fetchHTTP-mandate block from all prompt variants.web::fetchnaming (the injected guidance now covers how).workflowdependency fromiii.worker.yaml(workflow is optional andself-attaches via registry-change events;
webstays a hard dep so its injectedguidance is always present).
Follow-up fix — surfaced while investigating a live
web::fetch404iii.dev/docs/sdk-reference/<lang>-sdk(now 404, withor without
.md) →iii.dev/docs/api-reference/sdk-<lang>. Updated the URLs in allprompt variants and the
sdk_doc_gatetest.engine-sdkis unchanged.web::fetchmandate test from the harness (web_fetch_localhost_mandate,which asserted the now-removed prompt text) to the web worker
(
web_fetch_mandate_present), where the guidance now lives.Verification
web:cargo test→ 102 passing (incl.inject_guidanceenrich/empty + mandate tests).harness:cargo test --lib→ 98 passing; prompt suite 30/30 (previously 30/1 — therelocated test was red).
api-reference/sdk-<lang>.mdURLs return200 text/markdown; oldsdk-reference/<lang>-sdkpaths return404.Notes
webstays a harness dependency by design; onlyworkflowwas removed.the system prompt and drops when web disconnects) requires a running engine and was
not exercised in CI.
https://claude.ai/code/session_015P3MFVnbz8DVFSjtfpUosR
Summary by CodeRabbit
New Features
Bug Fixes