feat: upload_file tool — let MCP callers provide files for upload into page file inputs#620
feat: upload_file tool — let MCP callers provide files for upload into page file inputs#620apakkhalin-sudo wants to merge 2 commits into
Conversation
When the hub receives an execute message with a config payload, onExecute awaits configure() and then calls execute(). configure()'s setConfig re-renders useAgent, and the [config] effect cleanup disposes the current agent — the very agent the caller is about to run (execute still resolves agentRef to it). Its AbortController fires and every MCP task instantly fails with 'Task aborted' (alibaba#570). Two changes in useAgent.configure(): - Skip the agent rebuild entirely when the merged config is value-equal to the current one (the common MCP case: env config matches saved settings). Storage writes still happen. - When config genuinely changed, resolve configure()'s promise only after the [config] effect has installed the new agent, so callers execute on the new agent instead of the disposed one. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
…o page file inputs Implements the upload_file @todo. Files are offered per task by the MCP caller (absolute paths on the MCP host), validated and registered under unguessable random ids, and served only for the task's duration at GET /files/{id} on the existing localhost HTTP bridge. The hub registers offered files and appends their ids to the task text; the new upload_file customTool (extension) fetches the bytes, base64s them across the messaging boundary, and PageController injects them into the file input via DataTransfer + input/change events. The index may point at the visible upload button/label/dropzone — the real (often hidden) input is resolved from it. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
|
|
There was a problem hiding this comment.
💡 Codex Review
Here are some automated review suggestions for this pull request.
Reviewed commit: 13c7703e65
ℹ️ About Codex in GitHub
Codex has been enabled to automatically review pull requests in this repo. Reviews are triggered when you
- Open a pull request for review
- Mark a draft as ready
- Comment "@codex review".
If Codex has suggestions, it will comment; otherwise it will react with 👍.
When you sign up for Codex through ChatGPT, Codex can also answer questions or update the PR, like "@codex address that feedback".
| const inForm = element.closest('form')?.querySelector('input[type="file"]') | ||
| if (isFileInput(inForm ?? null)) return inForm as HTMLInputElement |
There was a problem hiding this comment.
Avoid choosing the wrong file input in a form
When the indexed target is a visible upload button/dropzone inside a form with more than one file input (for example separate resume and cover-letter uploads wired by click handlers instead of labels), this fallback always returns the first input[type="file"] in the form. That silently uploads to the wrong field even though the selected index points at a different upload control; the form fallback should only be used when it is unambiguous or when a closer association can be proven.
Useful? React with 👍 / 👎.
| mime: MIME_TYPES[extname(path).toLowerCase()] ?? 'application/octet-stream', | ||
| size: info.size, | ||
| } | ||
| this.#taskFiles.set(id, meta) |
There was a problem hiding this comment.
Clear task files when the hub disconnects
When a file-backed task is registered and the hub WebSocket disconnects before sending a result or error, these map entries remain because the close handler only rejects #pendingTask and never clears #taskFiles. The HTTP route then keeps serving /files/{id} after the task has ended, and even across later no-file tasks, leaving the local file readable to any client that has the id.
Useful? React with 👍 / 👎.
What
Implements the
upload_file@todo: MCP callers can now provide local files that the agent uploads into<input type="file">elements on the page.How it works
GET /files/{id}on the existing localhost HTTP bridge — no new ports, no persistent exposure.upload_filecustomTool in the extension fetches the bytes, base64-encodes them across the messaging boundary, andPageControllerinjects them into the file input viaDataTransfer+ syntheticinput/changeevents.Also included
f0219abfixes a race that breaks every hub task that arrives with aconfigpayload:onExecuteawaitsconfigure()beforeexecute(), butsetConfigre-rendersuseAgentand the[config]effect cleanup disposes the current agent — aborting the task it is about to run ("Task aborted" with zero LLM requests). The fix was found while developing this feature and the feature's MCP path exercises it, so it's included here; happy to split it into its own PR if you prefer.Testing
execute_taskwithfiles: [...]against a page with aFileReader-backed file input — exact filename, size, and byte content read back by the page.