Repository navigation
feat(load_artifact): allow urls entries to set the saved filename - #103
Merged
Merged
Conversation
A `urls` entry may now be {"url": ..., "filename": ...} as well as a bare
URL string. A bare string keeps today's naming exactly (last path segment,
percent-decoded, "downloaded" when empty, repeats suffixed -1, -2, ...);
an object entry is saved as <destination_path>/<filename> verbatim, so a
URL with no usable name (an opaque object key) can land under the name the
prompt refers to.
Entries are validated and named by one function, called at construction for
the stored urls and in _resolve_inputs for a per-run `urls` override, so a
bad override fails before anything is loaded. An object entry needs a
non-empty string url and filename and no other key; the filename must pass
validate_relative_filename and be a plain file name (no path separators,
not "."). An explicit filename is never renamed: one given twice, or one a
bare URL's derived name would match, raises instead of being suffixed.
loaded_urls[].files records the names as written. to_dict/from_dict round-
trip the entries unchanged: strings stay strings, objects stay objects.
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
earakely-scale
left a comment
Collaborator
There was a problem hiding this comment.
Does what it says. It merges cleanly with current main, and the unit tier passes on the merge.
One suggestion, inline: names derived from bare URLs skip the rules explicit names now get.
Heads-up for consumers: anything that pre-validates urls as strings, such as a URL scheme check, needs to read entry["url"] from object entries too, or those entries skip it.
earakely-scale
approved these changes
Oct 8, 2026
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.
What and why
load_artifactnames each URL download after the last segment of the URL path. When that segment is an opaque object key, as it often is for object-storage and signed URLs, the file lands with no real name and no extension. The prompt meanwhile refers to the file by its real name, and the agent has no way to match the two.A
urlsentry may now be{"url": ..., "filename": ...}as well as a bare URL string:{"id": "load-inputs", "type": "load_artifact", "agent_name": "agent", "destination_path": "/tmp/data", "urls": [ {"url": "https://files.example/objects/obj-4f9c2a", "filename": "report.txt"}, "https://a.example/data.csv" ]}This saves
/tmp/data/report.txtand/tmp/data/data.csv, andloaded_urls[].filesrecords both names.downloadedwhen empty, and repeats suffixed-1,-2, ….urlandfilenameand no other key. The filename must be a plain file name: relative, no.., no path separators../avsawould get past the duplicate check, andavsa/bwould put a file inside a directory instead of failing.__init__andfrom_dictreject a bad stored entry. A per-runurlsoverride is validated in_resolve_inputs, before anything in the step is loaded.to_dictandfrom_dictpass entries through unchanged.Compatibility: existing steps are unchanged. A step that uses the object form needs a version with this change to run. An older version accepts the step but fails at run time when it names the downloads.
How it was tested
make unit-test: 6544 passed, 13 skipped.tst/unit/task_step/test_load_artifact_{container_sandbox,overrides,url_filenames,vm_target}.py:loaded_urls.filename, an unknown key,.., an absolute path, a nested path..github/scripts/check_plugin_api.py: no break to the plugin surface.urls.🤖 Generated with Claude Code
The PR appears safe to merge.
What we checked:
Summary
load_artifactURL lists can now mix bare URLs with entries that choose a filename. Chosen names are used for downloads and recorded inloaded_urls[].files.Diagram
%%{init: {'theme': 'neutral'}}%% flowchart LR A["urls entry"] --> B{"Entry type"} B -->|Bare URL| C["Name from URL path"] B -->|Object| D["Check chosen filename"] C --> E["Check against chosen names"] D --> E E --> F["Download to target"] F --> G["Record loaded_urls"]Reviews (1) · Last reviewed commit: "feat(load_artifact): allow urls entries ..." · Reviewed by Greptile