fix(agents): bound model catalog JSON response reads for bedrock-mantle and huggingface#96480
fix(agents): bound model catalog JSON response reads for bedrock-mantle and huggingface#96480hugenshen wants to merge 1 commit into
Conversation
|
Thanks for the context here. I swept through the related work, and this is now duplicate or superseded. Keep open: current main still has the HuggingFace unbounded success-body read, and this branch is a narrow, plausible fix with no blocking code finding. The remaining blocker is merge readiness: the current PR body proof is stale to the dropped Mantle half and does not directly demonstrate the current HuggingFace-only change. Canonical path: Close this PR as superseded by #99961. So I’m closing this here and keeping the remaining discussion on #99961. Review detailsBest possible solution: Close this PR as superseded by #99961. Do we have a high-confidence way to reproduce the issue? Yes by source inspection: current main sends successful HuggingFace discovery responses to native Is this the best way to solve the issue? Yes for the code shape: using the existing plugin-sdk provider JSON reader is the narrow owner-boundary fix and preserves the existing static-catalog fallback. Merge readiness is not complete until the current HuggingFace-only head has direct real behavior proof or a maintainer proof override. Security review: Security review cleared: The diff narrows an untrusted provider-response DoS boundary and does not add dependencies, workflows, permissions, package-resolution changes, or secret handling. AGENTS.md: found and applied where relevant. What I checked:
Likely related people:
Codex review notes: model internal, reasoning high; reviewed against 92cfceac0924. |
|
@clawsweeper re-review |
|
🦞🧹 I asked ClawSweeper to review this item again. |
|
@sallyom here is a bounded response pr ready to merge, I'd really appreciate it if you could take a look! |
|
@clawsweeper re-review |
5eea52c to
04c9d94
Compare
|
The Amazon Bedrock Mantle half of this PR is now superseded by #99961, landed as Please drop the Mantle production/test changes when refreshing this branch. The Hugging Face model-catalog bound remains distinct and should stay independently reviewable. Thanks for the broader response-boundary work. |
…ider reader Drop the Mantle half of the original combined change; that surface is already covered by openclaw#99961 on main. Keep only the HuggingFace catalog success-path bound read using readProviderJsonResponse. Co-authored-by: Cursor <[email protected]>
04c9d94 to
cbd201f
Compare
|
Superseded by #101079, now landed on The landed fix consumes the Hugging Face model-discovery JSON through the shared 16 MiB bounded reader, cancels overflow, preserves the static-catalog fallback, and includes overflow-cleanup plus valid-response coverage. Exact-SHA release gate 28826762727 passed. Thank you @hugenshen for working on this. |
What Problem This Solves
Amazon Bedrock Mantle model discovery (
/v1/models) and HuggingFace model discovery (/models) both parse successful HTTP responses with an unboundedawait response.json(). On Node,response.json()buffers the entire body before parsing, so a provider-controlled endpoint can stream an arbitrarily large or never-ending JSON payload and push the discovery path into memory pressure, hangs, or OOM.That matters here because both inputs are untrusted:
This PR closes the same response-body gap already fixed for sibling catalog surfaces in
#95418,#95420, and#96027, but for the two remaining bundled provider discovery reads still using unbounded success-path JSON parsing on currentmain.Changes
discoverMantleModelswithreadProviderJsonResponse(response, "bedrock-mantle.model-discovery").discoverHuggingfaceModelswithreadProviderJsonResponse(response, "huggingface.model-discovery").[]on discovery failure, and HuggingFace still falls back to the static bundled catalog on discovery failure.Responseobjects instead of plain{ json() {} }mocks so the changed path uses the same body/stream API shape as production.scripts/proof-mantle-catalog-bound.mjs, an affected-path proof harness that drives the realdiscoverMantleModelsentry point against a local streaming server via injectedfetchFn.Real behavior proof
Content-Lengthmust not be buffered whole if it exceeds the JSON safety cap; the read must stop near the cap, cancel the stream, and fail soft through the existing discovery fallback paths instead of draining the full body.discoverMantleModelsinextensions/amazon-bedrock-mantle/discovery.ts— the exact success-path function changed by this PR.node:httpserver on127.0.0.1, streaming ~24 MiB catalog JSON in 64 KiB chunks with noContent-Length, injected via the productionfetchFnparameter.discoverMantleModels({ fetchFn })against/huge→ fail-soft fallback ([]when cache cold) plus early stream stop near the 16 MiB cap./small→ normal catalog parses with model id intact./small, expire refresh window, hit/huge→ bounded overflow falls back to cached models.discoverMantleModelsreturned[]when cache was cold.anthropic.claude-sonnet-4-6.pnpm test extensions/amazon-bedrock-mantle/discovery.test.tspassed 29/29 tests, including updated Mantle discovery tests that now use realResponseobjects on the success path.discoverHuggingfaceModelshas no injectable fetch seam, but uses the samereadProviderJsonResponsecall-site pattern; Mantle affected-path proof exercises the bounded read + fail-soft catch path through the real changed discovery function.discoverHuggingfaceModelsharness against a local streaming server.Evidence
Label: security
AI-assisted.