Repository navigation
Let Builtin shortcuts hand URL inputs to API2 as input_url - #607
Merged
Merged
Conversation
When every input of a Builtin shortcut call is a URL and the Builtin accepts input_url (api2#10292), send the URLs with template_id instead of downloading and tus-uploading them here. API2 imports them itself, so the Assembly exists at once and large files no longer run into the wait budget. API2 hosts without input_url support ignore the parameter and complete the Builtin without input files within milliseconds. The shortcut reads the status once or twice to detect that, and falls back to the download path, as it does when API2 refuses input_url for the request. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
- Recognize a host that runs input_url by its `imported` job and keep reading a slow host's status for up to 2.5 seconds before taking it as importing. - Keep the download path when a URL input was given a name the URL does not carry, and for upload_behavior none, which asks for reserved upload URLs. - Stop probing at the call's own wait deadline. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
API2 keeps percent escapes in imported file names, so a given name only matches the raw last path segment. Each probe's status read now ends with the call's remaining wait budget instead of after five seconds. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
API2 can rename an imported file after redirects or Content-Disposition, so only an upload keeps a given file name: any named URL input now downloads. AbortSignal.timeout() refuses fractional delays, which made every probe below a five second budget throw and skip the fallback. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
…sembly Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
A failed status read ended probing, so an old host's empty Assembly could be returned without the fallback. Reads are now retried within the budget, and a call that still cannot tell carries an mcp_input_url_unconfirmed warning. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Retried status reads could each wait five seconds, adding up to 22 seconds to a call and eating into the time a fallback download needs. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
The MCP server only talks to our API2, and this release ships after api2#10292 is on every host, so detecting old hosts only added status reads, empty fallback Assemblies and a warning. API2's refusals now surface like any other error, and the e2e checks the import itself. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
Errors and anything other than a clean completion without input files now fail, so only the rollout gap is skipped. Co-Authored-By: Claude Opus 5.5 (1M context) <noreply@anthropic.com>
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.
Why
When a user gives ChatGPT, Claude or Codex a URL for a Builtin shortcut (caption this video, transcribe this talk), the MCP server downloads the file and tus-uploads it before an Assembly exists. A 239 MB video blocked past the host's tool-call deadline. #603 (and #602) bounded that with a 45 second wait budget and
mcp_preparation_timeout, but the download still happens in the wrong layer: large URLs simply fail.api2#10292 adds a top-level
input_urlAssembly parameter: for an eligible locked Builtin, API2 replaces the:originalupload input with its own/http/importStep and keepstemplate_id, field validation and provenance. With it, the Assembly exists on the first response, nothing is downloaded by the MCP server, and nothing blocks on file size.Sequencing: release after api2#10292 is fleet-wide, no transition probe
api2#10292 is rolling out to every API2 host (build 39701275724).
@transloadit/mcp-serverwith this change is released and deployed only after that rollout completes. The hosted MCP server is the consumer that matters and it only talks to our API2, so the shortcut assumesinput_urlsupport and does not detect older hosts.Earlier rounds of this PR carried a transition probe (status reads after creation, a fallback to download when an old host completed the Builtin without input files, a fallback on
INVALID_FORM_DATAnaminginput_url, and anmcp_input_url_unconfirmedwarning). That was removed in 3318f9d: it caused most review findings, added status reads to every call, and would have left an empty Assembly in a customer account for each call that hit an old host. If API2 refusesinput_urlfor a request, its error now reaches the model like any other API2 error, without a silent second Assembly.What changes
input_url. When every file and attachment of a shortcut call is an http(s) URL, the Builtin is eligible and API2's literal-URL rules hold (absolute http(s), at most 4096 characters, no whitespace, no${, no|, 1 to 10 URLs, exactly one forcaption-video), the shortcut creates{ template_id, input_url, fields }with no uploads. Mixed inputs (URL plus base64, sandboxexpected_uploadsbeyond the URLs),upload_behavior: 'none'(which asks for reserved upload URLs), inputs given a file name, such as host attachments (API2 names imports after the URL, its redirects orContent-Disposition, so the given name and the extension processing may depend on would be lost), ineligible Builtins and URLs API2 would refuse keep today's download path.allowInputImportbut does not publish it in the catalog, somcpBuiltinInputUrlMaxCountssits next tomcpBuiltinTemplateManifestin the alphalib Builtin manifest (@transloadit/zod/v4/builtinTemplates), keyed by the approved versions and mirroring api2'sbuiltinInputImportTemplateNames. A test pins the list and checks every entry is an approved shortcut.capture-webpagestays out, as in API2.input_url(string or 1 to 10 strings) is added to alphalib'sassemblyInstructionsSchema, socreateAssembly({ params: { template_id, input_url } })type-checks in@transloadit/node. It stays out of the shared shape that Template content uses, like in API2.Review history
upload_behavior: 'none'lost its reservations, given file names were dropped, and probing ignored a shorterwait_timeout_ms.AbortSignal.timeout()throw, and a URL's own name does not guarantee the imported name, so any input with a given file name now keeps the download path.input_url. Kept on purpose for the rollout window, as the test comment says; drop the skip once api2#10292 is fleet-wide. The loop ended at the two-run cap without two consecutive clean rounds (round 8 had no P0-P2 findings, round 7 had one).Tests
test/unit/builtin-input-url.test.ts: request shape (template_id,input_url,fields, no files/uploads/expected uploads, nothing downloaded, no status reads) for files and attachments; eligibility pinning and the URL rules;caption-videotakes one URL and downloads two; mixed inputs, sandbox uploads,upload_behavior: 'none', named inputs and ineligible Builtins keep the download path; an Assembly that ran without input files is returned as API2 reported it; an API2 refusal ofinput_urlsurfaces as a tool error with no download and no second Assembly.test/e2e/url-import.test.ts: first creates abuiltin/prepare-imageAssembly withinput_urldirectly against API2 and fails on any error. If API2 imported the URL,transloadit_prepare_imagewith a URL must complete with one input file, no uploads, and results. If the host completed without input files (noinput_urlsupport yet), the test is skipped with the API2 build in the reason. It passed (not skipped) against production on 2026-10-22, build 39701275724. Re-run the e2e after the rollout completes to confirm on the full fleet before releasing.yarn check,yarn lint:changesets,yarn lint:transloadit-sync, mcp-serverlint:ts, e2e suite.🤖 Claimed by kvz on
framework1/node-sdksince 2026-10-21 · resume:claude --resume 26eaa88e-b3fa-4cc1-bcce-0c7ff5b6bab7