Skip to content

Support Bedrock application inference profile ARNs as model ids#803

Open
mattwebbio wants to merge 1 commit into
crmne:mainfrom
mattwebbio:bedrock-application-inference-profile-arn
Open

Support Bedrock application inference profile ARNs as model ids#803
mattwebbio wants to merge 1 commit into
crmne:mainfrom
mattwebbio:bedrock-application-inference-profile-arn

Conversation

@mattwebbio

Copy link
Copy Markdown

What this does

Fixes Bedrock so an application inference profile ARN can be passed as the model id.

Application inference profiles (used for cost-allocation tagging) are invoked by passing their ARN as the modelId. An ARN contains a /:

arn:aws:bedrock:us-west-2:123456789012:application-inference-profile/<profile-id>

The Bedrock provider builds the request path with the id raw — "/model/#{@model.id}/converse" — and the SigV4 signer (Bedrock::Signing#canonical_uri) splits the path on / to build the canonical URI. So the ARN's internal / is treated as a path separator in both the request URL and the signed canonical path, truncating the modelId to .../application-inference-profile. Bedrock then rejects the call:

The provided model identifier is invalid

The fix percent-encodes the model id's / (%2F) so the ARN stays a single path segment. canonical_uri then re-encodes each segment, double-encoding it to %252F — which is exactly what SigV4 requires for non-S3 services — so the signed path and the sent path stay consistent.

This is a no-op for ordinary model ids, which contain no /. A : version suffix (e.g. ...-v1:0) is a valid path-segment character and is unaffected.

Files:

  • lib/ruby_llm/providers/bedrock/chat.rbcompletion_url now escapes the id via a new escape_model_id helper.
  • lib/ruby_llm/providers/bedrock/streaming.rbstream_url escapes the id too (converse-stream).
  • spec/ruby_llm/providers/bedrock_spec.rb — new unit spec covering the converse URL, the converse-stream URL, an unchanged ordinary id, and the SigV4 canonical-path encoding.

Type of change

  • Bug fix
  • New feature
  • Breaking change
  • Documentation
  • Performance improvement

Scope check

  • I read the Contributing Guide
  • This aligns with RubyLLM's focus on LLM communication
  • This isn't application-specific logic that belongs in user code
  • This benefits most users, not just my specific use case

Required for new features

N/A — bug fix in an existing provider, no new public API.

Quality check

  • I ran overcommit --install and all hooks pass
  • I tested my changes thoroughly
    • For provider changes: Re-recorded VCR cassettes with bundle exec rake vcr:record[provider_name]N/A: this change only affects URL/path string construction; it touches no HTTP request body or response handling, and the new spec is a pure unit test (no cassette), consistent with the other top-level provider specs (vertex_ai_auth_spec.rb, ollama_spec.rb, etc.).
    • All tests pass: bundle exec rspec spec/ruby_llm/providers/bedrock_spec.rb (4 examples, 0 failures); bundle exec rubocop on the changed files reports no offenses.
  • I updated documentation if needed — none needed.
  • I didn't modify auto-generated files manually (models.json, aliases.json)

AI-generated code

  • I used AI tools to help write this code
  • I have reviewed and understand all generated code (required if above is checked)

API changes

  • Breaking change
  • New public methods/classes
  • Changed method signatures
  • No API changes

Application inference profiles (used for cost-allocation tagging) are invoked by
passing their ARN as the modelId. The Bedrock provider built the request path as
"/model/#{@model.id}/converse" with the id raw, so an ARN's internal "/"
(".../application-inference-profile/<id>") was parsed as a path separator in both
the request URL and the SigV4 canonical path — AWS then rejected it with
"The provided model identifier is invalid".

Percent-encode the model id's "/" so the ARN stays a single path segment.
canonical_uri re-encodes per segment, which double-encodes it as SigV4 requires for
non-S3 services, keeping the signed and sent paths consistent. No-op for ordinary
model ids (which contain no "/"); ":" version suffixes are valid path-segment
characters and are unaffected.
@codecov

codecov Bot commented Jun 11, 2026

Copy link
Copy Markdown

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 88.47%. Comparing base (978d5f2) to head (8ef5bb5).

Additional details and impacted files
@@           Coverage Diff           @@
##             main     #803   +/-   ##
=======================================
  Coverage   88.47%   88.47%           
=======================================
  Files         122      122           
  Lines        5898     5900    +2     
  Branches     1405     1405           
=======================================
+ Hits         5218     5220    +2     
  Misses        680      680           

☔ View full report in Codecov by Harness.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@mattwebbio mattwebbio marked this pull request as ready for review June 11, 2026 03:20
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant