Hacktoberfest 2026: the issues maintainers tagged for October, open and beginner-friendly. Browse Hacktoberfest issues

[FEATURE] Preserve external document URLs as input_file.file_url in the Responses protocol

Open
#1,262 0 comments 1 reaction 0 assignees View on GitHub

Maintainers usually reply within 1 day

Nobody has claimed this yet.

Assessment

Difficulty
4/5
Estimated time
3-5 days
Newbie friendliness
55/100
Issue type
Feature
Clarity
Clearly specified
Activity status
Active
Tech stack
ruby
Domain
api, backend

Research direction

Start with RubyLLM::Protocols::Responses::Media#render_document and the provider capability handling that decides which document representations are supported. Read the related attachment URL handling and add or inspect a spec for rendering a URL-backed PDF. Done means supported providers send file_url without downloading the document, while local files, uploaded files, and unsupported providers retain their stated behavior.

Written by the indexing model from the issue text.

Description

enhancement
Scope check
  • This is core LLM communication (not application logic)
  • This benefits most users (not just my use case)
  • This can't be solved in application code with current RubyLLM
  • I read the Contributing Guide
Due diligence
  • I searched existing issues
  • I checked the documentation
What problem does this solve?

RubyLLM accepts HTTP(S) URLs as attachment sources, but URL-backed documents are downloaded by the application and converted to Base64 when rendered for a Responses API request.

For example:

attachment = RubyLLM::Attachment.new(
  "https://example.com/signed/report.pdf",
  filename: "report.pdf"
)

chat.ask("Summarize this document", with: attachment)

RubyLLM::Protocols::Responses::Media#render_document currently renders every non-provider document as:

{
  type: "input_file",
  filename: document.filename,
  file_data: document.for_llm
}

For a URL-backed attachment, document.for_llm reads the remote file into the application process and Base64-encodes it.

The OpenAI Responses API supports external document URLs directly:

{
  "type": "input_file",
  "file_url": "https://example.com/signed/report.pdf"
}

Passing the URL through would allow the provider to download the document directly. This avoids:

  • Downloading the entire document into application memory
  • Base64 encoding overhead
  • Increasing the request body by approximately 33%
  • Relaying file bytes through the application server
  • Unnecessary latency and network traffic for applications using S3, CloudFront, or another object store

This is especially useful for Rails applications that generate short-lived authorized URLs for private uploads.

RubyLLM already preserves external URLs for images through Attachment#url_or_data_uri, so document URLs currently behave differently from image URLs.

In one sentence: preserve URLs when the provider supports them

I found two related issues, but neither appears to address this behavior:

  • #134 added attachment support to acts_as_chat; it does not preserve document URLs during Responses serialization.
  • #1261 concerns multipart ordering when uploading bytes to OpenAI's /v1/files endpoint. Passing file_url to /v1/responses would not use that upload endpoint.

This behavior is present in RubyLLM 2.1.1 and appears to remain present on main.

Proposed solution

When a document attachment is backed by an HTTP(S) URL and the selected Responses provider supports external file URLs, render it using file_url instead of downloading and encoding it as file_data.

Conceptually:

def render_document(document)
  if document.url?
    {
      type: "input_file",
      file_url: document.source.to_s
    }
  else
    {
      type: "input_file",
      filename: document.filename,
      file_data: document.for_llm
    }
  end
end

The exact implementation may need to be provider-aware because not every Responses-compatible provider necessarily supports external document URLs. Following RubyLLM's provider/protocol design, unsupported providers could retain the existing file_data behavior.

Expected behavior:

  • URL-backed document supported by the provider: send file_url
  • Local path, IO, or Active Storage object: continue sending filename and file_data
  • RubyLLM::UploadedFile: continue sending file_id
  • URL-backed image: preserve the existing behavior
  • Providers without URL-backed document support: retain the appropriate provider-specific fallback

A spec could construct a URL-backed PDF with an explicit filename, render the request, and assert that:

  • The payload contains file_url
  • The payload does not contain file_data
  • The URL is not downloaded by RubyLLM

I would be happy to help test or contribute the implementation.

Why this belongs in RubyLLM

This is request translation for a provider API, not application workflow logic.

An application can technically work around the behavior by monkey-patching RubyLLM::Protocols::Responses::Media, defining a custom protocol/provider, or bypassing RubyLLM for these requests. However, there is currently no supported public API that lets an application choose file_url for a document attachment.

A monkey patch would depend on internal classes and would have to reproduce provider capability decisions. Bypassing RubyLLM would also lose the consistent chat, usage, instrumentation, tool, and provider behavior that the gem provides.

RubyLLM already owns:

  • Attachment source detection
  • Provider capability handling
  • Responses request serialization
  • The choice between file_id, file_data, and provider-specific representations

Choosing file_url for a URL-backed document is therefore part of RubyLLM's core LLM communication responsibility. It benefits any application using remote object storage or signed document URLs, rather than being specific to one application's domain.

Dominant language
Ruby
Stars
4.5k
Forks
515
Avg merge
9h 31m
Merged PRs (30d)
220

Getting set up

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

More from crmne/ruby_llm

All issues in crmne/ruby_llm

Similar issues

More Ruby issues

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.