Conversation
Moved the HTTP GET and response rendering logic from the `WebFetchTool` implementation into a new private method `fetch_validated` on `WebFetchTool`. This separates the SSRF guard and gate disclosure from the actual fetch, making the code easier to test and reuse. Also changed the `url` parameter from `&str` to `&str` to avoid an unnecessary borrow. Auto-committed-on: dragonfly Co-authored-by: Medulla <medulla@tinyhumans.ai>
…cesses HTTP error status codes (4xx and 5xx) are now returned as tool errors rather than successful page reports, so that rate-limited, blocked, or unavailable pages are properly surfaced to the agent for retry or alternative sourcing. The error message includes the status code, host, a short body excerpt, and a Retry-After hint when present, while 3xx redirects continue to be reported as successful but unfollowed responses. Auto-committed-on: dragonfly Co-authored-by: Medulla <medulla@tinyhumans.ai>
Tiny Sweeper reviewTiny Sweeper reviewed this change across 6 lane(s) and found 0 active actionable finding(s). Detailed lane evidence and any incomplete work are listed below. State: Incomplete Review snapshot
Completeness: Incomplete What changedThe review could not produce a supported behavioral summary; inspect the cited changed surface and lane details below. FeaturesNone identified with supported citations. TestsNo supported feature-to-test mapping was produced. Test execution is not inferred. FindingsNo active actionable findings. Could not review: crates/tinytools-std/src/network/web_fetch.rs, crates/tinytools-std/src/network/web_fetch_tests.rs Before merge
How this fits togetherflowchart LR
n0["WebFetchTool<br/>changed"]:::changed
n1["execute_blocks_when_rate_limited<br/>changed"]:::changed
n2["fetch"]:::impacted
n3["test_security"]:::impacted
n4["Tool"]:::impacted
n5["NetGate"]:::impacted
n6["..._the_schema_into_extra_optional_arguments"]:::impacted
n7["HtmlExtractor"]:::impacted
n0 -->|implements| n4
n0 -->|uses| n5
n0 -->|uses| n7
n1 -->|calls| n2
n1 -->|tests| n2
n2 -->|uses| n0
n6 -->|calls| n2
n6 -->|tests| n2
n6 -->|calls| n3
n6 -->|tests| n3
classDef changed fill:#0d4429,stroke:#238636,color:#e6edf3
classDef impacted fill:#161b22,stroke:#6e7681,color:#c9d1d9
classDef flagged fill:#5a1e02,stroke:#d93f0b,color:#ffffff
classDef blocking fill:#67060c,stroke:#f85149,color:#ffffff
Agent review detailscritique
security
tests
commits
description
e2e
Evidence and run details
|
|
Warning Review limit reached
This review includes 2 billable files and costs up to $0.50. Or wait 46 minutes for your next included review. View limit detailsLimit details: You’ve used the included review currently available. Review configuration: ⚙️ Run configuration
📒 Files selected for processing (2)
Comment |
There was a problem hiding this comment.
tinysweeper found nothing blocking, but could not review everything, so this is not an approval: crates/tinytools-std/src/network/web_fetch.rs, crates/tinytools-std/src/network/web_fetch_tests.rs.
$0.0013 · 44,944 in / 7,290 out · 5,289 cached (12%) · deepseek/deepseek-v4-flash
tests: $0.0008 · 25,783 in / 738 out · 0 cached (0%) · deepseek/deepseek-v4-flash
description: $0.0002 · 7,404 in / 61 out · 0 cached (0%) · deepseek/deepseek-v4-flash
Summary
web_fetchreturned every HTTP response as a successfulToolResult(status=403 url=...), including 4xx/5xx. A host that budgets, retries or halts onis_error(OpenHuman's research budget, openhuman#6959 follow-up) therefore counted blocked or rate-limited fetches as completed research.Redirects are not followed (
Policy::none()), so the "final response" is the first response; 3xx handling is unchanged and still a successful "redirect not followed" report.Changes
ToolResult::errorwith model-useful text:HTTP 403 Forbidden from <host>; the site refused the request. Try another source.HTTP 429 Too Many Requests from <host>; the site is rate limiting requests. Retry-After: <v>. Try another source, or retry later.(Retry-Afteronly when the header is present)Response excerpt:line. HTML goes through the hostHtmlExtractorunlessraw: true.executeinto a privatefetch_validatedso tests can drive a loopback server (the SSRF guard refuses loopback inexecute; same approach ashttp_request_tests).[tool.web_fetch] http error status=... host=... retry_after_present=...(no body, no URL path or query).Tests (TDD: red first)
New in
web_fetch_tests.rs: 200 stays OK withstatus=header; 403, 404, 5xx are errors; 429 is an error with rate-limit wording andRetry-After(and without it when the header is absent); excerpt is bounded and stripped of markup; 301 stays successful.cargo test --workspace: all pass (tinytools-std 500 passed)cargo clippy --workspace --all-targets -- -D warningsandcargo fmt --all --check: cleanCompatibility note
Callers that matched on the
status=4xx/5xxsuccess preamble will now see an error result instead. Hosts that classify failures from the error text (e.g. keyword matching on "403"/"Forbidden") will now see these where they previously did not.