[M3a] Cloudflare Worker target: OpenRouter provider and an allowlisted http tool - #295
Merged
Merged
Conversation
…owlisted http tool Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
…available on Workers Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
Owner
Author
|
Merged origin/main again (d8539a7, fromAiSdk #287); CHANGELOG keeps both entries, llms regenerated. Re-ran the full verification on 333f3ae: tsc, lint, build, create-lousho-agent build, test:types, docs:verify-snippets, docs:llms:check all exit 0; test:coverage 228 files, 3260 passed / 2 skipped; fallow exit 0 (0 above threshold, dead exports 0.0%); Agent Forge typecheck, typecheck:server exit 0, test 112 passed, test:server 122 passed; pack-smoke all checks passed; |
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Closes #223
Round 2 ticket M3a. A spec built with
lousho build --target=cloudflare-workercan now use theopenrouterprovider and thehttptool.What changed
OpenRouter on Workers.
runtime.worker.tsregistersOpenRouterProvider. It imports the provider directly, not through the barrel. The key comes from theOPENROUTER_API_KEYbinding.WORKER_SUPPORTED_PROVIDERSis now['mock','openai','anthropic','openrouter']. The OpenRouter bundle passes thenode:leak check with no import fixes and no new shims; the bundle test proves it.ollamastays unsupported.src/tools/built-in/httpCore.ts(new, Node-free). This is the shared input schema and description, the request with its timeout and caller cancellation, the manual redirect loop (an injectedcheckHopruns on every redirect target), the response reading, andipFamily(), a regex replacement fornet.isIP. A test checks it gives the same answer asnode:neton 28 samples.src/security/privateAddress.ts(Node-only,net.BlockList). So the "pure parts" left to move were the request and redirect logic, notBLOCKED_RANGES.http.tskeeps its exports and behaviour. It does the IP-literal check itself, and its transport still does the pinned-DNS check.http.test.tspasses unchanged.src/tools/built-in/workerHttp.ts(new).createWorkerHttpTool({ allow, timeout?, maxRedirects? })has the same descriptor name (http_request) and the same input schema object ascreateHttpTool. It runs over the platformfetch(), which is injectable for tests. It has norequiresSandboxand novalidateSSL. On the first URL and on every redirect it refuses:http:andhttps:;2130706433and0x7f000001, whichURLnormalizes, and every bracketed IPv6;allow, checked withmatchesHostafter lower-casing.*.xmatches subdomains only. An empty list refuses everything.An entry that is not a host pattern fails every request with a message naming it. Every refusal and failure is a
toolFailure. A caller's cancellation stays anAbortError.Worker wiring.
WORKER_TOOLSentries are now built per request fromenv.httpreads the comma-separatedLOUSHO_HTTP_ALLOWbinding.WORKER_SUPPORTED_TOOLSis['current-date','day-name','http']. When the spec listshttp,wrangler.tomlgets a commented# [vars]/# LOUSHO_HTTP_ALLOW = "api.example.com"block.What the security claims stay within. The docs say what [N13a] web_fetch built-in with pinned-DNS SSRF checks; http_request no longer open to DNS rebinding #277 says: a Worker can check the URL and IP-literal hosts, but it cannot check where a host name connects. The allowlist moves that trust to the deployer. A listed name is reached wherever it resolves. A model cannot choose an arbitrary or DNS-rebinding host, because only listed names pass.
Docs.
docs/cloudflare-workers.md(the G6 page that merged during this ticket): limits table rows for providers and tools, the "Providers and tools" reasons list, the key and peer paragraph, aLOUSHO_HTTP_ALLOWrow in the bindings table (the intro line "Its two bindings:" became "Its bindings:"), and a[vars]example.docs/deployment.md: the summary list.docs/providers.md: the "Where each provider runs" note.docs/tools.mdanddocs/troubleshooting.md: the Worker sentences, which now link tocloudflare-workers.md#providers-and-tools.Tests.
workerHttp.test.ts(19 tests, no network).cloudflare.test.ts:web-fetchandollama;wrangler.toml[vars]line;prepareWorkerSpecresolvinghttp;it.eachreal-provider bundle build now includesopenrouter.it.eachnow replacesglobalThis.fetchwith a 401 stub for all three providers. It asserts that the request went to the provider's own host, so the test no longer touches the network.A new build with
provider: openrouter, tools: [http]checks the leak check and thewrangler.tomlline. A scripted OpenRouter (an injectedfetchanswering chat completions with a tool call) drives the bundle's/chat:LOUSHO_HTTP_ALLOWis unset (and the target host is never requested);All builds use
withBuildLock.src/schedules/scheduled.test.tsusedtools: ['http']as "a tool the Worker cannot build". It now usesweb-fetch.CHANGELOG entry under Unreleased / Added.
Notes:
mockprovider cannot be scripted from a spec: it only produces a tool call with{ input: 'mock input' }. So the test scripts the bundledopenrouterprovider through an injectedfetch. That also exercises OpenRouter end to end, offline.createAgentnames a spec tool after its spec key, on Node and on the Worker alike. So the model sees the tool ashttp, while the descriptor name ishttp_request. That behaviour existed before this change.Verification (on the branch after merging origin/main at d244b1f)
Live test spend: none. The ticket has no live test, and no model or provider API was called. The provider bundle tests now stub
fetch.Docs site follow-up
docs/cloudflare-workers.md(limits table, "Providers and tools" list, bindings table and its intro line,[vars]example),docs/deployment.md,docs/providers.md,docs/tools.md,docs/troubleshooting.md.🤖 Generated with Claude Code