diff --git a/.github/ISSUE_TEMPLATE/bug_report.yml b/.github/ISSUE_TEMPLATE/bug_report.yml
new file mode 100644
index 0000000..475e926
--- /dev/null
+++ b/.github/ISSUE_TEMPLATE/bug_report.yml
@@ -0,0 +1,61 @@
+name: Bug report
+description: Report a reproducible bug or unexpected behavior
+labels: [bug]
+body:
+ - type: markdown
+ attributes:
+ value: |
+ Thanks for reporting a bug! Please provide as much detail as possible.
+
+ - type: input
+ id: gem_version
+ attributes:
+ label: Gem Version
+ placeholder: e.g., 0.2.1
+ validations:
+ required: true
+
+ - type: textarea
+ id: description
+ attributes:
+ label: What happened?
+ description: Describe the unexpected behavior or error message
+ validations:
+ required: true
+
+ - type: textarea
+ id: steps
+ attributes:
+ label: Steps to Reproduce
+ description: Provide a minimal script or code snippet to reproduce the issue
+ placeholder: |
+ 1. Call method `X` with parameter `Y`
+ 2. Observe error message `Z`
+ validations:
+ required: true
+
+ - type: textarea
+ id: expected
+ attributes:
+ label: What did you expect to happen?
+ description: What should the correct behavior be?
+
+ - type: textarea
+ id: environment
+ attributes:
+ label: Environment
+ description: Ruby version, OS, and any other relevant info
+ placeholder: |
+ Ruby version: 3.2.2
+ OS: macOS 14.0
+ Bundler version: 2.4.0
+
+ - type: checkboxes
+ id: confirmation
+ attributes:
+ label: Before submitting
+ options:
+ - label: I've updated to the latest version of the gem
+ required: true
+ - label: I've read the README and documentation
+ required: true
\ No newline at end of file
diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml
new file mode 100644
index 0000000..a2e01d1
--- /dev/null
+++ b/.github/workflows/release.yml
@@ -0,0 +1,29 @@
+name: Release
+
+on:
+ push:
+ tags:
+ - 'v*.*.*'
+
+jobs:
+ release:
+ runs-on: ubuntu-latest
+
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Set up Ruby
+ uses: ruby/setup-ruby@v1
+ with:
+ ruby-version: '3.3'
+ bundler-cache: true
+
+ - name: Build and Push Gem
+ env:
+ GEM_HOST_API_KEY: ${{ secrets.RUBYGEMS_AUTH_TOKEN }}
+ run: |
+ mkdir -p ~/.gem
+ echo -e "---\n:rubygems_api_key: $GEM_HOST_API_KEY" > ~/.gem/credentials
+ chmod 0600 ~/.gem/credentials
+ gem build *.gemspec
+ gem push *.gem
\ No newline at end of file
diff --git a/.github/workflows/test.yml b/.github/workflows/test.yml
new file mode 100644
index 0000000..b386563
--- /dev/null
+++ b/.github/workflows/test.yml
@@ -0,0 +1,26 @@
+name: CI
+
+on:
+ push:
+ branches: [main]
+ pull_request:
+ branches: [main]
+
+jobs:
+ test:
+ runs-on: ubuntu-latest
+ strategy:
+ matrix:
+ ruby-version: ['3.1', '3.2', '3.3', '3.4']
+
+ steps:
+ - uses: actions/checkout@v4
+
+ - name: Set up Ruby
+ uses: ruby/setup-ruby@v1
+ with:
+ ruby-version: ${{ matrix.ruby-version }}
+ bundler-cache: true
+
+ - name: Run tests
+ run: bundle exec rspec
\ No newline at end of file
diff --git a/.rubocop.yml b/.rubocop.yml
index 0fa7209..c285a7a 100755
--- a/.rubocop.yml
+++ b/.rubocop.yml
@@ -1,5 +1,9 @@
+plugins:
+ - rubocop-rake
+ - rubocop-rspec
+
AllCops:
- TargetRubyVersion: 2.6
+ TargetRubyVersion: 3.1
NewCops: enable
SuggestExtensions: false
diff --git a/CHANGELOG.md b/CHANGELOG.md
index 578fd99..ec075f3 100644
--- a/CHANGELOG.md
+++ b/CHANGELOG.md
@@ -1,3 +1,16 @@
+## 1.0.0.rc3 (2025-04-06)
+
+- Added rspec test suite with vcr, covering current functionality:
+ - Chat and Multi-turn conversation tests
+ - Streaming response tests
+ - Tools calling functionality tests
+ - Embedding generation tests
+ - Image generation tests
+- Added GitHub workflows for:
+ - CI testing across Ruby versions 3.1, 3.2, 3.3, and 3.4
+ - Automated gem release process
+ - Issue templates for bug reports
+
## 1.0.0.rc2 (2025-03-16)
- Minor improvements to README documentation and fixes to GitHub repository links.
diff --git a/Gemfile b/Gemfile
index dea8dd5..f8d08b2 100644
--- a/Gemfile
+++ b/Gemfile
@@ -1,12 +1,18 @@
+# frozen_string_literal: true
+
source "https://rubygems.org"
-# Include gem dependencies from litellm.gemspec
gemspec
-gem "byebug", "~> 11.1.3"
-gem "dotenv", "~> 2.8.1"
-gem "rake", "~> 13.2"
-gem "rspec", "~> 3.13"
-gem "rubocop", "~> 1.73.1"
-gem "vcr", "~> 6.1.0"
-gem "webmock", "~> 3.24.0"
+group :development do
+ gem "activesupport", "< 8.0"
+ gem "bundler", ">= 2.0"
+ gem "dotenv"
+ gem "rake", ">= 13.0"
+ gem "rspec", "~> 3.12"
+ gem "rubocop", ">= 1.0"
+ gem "rubocop-rake"
+ gem "rubocop-rspec"
+ gem "vcr"
+ gem "webmock"
+end
diff --git a/Gemfile.lock b/Gemfile.lock
index ac1f74a..8f04c91 100644
--- a/Gemfile.lock
+++ b/Gemfile.lock
@@ -1,61 +1,81 @@
PATH
remote: .
specs:
- litellm (1.0.0.rc1)
+ litellm (1.0.0.rc3)
event_stream_parser (>= 0.3.0, < 2.0.0)
faraday (>= 1)
GEM
remote: https://rubygems.org/
specs:
+ activesupport (7.2.2.1)
+ base64
+ benchmark (>= 0.3)
+ bigdecimal
+ concurrent-ruby (~> 1.0, >= 1.3.1)
+ connection_pool (>= 2.2.5)
+ drb
+ i18n (>= 1.6, < 2)
+ logger (>= 1.4.2)
+ minitest (>= 5.1)
+ securerandom (>= 0.3)
+ tzinfo (~> 2.0, >= 2.0.5)
addressable (2.8.7)
public_suffix (>= 2.0.2, < 7.0)
- ast (2.4.2)
+ ast (2.4.3)
+ base64 (0.2.0)
+ benchmark (0.4.0)
bigdecimal (3.1.9)
- byebug (11.1.3)
+ concurrent-ruby (1.3.5)
+ connection_pool (2.5.0)
crack (1.0.0)
bigdecimal
rexml
- diff-lcs (1.5.1)
- dotenv (2.8.1)
+ diff-lcs (1.6.1)
+ dotenv (3.1.7)
+ drb (2.2.1)
event_stream_parser (1.0.0)
- faraday (2.12.0)
- faraday-net_http (>= 2.0, < 3.4)
+ faraday (2.12.2)
+ faraday-net_http (>= 2.0, < 3.5)
json
logger
- faraday-net_http (3.3.0)
- net-http
- hashdiff (1.1.1)
- json (2.9.1)
+ faraday-net_http (3.4.0)
+ net-http (>= 0.5.0)
+ hashdiff (1.1.2)
+ i18n (1.14.7)
+ concurrent-ruby (~> 1.0)
+ json (2.10.2)
language_server-protocol (3.17.0.4)
lint_roller (1.1.0)
- logger (1.6.6)
- net-http (0.5.0)
+ logger (1.7.0)
+ minitest (5.25.5)
+ net-http (0.6.0)
uri
parallel (1.26.3)
- parser (3.3.6.0)
+ parser (3.3.7.4)
ast (~> 2.4.1)
racc
+ prism (1.4.0)
public_suffix (6.0.1)
racc (1.8.1)
rainbow (3.1.1)
rake (13.2.1)
regexp_parser (2.10.0)
- rexml (3.3.9)
+ rexml (3.4.1)
rspec (3.13.0)
rspec-core (~> 3.13.0)
rspec-expectations (~> 3.13.0)
rspec-mocks (~> 3.13.0)
- rspec-core (3.13.0)
+ rspec-core (3.13.3)
rspec-support (~> 3.13.0)
- rspec-expectations (3.13.0)
+ rspec-expectations (3.13.3)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.13.0)
- rspec-mocks (3.13.0)
+ rspec-mocks (3.13.2)
diff-lcs (>= 1.2.0, < 2.0)
rspec-support (~> 3.13.0)
- rspec-support (3.13.1)
- rubocop (1.73.2)
+ rspec-support (3.13.2)
+ rubocop (1.75.2)
json (~> 2.3)
language_server-protocol (~> 3.17.0.2)
lint_roller (~> 1.1.0)
@@ -63,16 +83,29 @@ GEM
parser (>= 3.3.0.2)
rainbow (>= 2.2.2, < 4.0)
regexp_parser (>= 2.9.3, < 3.0)
- rubocop-ast (>= 1.38.0, < 2.0)
+ rubocop-ast (>= 1.44.0, < 2.0)
ruby-progressbar (~> 1.7)
unicode-display_width (>= 2.4.0, < 4.0)
- rubocop-ast (1.38.1)
- parser (>= 3.3.1.0)
+ rubocop-ast (1.44.0)
+ parser (>= 3.3.7.2)
+ prism (~> 1.4)
+ rubocop-rake (0.7.1)
+ lint_roller (~> 1.1)
+ rubocop (>= 1.72.1)
+ rubocop-rspec (3.5.0)
+ lint_roller (~> 1.1)
+ rubocop (~> 1.72, >= 1.72.1)
ruby-progressbar (1.13.0)
- unicode-display_width (2.6.0)
- uri (1.0.2)
- vcr (6.1.0)
- webmock (3.24.0)
+ securerandom (0.4.1)
+ tzinfo (2.0.6)
+ concurrent-ruby (~> 1.0)
+ unicode-display_width (3.1.4)
+ unicode-emoji (~> 4.0, >= 4.0.4)
+ unicode-emoji (4.0.4)
+ uri (1.0.3)
+ vcr (6.3.1)
+ base64
+ webmock (3.25.1)
addressable (>= 2.8.0)
crack (>= 0.3.2)
hashdiff (>= 0.4.0, < 2.0.0)
@@ -82,14 +115,17 @@ PLATFORMS
ruby
DEPENDENCIES
- byebug (~> 11.1.3)
- dotenv (~> 2.8.1)
+ activesupport (< 8.0)
+ bundler (>= 2.0)
+ dotenv
litellm!
- rake (~> 13.2)
- rspec (~> 3.13)
- rubocop (~> 1.73.1)
- vcr (~> 6.1.0)
- webmock (~> 3.24.0)
+ rake (>= 13.0)
+ rspec (~> 3.12)
+ rubocop (>= 1.0)
+ rubocop-rake
+ rubocop-rspec
+ vcr
+ webmock
BUNDLED WITH
- 2.6.2
+ 2.6.5
diff --git a/README.md b/README.md
index 85908dd..44010c5 100644
--- a/README.md
+++ b/README.md
@@ -1,5 +1,7 @@
# LiteLLM Ruby Client
+
+
A Ruby client for [LiteLLM](https://docs.litellm.ai/docs) with support for completions, embeddings, and image generation.
## Installation
diff --git a/VERSION b/VERSION
index 525b339..facbc65 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-1.0.0.rc2
\ No newline at end of file
+1.0.0.rc3
\ No newline at end of file
diff --git a/bin/console b/bin/console
index dfb0352..e5dba7d 100755
--- a/bin/console
+++ b/bin/console
@@ -1,14 +1,16 @@
#!/usr/bin/env ruby
+# frozen_string_literal: true
require "bundler/setup"
-require "openai"
+require "litellm"
+require "dotenv/load"
-# You can add fixtures and/or initialization code here to make experimenting
-# with your gem easier. You can also use a different console, if you like.
+require "irb"
-# (If you use this, don't forget to add pry to your Gemfile!)
-# require "pry"
-# Pry.start
+LiteLLM.configure do |config|
+ config.base_url = "http://localhost:8000"
+ config.debug = true
+ config.model = "gpt-4o"
+end
-require "irb"
IRB.start(__FILE__)
diff --git a/bin/start_litellm_server b/bin/start_litellm_server
new file mode 100755
index 0000000..8985021
--- /dev/null
+++ b/bin/start_litellm_server
@@ -0,0 +1,8 @@
+#!/bin/bash
+
+# Get the directory where this script is located
+SCRIPT_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
+PROJECT_ROOT="$(dirname "$SCRIPT_DIR")"
+
+# Change to the test_server directory and run the start script
+cd "$PROJECT_ROOT/test_server" && ./start_litellm.sh
\ No newline at end of file
diff --git a/lib/litellm.rb b/lib/litellm.rb
index 63d0f53..a5507ec 100644
--- a/lib/litellm.rb
+++ b/lib/litellm.rb
@@ -1,17 +1,17 @@
# frozen_string_literal: true
-require 'faraday'
-require 'event_stream_parser'
-require 'json'
-require 'logger'
-
-require_relative 'litellm/version'
-require_relative 'litellm/configuration'
-require_relative 'litellm/streaming'
-require_relative 'litellm/client'
-require_relative 'litellm/errors'
-require_relative 'litellm/tool_handler'
-require_relative 'litellm/utils/tool_definition'
+require "faraday"
+require "event_stream_parser"
+require "json"
+require "logger"
+
+require_relative "litellm/version"
+require_relative "litellm/configuration"
+require_relative "litellm/streaming"
+require_relative "litellm/client"
+require_relative "litellm/errors"
+require_relative "litellm/tool_handler"
+require_relative "litellm/utils/tool_definition"
module LiteLLM
class Error < StandardError; end
diff --git a/lib/litellm/client.rb b/lib/litellm/client.rb
index 1497bd3..eeb965c 100644
--- a/lib/litellm/client.rb
+++ b/lib/litellm/client.rb
@@ -16,6 +16,14 @@ def initialize(config = LiteLLM.configuration)
validate_configuration!
end
+ # Get a list of available models from the LiteLLM server
+ # @return [Array] Array of model names
+ def models
+ response = make_get_request("/models")
+ parsed_response = handle_json_response(response)
+ parsed_response["data"].map { |model| model["id"] }
+ end
+
# Make a completion request
# @param messages [Array] Array of message objects
# @param model [String, nil] Optional model override
@@ -131,13 +139,13 @@ def build_tools_schema(tools)
end
end
- def make_request(endpoint, payload, &block)
+ def make_request(endpoint, payload, method: :post, &block)
request_id = SecureRandom.uuid
log_request(request_id, endpoint, payload)
- response = connection.post(endpoint) do |req|
+ response = connection.send(method, endpoint) do |req|
req.headers["X-Request-ID"] = request_id
- req.body = payload.to_json
+ req.body = payload.to_json if method == :post
req.options.on_data = Streaming.process_stream(&block) if payload[:stream]
end
@@ -148,7 +156,25 @@ def make_request(endpoint, payload, &block)
raise
end
- def handle_tool_calls(response_data, tools, model, stream, &block)
+ # Make a GET request to the specified endpoint
+ # @param endpoint [String] The API endpoint to call
+ # @param payload [Hash] The request payload
+ # @param block [Proc] Optional block for handling streaming responses
+ # @return [Faraday::Response] The API response
+ def make_get_request(endpoint, payload = {}, &)
+ make_request(endpoint, payload, method: :get, &)
+ end
+
+ # Make a POST request to the specified endpoint
+ # @param endpoint [String] The API endpoint to call
+ # @param payload [Hash] The request payload
+ # @param block [Proc] Optional block for handling streaming responses
+ # @return [Faraday::Response] The API response
+ def make_post_request(endpoint, payload = {}, &)
+ make_request(endpoint, payload, method: :post, &)
+ end
+
+ def handle_tool_calls(response_data, tools, model, stream, &)
LiteLLM.logger.debug "Handling tool calls, stream=#{stream}"
begin
@@ -160,7 +186,7 @@ def handle_tool_calls(response_data, tools, model, stream, &block)
LiteLLM.logger.debug "Tool handler generated messages: #{@messages.inspect}"
- completion(messages: @messages, model: model, tools: tools, stream: stream, &block)
+ completion(messages: @messages, model: model, tools: tools, stream: stream, &)
rescue StandardError => e
LiteLLM.logger.error "Error in handle_tool_calls: #{e.message}\n#{e.backtrace.join("\n")}"
raise
diff --git a/lib/litellm/configuration.rb b/lib/litellm/configuration.rb
index dcc4e12..d2297ef 100644
--- a/lib/litellm/configuration.rb
+++ b/lib/litellm/configuration.rb
@@ -32,8 +32,7 @@ def logger
end
class Configuration
- attr_reader :base_url, :timeout, :model, :embedding_model, :image_model, :embedding_dimensions,
- :debug, :logger, :enable_message_redaction, :api_key
+ attr_reader :base_url, :timeout, :model, :embedding_model, :image_model, :embedding_dimensions, :debug, :logger, :enable_message_redaction, :api_key
def initialize
@base_url = DEFAULTS[:base_url]
diff --git a/lib/litellm/errors.rb b/lib/litellm/errors.rb
index dab3f73..71c5ba2 100644
--- a/lib/litellm/errors.rb
+++ b/lib/litellm/errors.rb
@@ -79,8 +79,6 @@ def self.handle_tool_error(message, original_error = nil)
raise error
end
- private
-
def self.parse_json(body)
JSON.parse(body)
rescue JSON::ParserError => e
diff --git a/lib/litellm/tool_handler.rb b/lib/litellm/tool_handler.rb
index ef5017f..c342c47 100644
--- a/lib/litellm/tool_handler.rb
+++ b/lib/litellm/tool_handler.rb
@@ -11,7 +11,7 @@ def self.call(response:, available_tools: [])
# Build a mapping of function names to tools
@available_tools = {}
available_tools.each do |tool|
- tool.class.function_definitions.each do |function_name, definition|
+ tool.class.function_definitions.each do |_function_name, definition|
@available_tools[definition[:name]] = tool
end
end
@@ -28,8 +28,6 @@ def self.call(response:, available_tools: [])
messages
end
- private
-
def self.execute_tool_calls(tool_calls)
tool_calls.map do |tool_call|
function_name = tool_call.dig("function", "name")
diff --git a/lib/litellm/utils/tool_definition.rb b/lib/litellm/utils/tool_definition.rb
index 5237187..9b9beaf 100644
--- a/lib/litellm/utils/tool_definition.rb
+++ b/lib/litellm/utils/tool_definition.rb
@@ -28,11 +28,11 @@ def normalized_tool_name
private
- def build_parameters(&block)
+ def build_parameters(&)
return nil unless block_given?
builder = ParameterBuilder.new
- schema = builder.build(&block)
+ schema = builder.build(&)
{
type: "object",
@@ -101,8 +101,8 @@ def initialize
@required = []
end
- def build(&block)
- instance_eval(&block)
+ def build(&)
+ instance_eval(&)
{ properties: @properties, required: @required }
end
diff --git a/spec/Rakefile b/spec/Rakefile
new file mode 100644
index 0000000..5f25233
--- /dev/null
+++ b/spec/Rakefile
@@ -0,0 +1,14 @@
+require "fileutils"
+
+namespace :vcr do
+ desc "Delete all VCR cassettes"
+ task :reset do
+ cassette_dir = "spec/fixtures/vcr_cassettes"
+ if File.directory?(cassette_dir)
+ FileUtils.rm_rf(Dir.glob("#{cassette_dir}/*"))
+ puts "All VCR cassettes have been deleted from #{cassette_dir}"
+ else
+ puts "No VCR cassettes directory found at #{cassette_dir}"
+ end
+ end
+end
diff --git a/spec/fixtures/vcr_cassettes/client_basic_chat_functionality_can_handle_multi-turn_conversations.yml b/spec/fixtures/vcr_cassettes/client_basic_chat_functionality_can_handle_multi-turn_conversations.yml
new file mode 100644
index 0000000..4c0b9b9
--- /dev/null
+++ b/spec/fixtures/vcr_cassettes/client_basic_chat_functionality_can_handle_multi-turn_conversations.yml
@@ -0,0 +1,115 @@
+---
+http_interactions:
+- request:
+ method: post
+ uri: http://localhost:8000/chat/completions
+ body:
+ encoding: UTF-8
+ string: '{"messages":[{"role":"user","content":"Who was Ruby''s creator?"},{"role":"assistant","content":"Yukihiro
+ Matsumoto (Matz)"},{"role":"user","content":"What year did he create Ruby?"}],"model":"gpt-3.5-turbo","stream":false}'
+ headers:
+ X-Litellm-Timeout:
+ - '120'
+ User-Agent:
+ - Faraday v2.12.2
+ X-Request-Id:
+ - f8e0cda5-7755-42b3-a5cb-9f7921516e95
+ Content-Type:
+ - application/json
+ Accept-Encoding:
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
+ Accept:
+ - "*/*"
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Date:
+ - Sun, 06 Apr 2025 06:32:42 GMT
+ Server:
+ - uvicorn
+ Content-Length:
+ - '638'
+ Content-Type:
+ - application/json
+ X-Litellm-Call-Id:
+ - e1dcddbc-c06e-435d-958c-7bf7d402f8c2
+ X-Litellm-Model-Id:
+ - a894f5c6235fa10c0c1755367a3bb2ad54a34654ed3da22bee9da260609709f7
+ X-Litellm-Model-Api-Base:
+ - https://api.openai.com/v1
+ X-Litellm-Version:
+ - 1.61.9
+ X-Litellm-Response-Cost:
+ - '3.9999999999999996e-05'
+ X-Litellm-Key-Spend:
+ - '0.0'
+ X-Litellm-Response-Duration-Ms:
+ - '587.4979999999999'
+ X-Litellm-Overhead-Duration-Ms:
+ - '3.082'
+ X-Ratelimit-Limit-Requests:
+ - '5000'
+ X-Ratelimit-Remaining-Requests:
+ - '4999'
+ X-Ratelimit-Limit-Tokens:
+ - '2000000'
+ X-Ratelimit-Remaining-Tokens:
+ - '1999976'
+ Llm-Provider-Date:
+ - Sun, 06 Apr 2025 06:32:43 GMT
+ Llm-Provider-Content-Type:
+ - application/json
+ Llm-Provider-Transfer-Encoding:
+ - chunked
+ Llm-Provider-Connection:
+ - keep-alive
+ Llm-Provider-Access-Control-Expose-Headers:
+ - X-Request-ID
+ Llm-Provider-Openai-Organization:
+ - user-s7l904mmsyaeoqfhuynmxjmp
+ Llm-Provider-Openai-Processing-Ms:
+ - '256'
+ Llm-Provider-Openai-Version:
+ - '2020-10-01'
+ Llm-Provider-X-Ratelimit-Limit-Requests:
+ - '5000'
+ Llm-Provider-X-Ratelimit-Limit-Tokens:
+ - '2000000'
+ Llm-Provider-X-Ratelimit-Remaining-Requests:
+ - '4999'
+ Llm-Provider-X-Ratelimit-Remaining-Tokens:
+ - '1999976'
+ Llm-Provider-X-Ratelimit-Reset-Requests:
+ - 12ms
+ Llm-Provider-X-Ratelimit-Reset-Tokens:
+ - 0s
+ Llm-Provider-X-Request-Id:
+ - req_c2166dd745242d7e4f4398d124752c5c
+ Llm-Provider-Strict-Transport-Security:
+ - max-age=31536000; includeSubDomains; preload
+ Llm-Provider-Cf-Cache-Status:
+ - DYNAMIC
+ Llm-Provider-X-Content-Type-Options:
+ - nosniff
+ Llm-Provider-Server:
+ - cloudflare
+ Llm-Provider-Cf-Ray:
+ - 92bf3fe41b93f9cd-MCT
+ Llm-Provider-Content-Encoding:
+ - gzip
+ Llm-Provider-Alt-Svc:
+ - h3=":443"; ma=86400
+ X-Litellm-Model-Group:
+ - gpt-3.5-turbo
+ X-Litellm-Attempted-Retries:
+ - '0'
+ X-Litellm-Attempted-Fallbacks:
+ - '0'
+ body:
+ encoding: UTF-8
+ string: '{"id":"chatcmpl-BJDqdLFkNAUOCWH0hZUcd7zZHre0h","created":1743921163,"model":"gpt-3.5-turbo-0125","object":"chat.completion","system_fingerprint":null,"choices":[{"finish_reason":"stop","index":0,"message":{"content":"Yukihiro
+ Matsumoto created Ruby in 1995.","role":"assistant","tool_calls":null,"function_call":null,"refusal":null,"annotations":[]}}],"usage":{"completion_tokens":14,"prompt_tokens":38,"total_tokens":52,"completion_tokens_details":{"accepted_prediction_tokens":0,"audio_tokens":0,"reasoning_tokens":0,"rejected_prediction_tokens":0},"prompt_tokens_details":{"audio_tokens":0,"cached_tokens":0}},"service_tier":"default"}'
+ recorded_at: Sun, 06 Apr 2025 06:32:43 GMT
+recorded_with: VCR 6.3.1
diff --git a/spec/fixtures/vcr_cassettes/client_basic_chat_functionality_can_have_a_basic_conversation.yml b/spec/fixtures/vcr_cassettes/client_basic_chat_functionality_can_have_a_basic_conversation.yml
new file mode 100644
index 0000000..4613f79
--- /dev/null
+++ b/spec/fixtures/vcr_cassettes/client_basic_chat_functionality_can_have_a_basic_conversation.yml
@@ -0,0 +1,119 @@
+---
+http_interactions:
+- request:
+ method: post
+ uri: http://localhost:8000/chat/completions
+ body:
+ encoding: UTF-8
+ string: '{"messages":[{"role":"user","content":"What''s 2 + 2?"}],"model":"gpt-3.5-turbo","stream":false}'
+ headers:
+ X-Litellm-Timeout:
+ - '120'
+ User-Agent:
+ - Faraday v2.12.2
+ X-Request-Id:
+ - 7691928f-4110-44df-b3be-17042df55a89
+ Content-Type:
+ - application/json
+ Accept-Encoding:
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
+ Accept:
+ - "*/*"
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Date:
+ - Sun, 06 Apr 2025 06:32:40 GMT
+ Server:
+ - uvicorn
+ Content-Length:
+ - '612'
+ Content-Type:
+ - application/json
+ X-Litellm-Call-Id:
+ - 2a9764e3-400c-41f2-9be3-7b01d3ae1b3e
+ X-Litellm-Model-Id:
+ - a894f5c6235fa10c0c1755367a3bb2ad54a34654ed3da22bee9da260609709f7
+ X-Litellm-Model-Api-Base:
+ - https://api.openai.com/v1
+ X-Litellm-Version:
+ - 1.61.9
+ X-Litellm-Response-Cost:
+ - '2.1e-05'
+ X-Litellm-Key-Spend:
+ - '0.0'
+ X-Litellm-Response-Duration-Ms:
+ - '1605.4060000000002'
+ X-Litellm-Overhead-Duration-Ms:
+ - '25.89'
+ X-Ratelimit-Limit-Requests:
+ - '5000'
+ X-Ratelimit-Remaining-Requests:
+ - '4999'
+ X-Ratelimit-Limit-Tokens:
+ - '2000000'
+ X-Ratelimit-Remaining-Tokens:
+ - '1999994'
+ Llm-Provider-Date:
+ - Sun, 06 Apr 2025 06:32:42 GMT
+ Llm-Provider-Content-Type:
+ - application/json
+ Llm-Provider-Transfer-Encoding:
+ - chunked
+ Llm-Provider-Connection:
+ - keep-alive
+ Llm-Provider-Access-Control-Expose-Headers:
+ - X-Request-ID
+ Llm-Provider-Openai-Organization:
+ - user-s7l904mmsyaeoqfhuynmxjmp
+ Llm-Provider-Openai-Processing-Ms:
+ - '242'
+ Llm-Provider-Openai-Version:
+ - '2020-10-01'
+ Llm-Provider-X-Ratelimit-Limit-Requests:
+ - '5000'
+ Llm-Provider-X-Ratelimit-Limit-Tokens:
+ - '2000000'
+ Llm-Provider-X-Ratelimit-Remaining-Requests:
+ - '4999'
+ Llm-Provider-X-Ratelimit-Remaining-Tokens:
+ - '1999994'
+ Llm-Provider-X-Ratelimit-Reset-Requests:
+ - 12ms
+ Llm-Provider-X-Ratelimit-Reset-Tokens:
+ - 0s
+ Llm-Provider-X-Request-Id:
+ - req_e237c8496b923623d03975a657b750e2
+ Llm-Provider-Strict-Transport-Security:
+ - max-age=31536000; includeSubDomains; preload
+ Llm-Provider-Cf-Cache-Status:
+ - DYNAMIC
+ Llm-Provider-Set-Cookie:
+ - __cf_bm=a7CYAzbs4uuFYWCAK4g8o8noSxY8SNunLrsMfrzpXNA-1743921162-1.0.1.1-AgTkrWj.4i2dDH8C.ngpDiu80YidnfuFJ5O_sl.Fh4zDLERPz0HBrjhwKGXEB6XFZmKlj0MmFNOQrHB7pij6LwTdbYQJ_eM9lp7cc5kmTOU;
+ path=/; expires=Sun, 06-Apr-25 07:02:42 GMT; domain=.api.openai.com; HttpOnly;
+ Secure; SameSite=None, _cfuvid=XBwh4kk.PnKz5mo7.vGNCpRSAB2MvTm_bXdVTHSROWU-1743921162814-0.0.1.1-604800000;
+ path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None
+ Llm-Provider-X-Content-Type-Options:
+ - nosniff
+ Llm-Provider-Server:
+ - cloudflare
+ Llm-Provider-Cf-Ray:
+ - 92bf3fda7e97f9cd-MCT
+ Llm-Provider-Content-Encoding:
+ - gzip
+ Llm-Provider-Alt-Svc:
+ - h3=":443"; ma=86400
+ X-Litellm-Model-Group:
+ - gpt-3.5-turbo
+ X-Litellm-Attempted-Retries:
+ - '0'
+ X-Litellm-Attempted-Fallbacks:
+ - '0'
+ body:
+ encoding: UTF-8
+ string: '{"id":"chatcmpl-BJDqcIL5W8QB1ACkd6X3Hklp1YYbQ","created":1743921162,"model":"gpt-3.5-turbo-0125","object":"chat.completion","system_fingerprint":null,"choices":[{"finish_reason":"stop","index":0,"message":{"content":"2
+ + 2 equals 4.","role":"assistant","tool_calls":null,"function_call":null,"refusal":null,"annotations":[]}}],"usage":{"completion_tokens":9,"prompt_tokens":15,"total_tokens":24,"completion_tokens_details":{"accepted_prediction_tokens":0,"audio_tokens":0,"reasoning_tokens":0,"rejected_prediction_tokens":0},"prompt_tokens_details":{"audio_tokens":0,"cached_tokens":0}},"service_tier":"default"}'
+ recorded_at: Sun, 06 Apr 2025 06:32:42 GMT
+recorded_with: VCR 6.3.1
diff --git a/spec/fixtures/vcr_cassettes/client_basic_chat_functionality_successfully_uses_the_system_prompt.yml b/spec/fixtures/vcr_cassettes/client_basic_chat_functionality_successfully_uses_the_system_prompt.yml
new file mode 100644
index 0000000..47432c5
--- /dev/null
+++ b/spec/fixtures/vcr_cassettes/client_basic_chat_functionality_successfully_uses_the_system_prompt.yml
@@ -0,0 +1,118 @@
+---
+http_interactions:
+- request:
+ method: post
+ uri: http://localhost:8000/chat/completions
+ body:
+ encoding: UTF-8
+ string: '{"messages":[{"role":"system","content":"You must respond like a pirate
+ and include the phrase \"Arrr matey!\" in your response."},{"role":"user","content":"Tell
+ me about the weather."}],"model":"gpt-3.5-turbo","stream":false}'
+ headers:
+ X-Litellm-Timeout:
+ - '120'
+ User-Agent:
+ - Faraday v2.12.2
+ X-Request-Id:
+ - 502ee239-97b9-4126-91c4-3d183374b0b0
+ Content-Type:
+ - application/json
+ Accept-Encoding:
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
+ Accept:
+ - "*/*"
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Date:
+ - Sun, 06 Apr 2025 06:32:43 GMT
+ Server:
+ - uvicorn
+ Content-Length:
+ - '797'
+ Content-Type:
+ - application/json
+ X-Litellm-Call-Id:
+ - efb02880-dfc7-4640-b841-f9c4f1808616
+ X-Litellm-Model-Id:
+ - a894f5c6235fa10c0c1755367a3bb2ad54a34654ed3da22bee9da260609709f7
+ X-Litellm-Model-Api-Base:
+ - https://api.openai.com/v1
+ X-Litellm-Version:
+ - 1.61.9
+ X-Litellm-Response-Cost:
+ - '9.800000000000001e-05'
+ X-Litellm-Key-Spend:
+ - '0.0'
+ X-Litellm-Response-Duration-Ms:
+ - '966.668'
+ X-Litellm-Overhead-Duration-Ms:
+ - '3.231'
+ X-Ratelimit-Limit-Requests:
+ - '5000'
+ X-Ratelimit-Remaining-Requests:
+ - '4999'
+ X-Ratelimit-Limit-Tokens:
+ - '2000000'
+ X-Ratelimit-Remaining-Tokens:
+ - '1999969'
+ Llm-Provider-Date:
+ - Sun, 06 Apr 2025 06:32:44 GMT
+ Llm-Provider-Content-Type:
+ - application/json
+ Llm-Provider-Transfer-Encoding:
+ - chunked
+ Llm-Provider-Connection:
+ - keep-alive
+ Llm-Provider-Access-Control-Expose-Headers:
+ - X-Request-ID
+ Llm-Provider-Openai-Organization:
+ - user-s7l904mmsyaeoqfhuynmxjmp
+ Llm-Provider-Openai-Processing-Ms:
+ - '583'
+ Llm-Provider-Openai-Version:
+ - '2020-10-01'
+ Llm-Provider-X-Ratelimit-Limit-Requests:
+ - '5000'
+ Llm-Provider-X-Ratelimit-Limit-Tokens:
+ - '2000000'
+ Llm-Provider-X-Ratelimit-Remaining-Requests:
+ - '4999'
+ Llm-Provider-X-Ratelimit-Remaining-Tokens:
+ - '1999969'
+ Llm-Provider-X-Ratelimit-Reset-Requests:
+ - 12ms
+ Llm-Provider-X-Ratelimit-Reset-Tokens:
+ - 0s
+ Llm-Provider-X-Request-Id:
+ - req_5a06eaea2c8d2ee5297a43a772861267
+ Llm-Provider-Strict-Transport-Security:
+ - max-age=31536000; includeSubDomains; preload
+ Llm-Provider-Cf-Cache-Status:
+ - DYNAMIC
+ Llm-Provider-X-Content-Type-Options:
+ - nosniff
+ Llm-Provider-Server:
+ - cloudflare
+ Llm-Provider-Cf-Ray:
+ - 92bf3fe81997f9cd-MCT
+ Llm-Provider-Content-Encoding:
+ - gzip
+ Llm-Provider-Alt-Svc:
+ - h3=":443"; ma=86400
+ X-Litellm-Model-Group:
+ - gpt-3.5-turbo
+ X-Litellm-Attempted-Retries:
+ - '0'
+ X-Litellm-Attempted-Fallbacks:
+ - '0'
+ body:
+ encoding: UTF-8
+ string: '{"id":"chatcmpl-BJDqdTtckhrdLSpolnIyA1vmBNu6x","created":1743921163,"model":"gpt-3.5-turbo-0125","object":"chat.completion","system_fingerprint":null,"choices":[{"finish_reason":"stop","index":0,"message":{"content":"Arrr
+ matey! The weather be fair with a bit o'' sunshine and a gentle breeze. But
+ keep a weather eye open, for ye never know when a storm be brewin'' on the
+ horizon. Best be stayin'' prepared, me hearty!","role":"assistant","tool_calls":null,"function_call":null,"refusal":null,"annotations":[]}}],"usage":{"completion_tokens":53,"prompt_tokens":37,"total_tokens":90,"completion_tokens_details":{"accepted_prediction_tokens":0,"audio_tokens":0,"reasoning_tokens":0,"rejected_prediction_tokens":0},"prompt_tokens_details":{"audio_tokens":0,"cached_tokens":0}},"service_tier":"default"}'
+ recorded_at: Sun, 06 Apr 2025 06:32:44 GMT
+recorded_with: VCR 6.3.1
diff --git a/spec/fixtures/vcr_cassettes/client_embedding_generation_generates_embeddings_for_text_input.yml b/spec/fixtures/vcr_cassettes/client_embedding_generation_generates_embeddings_for_text_input.yml
new file mode 100644
index 0000000..60c442d
--- /dev/null
+++ b/spec/fixtures/vcr_cassettes/client_embedding_generation_generates_embeddings_for_text_input.yml
@@ -0,0 +1,126 @@
+---
+http_interactions:
+- request:
+ method: post
+ uri: http://localhost:8000/embeddings
+ body:
+ encoding: UTF-8
+ string: '{"input":"Hello, world!","model":"text-embedding-3-small","dimensions":1536}'
+ headers:
+ X-Litellm-Timeout:
+ - '120'
+ User-Agent:
+ - Faraday v2.12.2
+ X-Request-Id:
+ - 4e7549ba-beae-4059-b6e0-19e8bfb91338
+ Content-Type:
+ - application/json
+ Accept-Encoding:
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
+ Accept:
+ - "*/*"
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Date:
+ - Sun, 06 Apr 2025 06:32:48 GMT
+ Server:
+ - uvicorn
+ Content-Length:
+ - '32918'
+ Content-Type:
+ - application/json
+ X-Litellm-Call-Id:
+ - 276fca61-3053-4b43-9025-7378167b40a2
+ X-Litellm-Model-Id:
+ - 4a7f0868c5473e06a5f20ae08390f921cbf173866984f81d99f3a3501adf13e2
+ X-Litellm-Model-Api-Base:
+ - https://api.openai.com/v1
+ X-Litellm-Version:
+ - 1.61.9
+ X-Litellm-Response-Cost:
+ - 8e-08
+ X-Litellm-Key-Spend:
+ - '0.0'
+ X-Litellm-Response-Duration-Ms:
+ - '881.2449999999999'
+ X-Litellm-Overhead-Duration-Ms:
+ - '3.876'
+ X-Ratelimit-Limit-Requests:
+ - '5000'
+ X-Ratelimit-Remaining-Requests:
+ - '4999'
+ X-Ratelimit-Limit-Tokens:
+ - '1000000'
+ X-Ratelimit-Remaining-Tokens:
+ - '999997'
+ Llm-Provider-Date:
+ - Sun, 06 Apr 2025 06:32:50 GMT
+ Llm-Provider-Content-Type:
+ - application/json
+ Llm-Provider-Transfer-Encoding:
+ - chunked
+ Llm-Provider-Connection:
+ - keep-alive
+ Llm-Provider-Access-Control-Allow-Origin:
+ - "*"
+ Llm-Provider-Access-Control-Expose-Headers:
+ - X-Request-ID
+ Llm-Provider-Openai-Model:
+ - text-embedding-3-small
+ Llm-Provider-Openai-Organization:
+ - user-s7l904mmsyaeoqfhuynmxjmp
+ Llm-Provider-Openai-Processing-Ms:
+ - '64'
+ Llm-Provider-Openai-Version:
+ - '2020-10-01'
+ Llm-Provider-Strict-Transport-Security:
+ - max-age=31536000; includeSubDomains; preload
+ Llm-Provider-Via:
+ - envoy-router-868dc8d978-28dcm
+ Llm-Provider-X-Envoy-Upstream-Service-Time:
+ - '34'
+ Llm-Provider-X-Ratelimit-Limit-Requests:
+ - '5000'
+ Llm-Provider-X-Ratelimit-Limit-Tokens:
+ - '1000000'
+ Llm-Provider-X-Ratelimit-Remaining-Requests:
+ - '4999'
+ Llm-Provider-X-Ratelimit-Remaining-Tokens:
+ - '999997'
+ Llm-Provider-X-Ratelimit-Reset-Requests:
+ - 12ms
+ Llm-Provider-X-Ratelimit-Reset-Tokens:
+ - 0s
+ Llm-Provider-X-Request-Id:
+ - req_e6b770cf9af00804c6668f143f09df39
+ Llm-Provider-Cf-Cache-Status:
+ - DYNAMIC
+ Llm-Provider-Set-Cookie:
+ - __cf_bm=Fh5Uf9vcOJ9RL5IQ1UJjmiF3tJ6dykToGy7EJmiKtrs-1743921170-1.0.1.1-gi5W2I.sjW2_QWG8ilI0_leIXLO6i1N2Peq76NuI.YSM3FocxAGXm82CfGIwpkBKR9JeOUFyP.5dJn93uT3__bE09pHTxwDdT_HkzCRG5rw;
+ path=/; expires=Sun, 06-Apr-25 07:02:50 GMT; domain=.api.openai.com; HttpOnly;
+ Secure; SameSite=None, _cfuvid=_i6IM7dUspv6Y1Ry0Yz3eCbETZJ3eXFTjDAgfSHBj2M-1743921170124-0.0.1.1-604800000;
+ path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None
+ Llm-Provider-X-Content-Type-Options:
+ - nosniff
+ Llm-Provider-Server:
+ - cloudflare
+ Llm-Provider-Cf-Ray:
+ - 92bf400cbb05f9f8-MCT
+ Llm-Provider-Content-Encoding:
+ - gzip
+ Llm-Provider-Alt-Svc:
+ - h3=":443"; ma=86400
+ X-Litellm-Model-Group:
+ - text-embedding-3-small
+ X-Litellm-Attempted-Retries:
+ - '0'
+ X-Litellm-Attempted-Fallbacks:
+ - '0'
+ body:
+ encoding: UTF-8
+ string: '{"model":"text-embedding-3-small","data":[{"embedding":[-0.019184619188308716,-0.025279032066464424,-0.0017195191467180848,0.01884828321635723,-0.033795066177845,-0.01969585195183754,-0.02094702236354351,0.051580529659986496,-0.03212684020400047,-0.030377890914678574,-0.002145825419574976,-0.028978731483221054,-0.0024737531784921885,-0.031481072306632996,0.010332250036299229,0.018606122583150864,-0.04614533483982086,0.04146353527903557,0.0004418617463670671,0.04122137278318405,0.05367926508188248,0.0018733929609879851,0.0045674461871385574,0.010022819973528385,0.04786737635731697,0.0022013208363205194,-0.009834472090005875,0.03847686946392059,0.00089213193859905,-0.05211866647005081,0.051150016486644745,-0.032557349652051926,-0.014031948521733284,-0.012632790021598339,0.013271828182041645,0.018565760925412178,0.0016068464610725641,-0.0008185583865270019,-0.012753871269524097,-0.029705218970775604,-0.004443001933395863,-0.015323479659855366,0.025655729696154594,0.009107985533773899,-0.03686245530843735,0.020328164100646973,-0.04071014001965523,-0.002621741034090519,0.03549019992351532,0.04851314052939415,-0.03368743881583214,-0.002441801130771637,0.017260776832699776,0.07598508894443512,0.0009232430020347238,-0.04267434403300285,0.008381499908864498,0.0760388970375061,-0.047275424003601074,0.015081318095326424,0.014247204177081585,0.024700535461306572,0.010197714902460575,-0.000978738535195589,0.013789786025881767,-0.010103541426360607,-0.020704859867691994,-0.001531170797534287,-0.011717955581843853,0.04934725537896156,0.0010939337080344558,0.037831101566553116,-0.019332608208060265,0.005855614319443703,-0.046279869973659515,-0.0045439028181135654,-0.022359633818268776,0.008751469664275646,-0.02657056413590908,-0.05440575256943703,-0.04423494264483452,0.019332608208060265,-0.03091602772474289,-0.06037908419966698,-0.018888644874095917,0.004372371360659599,-0.02389332838356495,-0.012027384713292122,-0.016601556912064552,0.0022013208363205194,-0.00802498310804367,0.01529657281935215,-0.014960236847400665,0.01245789509266615,0.014502819627523422,-0.027687201276421547,-0.022790145128965378,0.05666593089699745,0.061024848371744156,-0.04929343983530998,0.014610446989536285,-0.027323957532644272,0.013251648284494877,-0.0205434188246727,0.0298666600137949,0.022507622838020325,0.00819987803697586,-0.04068323224782944,-0.026584018021821976,0.004533812869340181,-0.12474039196968079,0.009417415596544743,0.031803958117961884,-0.031077470630407333,0.005801800638437271,0.030835308134555817,0.05367926508188248,-0.039553143084049225,0.02342245727777481,-0.05375998839735985,0.00868420209735632,-0.01152287982404232,0.019534409046173096,-0.04184022918343544,-0.043131761252880096,-0.04297031834721565,0.005852250847965479,0.057526953518390656,-0.031481072306632996,0.019911106675863266,0.03944551572203636,0.03982221335172653,0.01127399131655693,-0.0002850449818652123,-0.045553382486104965,0.0018666662508621812,-0.040656328201293945,-0.013446723110973835,-0.049105092883110046,0.047275424003601074,0.056450676172971725,-0.047248516231775284,-0.010890567675232887,-0.00996228028088808,-0.005926244892179966,-0.04119446501135826,-0.008791829459369183,0.026086239144206047,-0.009948826394975185,-0.00625585438683629,0.030377890914678574,0.060648154467344284,-0.051230739802122116,0.025776810944080353,0.00377705623395741,-0.002621741034090519,0.024512186646461487,-0.016816813498735428,-0.02782173454761505,0.015054411254823208,0.05510533228516579,0.039580050855875015,-0.04436947777867317,-0.007897174917161465,-0.008146064355969429,0.00850930716842413,-0.011744862422347069,0.002426665974780917,-0.04361608624458313,-0.002248407807201147,0.023974047973752022,0.020933568477630615,-0.0211219172924757,-0.04509596526622772,-0.0192249808460474,0.02634185552597046,0.023449363186955452,-0.04958941787481308,-0.01622486114501953,-0.025238672271370888,0.02852131426334381,0.04541884735226631,0.0022921315394341946,0.019090445712208748,-0.026584018021821976,-0.011179816909134388,-0.004473272245377302,-0.006804082542657852,-0.011913030408322811,0.0008563962182961404,-0.03298785910010338,0.056235421448946,0.023476270958781242,0.0019675670191645622,0.004510269034653902,-0.03659338504076004,0.0669981837272644,0.00536792678758502,-0.021565880626440048,0.02427002415060997,-0.00038993984344415367,0.012706783600151539,-0.05136527121067047,-0.031884677708148956,-0.02342245727777481,-0.04186713695526123,-0.000014254876077757217,0.07087277621030807,-0.00837477296590805,-0.05246845632791519,0.058603230863809586,-0.014677714556455612,-0.0541904978454113,-0.0020482877735048532,-0.04932034760713577,-0.017879635095596313,0.041275184601545334,0.02229236625134945,-0.011226904578506947,-0.03161560744047165,-0.07937535643577576,0.07157235592603683,0.08513343334197998,-0.04122137278318405,0.030889121815562248,-0.013339095748960972,-0.008536214008927345,-0.008213330991566181,0.04996611550450325,0.01458354014903307,0.020879754796624184,0.01826978474855423,0.02429693192243576,-0.021431345492601395,-0.010500418022274971,-0.004325284156948328,0.036727920174598694,-0.021350625902414322,-0.005657176021486521,-0.0071572354063391685,-0.0387459360063076,-0.0011199996806681156,-0.006037235725671053,0.034252483397722244,0.04563410207629204,-0.016103779897093773,-0.042728159576654434,-0.022413447499275208,0.011119276285171509,0.04076395556330681,0.017960356548428535,0.02724323607981205,0.005418376997113228,-0.02036852389574051,0.017166603356599808,-0.01021116878837347,0.006659457925707102,-0.027458492666482925,0.042728159576654434,-0.02106810361146927,-0.048728395253419876,-0.062101125717163086,-0.035301852971315384,-0.02779482863843441,0.012632790021598339,-0.027404678985476494,0.004089849069714546,-0.013897414319217205,-0.016615010797977448,-0.013164200820028782,0.04385824874043465,-0.0075810193084180355,0.03266497701406479,-0.004355554468929768,-0.025803716853260994,0.0032876869663596153,-0.005179578438401222,-0.017328044399619102,-0.01981693133711815,0.0369969867169857,-0.025763357058167458,-0.0014664260670542717,0.010513870976865292,0.033983416855335236,-0.05131145939230919,0.008832190185785294,0.027081795036792755,-0.01144888624548912,0.007722280453890562,-0.02479470893740654,0.03277260437607765,0.02774101495742798,0.016278674826025963,-0.02039542980492115,0.025911344215273857,-0.002879038453102112,-0.0013175972271710634,-0.041651882231235504,0.038153983652591705,0.0025460654869675636,0.07695373892784119,0.0007592791225761175,0.04294341430068016,-0.005845523905009031,-0.001709428965114057,0.04154425486922264,0.015901979058980942,-0.01701861433684826,0.05951806530356407,-0.0013714110245928168,-0.008959997445344925,0.009585583582520485,0.05666593089699745,-0.02784864231944084,0.01347362995147705,-0.045849356800317764,0.019857292994856834,-0.019332608208060265,0.0009694892796687782,-0.04003746807575226,0.023449363186955452,-0.06199349835515022,0.009477955289185047,-0.015713630244135857,-0.015162038616836071,-0.00862366147339344,0.045553382486104965,0.021538974717259407,0.0020180174615234137,0.013756153173744678,0.014664260670542717,-0.02706834115087986,-0.004664984066039324,0.010830027051270008,0.007224502973258495,-0.016951346769928932,-0.04372371360659599,0.05427121743559837,0.012767324224114418,0.04579554498195648,-0.02657056413590908,-0.027902456000447273,0.02179458923637867,-0.03651266545057297,-0.011987023986876011,-0.0041941129602491856,0.033929601311683655,-0.02712215483188629,0.004288287367671728,0.004399278201162815,-0.017381858080625534,-0.005243482068181038,0.016413209959864616,-0.02464671991765499,-0.01762402057647705,-0.009868105873465538,0.0716799795627594,-0.024727441370487213,-0.019534409046173096,0.021256450563669205,-0.006609007250517607,-0.006915073376148939,0.00413020933046937,-0.01210810523480177,0.03384888172149658,0.030431704595685005,-0.007258136291056871,-0.04081776738166809,-0.007345583755522966,0.04385824874043465,0.013298735953867435,0.01475843507796526,0.032153744250535965,-0.0036324316170066595,-0.03479062393307686,-0.015175491571426392,0.0117986761033535,-0.00017373869195580482,0.059625692665576935,-0.009249246679246426,0.04036035016179085,0.03371434658765793,-0.019736211746931076,-0.026610923931002617,0.010325523093342781,-0.005855614319443703,0.0206914059817791,0.011381618678569794,-0.01701861433684826,0.008576574735343456,0.03352599963545799,-0.011563240550458431,0.004426185041666031,0.00951158907264471,0.007809727918356657,-0.01757020689547062,-0.021808043122291565,-0.015188945457339287,-0.022682517766952515,-0.05763458088040352,0.04716779664158821,-0.023664619773626328,0.007527205627411604,0.011401799507439137,-0.02022053487598896,-0.03347218409180641,0.012229186482727528,0.05112311244010925,-0.0036391583271324635,-0.023503176867961884,0.004083122126758099,-0.052280109375715256,0.033956509083509445,0.03191158547997475,-0.025036871433258057,0.00199615559540689,-0.023261016234755516,-0.03928407281637192,-0.0007407806115224957,-0.0041201189160346985,0.00614150008186698,0.019036632031202316,-0.014153029769659042,0.025911344215273857,-0.032557349652051926,0.04006437584757805,0.03062005341053009,-0.028063897043466568,0.0187944695353508,-0.08260418474674225,-0.0015959155280143023,-0.03573236241936684,-0.00360216130502522,0.03624359518289566,0.02631494775414467,-0.04617224261164665,0.002162642078474164,-0.006302941590547562,0.058603230863809586,0.02322065457701683,-0.0025494287256151438,0.009013812057673931,0.008832190185785294,0.0022988582495599985,-0.009350148029625416,-0.05384070798754692,-0.003153152298182249,-0.013857053592801094,-0.040548697113990784,0.017812367528676987,0.0035248040221631527,-0.04358917847275734,0.013177654705941677,0.013978134840726852,0.03134653717279434,0.015175491571426392,-0.0002869368763640523,0.01687062717974186,0.01992456056177616,0.026449482887983322,-0.0039048639591783285,0.0231668408960104,-0.04773284122347832,0.052172478288412094,0.006410568952560425,-0.0035718909930437803,-0.02284395880997181,0.023328281939029694,-0.016305582597851753,-0.02229236625134945,-0.012525161728262901,0.025077231228351593,0.008226784877479076,-0.023758793249726295,-0.020314710214734077,-0.018202519044280052,-0.05445956811308861,0.01547146774828434,-0.044154223054647446,0.0001709008647594601,0.027525758370757103,0.007002520840615034,0.04143662750720978,0.02919398620724678,-0.003316275542601943,0.009773931466042995,-0.07211049646139145,0.026732005178928375,-0.004042761866003275,-0.010231348685920238,-0.034333206713199615,0.06193968653678894,0.0640922337770462,-0.015484921634197235,-0.009706663899123669,-0.008280598558485508,0.005670629441738129,-0.013251648284494877,-0.002973212394863367,-0.02879038266837597,-0.007143781986087561,-0.04157116264104843,-0.0066998181864619255,0.01987074688076973,0.06199349835515022,-0.006968887057155371,-0.04687182232737541,-0.014193389564752579,0.007399397436529398,-0.03374125435948372,-0.043481551110744476,-0.008139337413012981,0.007634832989424467,-0.005532731302082539,0.012087925337255001,-0.003134653903543949,0.009518316015601158,0.028252245858311653,-0.012000477872788906,-0.030835308134555817,0.026624377816915512,0.032557349652051926,-0.006575373932719231,-0.00798462238162756,-0.0033515908289700747,0.019386421889066696,-0.05160743370652199,-0.022104019299149513,0.008516034111380577,0.027875548228621483,0.019628584384918213,0.004991230089217424,0.028655849397182465,0.01359471119940281,-0.007782821077853441,-0.01109909638762474,-0.0005763962399214506,0.011953390203416348,-0.004738977644592524,-0.022790145128965378,0.007096694782376289,0.02948996238410473,-0.006481199525296688,-0.0007987986318767071,-0.011475793085992336,-0.00785008817911148,0.04687182232737541,0.006397115532308817,-0.002424984471872449,0.025157952681183815,0.00809897668659687,-0.016332488507032394,-0.013897414319217205,-0.012081198394298553,0.03387578949332237,0.0027613206766545773,-0.02149861305952072,-0.006656094454228878,0.015148584730923176,0.06586809456348419,0.004765884950757027,-0.010439877398312092,0.013762879185378551,0.027956269681453705,-0.00009002249862533063,0.03177705034613609,0.007190869189798832,-0.0212699044495821,-0.03772347420454025,-0.038530681282281876,-0.03616287559270859,-0.024014407768845558,-0.026032425463199615,-0.06387697905302048,0.021175730973482132,-0.007587745785713196,0.033929601311683655,0.026355309411883354,0.0013167564757168293,-0.004880239255726337,-0.004715434275567532,-0.0167495459318161,-0.0015866663306951523,0.029705218970775604,-0.04119446501135826,0.048755303025245667,0.02182149700820446,0.014368284493684769,0.024700535461306572,-0.032207559794187546,0.012188825756311417,0.003978857770562172,0.009249246679246426,0.04264743626117706,0.0012848045444115996,-0.0352480411529541,-0.018000716343522072,-0.02034161612391472,-0.029382335022091866,0.03702389448881149,0.011785222217440605,0.006400479003787041,-0.022238552570343018,-0.04845932871103287,0.027552666142582893,-0.014166482724249363,-0.01102510280907154,-0.0018464860040694475,0.0025527921970933676,-0.04958941787481308,-0.024956149980425835,0.03772347420454025,-0.021565880626440048,-0.05410977825522423,-0.004147026222199202,0.03053933195769787,-0.011354711838066578,0.011778495274484158,-0.015202398411929607,-0.021888762712478638,-0.008253691717982292,-0.042378369718790054,0.0026671465020626783,0.028225338086485863,-0.00250906846486032,0.016789905726909637,-0.018606122583150864,0.0023072666954249144,-0.02369152568280697,0.01987074688076973,0.012901858426630497,0.014960236847400665,0.0059800585731863976,-0.0016825221246108413,-0.006575373932719231,-0.005008046980947256,-0.008657295256853104,-0.01654774323105812,0.00396204087883234,-0.02334173582494259,0.04958941787481308,0.020852847024798393,0.0028454046696424484,-0.01757020689547062,0.05203794687986374,0.014260657131671906,0.013083480298519135,0.03137344494462013,0.009531769901514053,-0.013339095748960972,0.026705099269747734,0.004022581502795219,0.0033717709593474865,0.0017573569202795625,0.012908585369586945,-0.020489605143666267,-0.028117710724473,-0.01844467967748642,-0.021027741953730583,0.02234617993235588,-0.004634713754057884,0.07496262341737747,-0.016278674826025963,-0.006239037495106459,-0.009074351750314236,0.010049727745354176,0.019467143341898918,0.014193389564752579,-0.008072069846093655,-0.019561316817998886,0.00862366147339344,-0.014314470812678337,0.04251290112733841,0.0033566358033567667,0.03659338504076004,0.0019103899830952287,-0.030108822509646416,-0.007305223494768143,0.0018733929609879851,-0.024431465193629265,0.01335927564650774,0.006326484959572554,-0.04105992987751961,-0.03629740700125694,-0.0020953749772161245,0.028924917802214622,0.029785938560962677,0.01069549284875393,-0.003615614725276828,-0.0005154352984391153,-0.02922089397907257,-0.021808043122291565,-0.0036324316170066595,0.04243218153715134,-0.010480238124728203,-0.03156179562211037,0.022709423676133156,0.004443001933395863,-0.01286149863153696,-0.03826161101460457,0.024660173803567886,-0.011004921980202198,-0.006393752060830593,0.02114882320165634,0.026906900107860565,-0.023462817072868347,-0.024135489016771317,0.03446773812174797,0.028036991134285927,0.014341377653181553,-0.04700635373592377,0.005378016736358404,-0.02914017252624035,0.0093232411891222,-0.05881848558783531,-0.0029210804495960474,-0.029678311198949814,-0.060701966285705566,-0.006797355599701405,0.002322401851415634,-0.034306298941373825,0.0004843242058996111,-0.023651165887713432,0.01073585357517004,-0.021310264244675636,-0.035005878657102585,0.0028050444088876247,-0.01596924476325512,0.03126581758260727,0.018256332725286484,0.0285482220351696,-0.01844467967748642,0.013688885606825352,0.02581717073917389,0.0167495459318161,-0.0010073271114379168,-0.023826060816645622,-0.01404540240764618,0.015054411254823208,-0.01493333000689745,-0.022978492081165314,0.02494269609451294,0.04407350346446037,0.022938132286071777,-0.016655370593070984,0.012807684950530529,0.001075435196980834,0.001704383990727365,-0.016386302188038826,-0.00007651649502804503,0.011771769262850285,0.01046005729585886,-0.028575127944350243,-0.003598797833546996,0.004406005144119263,-0.012377174571156502,0.017704740166664124,-0.0015740536618977785,-0.017112787812948227,0.021565880626440048,-0.01887519098818302,0.030862214043736458,0.00434210104867816,0.05147290229797363,-0.020449243485927582,0.006454292684793472,0.011926483362913132,0.0012721918756142259,-0.001787627232261002,0.003323002252727747,0.04606461524963379,-0.003995674662292004,0.01133453194051981,0.0022013208363205194,0.0026419213972985744,0.0064273858442902565,-0.04157116264104843,0.022332727909088135,-0.042324554175138474,-0.018431227654218674,-0.006249127443879843,0.009444322437047958,-0.024108583107590675,-0.0015706903068348765,0.01404540240764618,-0.017812367528676987,0.0015967563958838582,0.011516153812408447,0.022211646661162376,-0.04229764640331268,-0.024175850674510002,-0.046279869973659515,-0.01168432179838419,0.005357836373150349,0.005263662431389093,0.044907618314027786,-0.01824287883937359,-0.032207559794187546,0.010641679167747498,0.003783782944083214,0.004570809658616781,-0.04751758649945259,0.02071831375360489,0.04009127989411354,0.004762521479278803,-0.026678191497921944,-0.014395191334187984,0.008838917128741741,0.006434112787246704,-0.008267145603895187,0.021525520831346512,0.03406413644552231,-0.012101378291845322,-0.012356993742287159,0.005690809339284897,-0.03982221335172653,0.006400479003787041,0.0035483473911881447,0.02304575964808464,-0.00011897894728463143,0.02071831375360489,0.008327685296535492,-0.018552307039499283,-0.014206843450665474,0.046898726373910904,0.0218484029173851,-0.023974047973752022,0.014287563972175121,0.03376815840601921,-0.003514713840559125,-0.018565760925412178,0.0023139934055507183,-0.006820899434387684,-0.006615734193474054,0.006568646989762783,0.02922089397907257,0.00862366147339344,-0.01687062717974186,-0.03522113338112831,-0.010668586008250713,0.0003584083169698715,-0.0030942936427891254,0.0010552549501881003,-0.0161710474640131,0.02601897343993187,-0.008072069846093655,0.021538974717259407,-0.02456600032746792,-0.0029093085322529078,0.012942219153046608,-0.043454643338918686,-0.012854771688580513,0.026207320392131805,-0.006733451969921589,-0.03209993243217468,0.016063420102000237,-0.026032425463199615,-0.012195552699267864,-0.002974894130602479,-0.01949404925107956,-0.005391470156610012,0.019655490294098854,0.018485041335225105,0.017139695584774017,0.033283837139606476,-0.014731528237462044,-0.0006108707166276872,-0.012377174571156502,0.0495356023311615,0.050100646913051605,0.0015606002416461706,-0.00031111104181036353,0.001344504184089601,-0.02948996238410473,0.020758673548698425,0.04474617540836334,-0.05475554242730141,0.02784864231944084,-0.006649367976933718,-0.007708827033638954,0.022790145128965378,0.04264743626117706,0.010338976047933102,0.006767085287719965,-0.036028340458869934,-0.026032425463199615,0.01494678296148777,0.02324756234884262,0.01347362995147705,0.008246964775025845,-0.014341377653181553,0.003151470795273781,-0.0016581377713009715,-0.00967303104698658,0.006259217858314514,-0.02124299854040146,-0.010675312951207161,0.027202876284718513,0.014879516325891018,0.009269427508115768,0.010675312951207161,-0.007937535643577576,0.02121609076857567,0.02779482863843441,0.018135251477360725,-0.007567565888166428,-0.0042714704759418964,-0.002071831375360489,-0.006245764438062906,0.0018363959388807416,-0.014650807715952396,-0.0521455742418766,0.02922089397907257,0.024485278874635696,0.047975003719329834,0.009081078693270683,0.015592548996210098,0.022238552570343018,-0.0061784968711435795,0.006121319718658924,-0.01894245855510235,-0.04353536665439606,-0.016937894746661186,0.0056975362822413445,-0.004089849069714546,-0.009121439419686794,-0.032853323966264725,0.0556434690952301,0.006935253739356995,-0.017435671761631966,0.029086358845233917,0.029624497517943382,-0.016036512330174446,0.01809488981962204,0.007897174917161465,-0.013453450053930283,-0.051580529659986496,0.030512424185872078,0.0027512304950505495,-0.031104376539587975,-0.03099674917757511,0.03879975154995918,0.0193729680031538,0.00539819709956646,0.06226256862282753,0.00551255140453577,0.017906542867422104,-0.004089849069714546,-0.015229305252432823,-0.0192249808460474,-0.023651165887713432,-0.002043242799118161,0.0007563361432403326,0.007587745785713196,-0.010830027051270008,0.008246964775025845,0.044127315282821655,-0.008919637650251389,-0.005472190678119659,0.012404081411659718,-0.01666882447898388,-0.016426661983132362,-0.02474089525640011,-0.012195552699267864,-0.0016488884575664997,-0.004607806913554668,-0.01870029605925083,-0.013830146752297878,0.009713390842080116,0.015632908791303635,-0.0273912250995636,0.0006550148827955127,0.03656647726893425,-0.01140852551907301,0.0023745340295135975,-0.017287682741880417,-0.035328760743141174,0.025884438306093216,0.04052179306745529,-0.006302941590547562,0.023624258115887642,0.02266906388103962,0.02584407851099968,-0.005145944654941559,-0.005293932743370533,0.001347026671282947,0.01459699310362339,0.006010328885167837,-0.016184501349925995,-0.014475912787020206,0.007305223494768143,-0.006706545129418373,-0.02092011459171772,0.03452155366539955,0.03976839780807495,-0.003048888174816966,-0.025938251987099648,-0.011354711838066578,-0.02129681222140789,-0.0167495459318161,0.0022753148805350065,0.01684371940791607,0.02414894290268421,-0.002409849315881729,0.0163190346211195,-0.0012705102562904358,-0.006528286729007959,0.006094412878155708,0.012955672107636929,-0.015727084130048752,0.030700773000717163,-0.003481080289930105,-0.014085762202739716,0.025857530534267426,0.026503296568989754,0.005149308126419783,-0.029086358845233917,0.04140971973538399,-0.004678437486290932,0.0144220981746912,-0.025951705873012543,-0.005445283837616444,0.005421740468591452,-0.009706663899123669,-0.007971169427037239,-0.018955910578370094,0.010769487358629704,-0.011213450692594051,-0.02919398620724678,0.027606479823589325,-0.018256332725286484,0.02114882320165634,-0.00399231119081378,0.0361359678208828,-0.00720432261005044,0.03137344494462013,-0.02589789219200611,-0.012067744508385658,-0.017731647938489914,-0.009471229277551174,-0.004722161218523979,-0.018377412110567093,-0.01338618341833353,0.02324756234884262,0.0035853444132953882,-0.004755794536322355,-0.03029716946184635,0.029032545164227486,0.0035449841525405645,-0.010628225281834602,-0.015942338854074478,0.029059452936053276,-0.00629285117611289,0.02421621046960354,0.022063657641410828,0.00978738535195589,0.010103541426360607,-0.0140588553622365,0.005495734512805939,0.02281705103814602,-0.054325032979249954,-0.029059452936053276,-0.02983975224196911,0.00378041947260499,0.016776451840996742,-0.028063897043466568,0.023287922143936157,0.003978857770562172,0.00819987803697586,0.03656647726893425,-0.01899627223610878,0.014502819627523422,-0.012787504121661186,0.033283837139606476,-0.009020538069307804,-0.018108343705534935,0.02992047369480133,-0.025938251987099648,0.016467023640871048,-0.011011648923158646,0.021808043122291565,-0.011038555763661861,0.023328281939029694,-0.031185097992420197,-0.03979530557990074,-0.031158190220594406,0.0022265459410846233,0.005660539027303457,0.029032545164227486,-0.014664260670542717,0.0030051644425839186,0.0048028817400336266,-0.026301495730876923,0.016480475664138794,-0.044477105140686035,0.018054530024528503,0.027081795036792755,0.010076634585857391,0.05316803604364395,-0.02642257697880268,-0.00046036025742068887,0.02024744264781475,0.023355189710855484,-0.018955910578370094,-0.010049727745354176,0.007998076267540455,-0.01303639356046915,-0.01387050747871399,0.0035550743341445923,0.039230260998010635,0.021579334512352943,-0.00399231119081378,0.003669428639113903,-0.0096124904230237,0.02409512922167778,0.0008652250398881733,-0.022588342428207397,0.00023102096747606993,0.00042714705341495574,-0.0077895475551486015,0.02024744264781475,-0.03688935935497284,0.02004563994705677,-0.0068747131153941154,-0.008637115359306335,-0.009471229277551174,0.05306040868163109,0.021606240421533585,-0.03347218409180641,0.007365764118731022,0.02414894290268421,0.005129127763211727,0.022440355271100998,-0.04375062137842178,0.015431107021868229,0.05074641481041908,-0.017301136627793312,-0.01722041703760624,-0.027256689965724945,0.022009843960404396,0.04829788580536842,-0.007305223494768143,-0.008361319079995155,-0.0010258256224915385,-0.03801944851875305,-0.0056437221355736256,-0.006834352854639292,0.10095468908548355,-0.004984503146260977,-0.022655609995126724,0.004284923896193504,0.038180891424417496,-0.028763476759195328,0.007809727918356657,-0.0008156154071912169,-0.009491409175097942,-0.015256212092936039,-0.012309907004237175,-0.012666423805058002,-0.04536503553390503,-0.008018256165087223,-0.008240237832069397,0.02954377606511116,-0.006114593241363764,-0.03207302466034889,-0.007856815122067928,0.0016387983923777938,0.008119157515466213,-0.050477344542741776,-0.009168526157736778,0.005889247637242079,0.0017842638771981,-0.02427002415060997,-0.04014509543776512,-0.0161710474640131,0.019964920356869698,0.03839614614844322,-0.014368284493684769,0.00034768760087899864,0.04614533483982086,-0.018727201968431473,-0.01388396043330431,0.020207082852721214,-0.044826894998550415,-0.021686961874365807,-0.03686245530843735,0.0249157901853323,-0.03627050295472145,0.0027461855206638575,0.028010083362460136,-0.02529248595237732,0.0016228224849328399,0.005280479323118925,0.00720432261005044,-0.00756083894520998,0.0009156754822470248,-0.01444900594651699,-0.005129127763211727,0.04116755723953247,-0.004897055681794882,0.012962399050593376,0.01423375029116869,-0.01203411165624857,0.03374125435948372,0.055078424513339996,0.05591253936290741,-0.01292203925549984,0.0007449848344549537,0.012054291553795338,0.0142741110175848,0.010372609831392765,0.005805163644254208,-0.015780897811055183,-0.0396338626742363,0.038934286683797836,-0.010325523093342781,0.04700635373592377,-0.008455493487417698,0.0192249808460474,0.01477188803255558,0.03387578949332237,0.009242520667612553,0.012881678529083729,-0.015498374588787556,0.022978492081165314,-0.001986065646633506,0.039176445454359055,-0.007540659047663212,-0.023180294781923294,0.007991349324584007,0.0419478565454483,-0.014327924698591232,0.03239590674638748,-0.006343301851302385,-0.005465464200824499,-0.01512167789041996,-0.008462220430374146,0.0028403596952557564,-0.0056336321868002415,0.023059213533997536,0.0068612596951425076,-0.012552069500088692,0.025184858590364456,-0.054002150893211365,0.020906662568449974,-0.02377224713563919,0.020301256328821182,0.020435791462659836,0.019184619188308716,0.03352599963545799,0.019413327798247337,-0.028951825574040413,-0.011065462604165077,-0.008125883527100086,-0.0582803450524807,-0.03939170390367508,0.031077470630407333,-0.00020705700444523245,-0.009794111363589764,0.015135131776332855,-0.004722161218523979,0.05106929689645767,-0.07060370594263077,-0.03624359518289566,-0.03161560744047165,0.0004237836692482233,0.013513990677893162,0.045176684856414795,0.03314930200576782,0.014287563972175121,-0.022453809157013893,0.03656647726893425,-0.008280598558485508,0.04996611550450325,0.013379456475377083,0.025184858590364456,-0.021888762712478638,0.003402041271328926,-0.014153029769659042,-0.001526966574601829,0.014502819627523422,0.02059723250567913,-0.0005839638179168105,0.013628344982862473,-0.012948946096003056,-0.0027663656510412693,0.00431183073669672,0.0013747744960710406,-0.03645884990692139,0.013379456475377083,-0.009255973622202873,-0.01739531196653843,-0.0028117711190134287,0.025938251987099648,-0.00592960836365819,-0.03559783101081848,-0.039902932941913605,-0.003255734918639064,-0.021754229441285133,0.009269427508115768,0.0029849843122065067,-0.0046414402313530445,-0.004863422363996506,-0.029759032651782036,0.0034777168184518814,0.01704552210867405,-0.03573236241936684,-0.047329239547252655,-0.013063300400972366,-0.01346017699688673,-0.0034642633982002735,-0.015928884968161583,0.02339554950594902,-0.02339554950594902,0.021660054102540016,-0.00933669414371252,-0.0029160352423787117,0.022951586171984673,-0.031050562858581543,-0.019278794527053833,0.014435552060604095,0.005872431211173534,-0.01672263815999031,0.0056100888177752495,0.014354831539094448,0.04210929945111275,0.008711108937859535,-0.06419986486434937,-0.037077710032463074,0.02199639193713665,-0.018363960087299347,-0.0029059452936053276,0.024135489016771317,-0.014987143687903881,-0.019305700436234474,-0.012942219153046608,-0.03269188478589058,0.0018212607828900218,-0.018982818350195885,-0.005663902498781681,-0.005209848750382662,-0.013574531301856041,-0.01777200773358345,-0.03476371616125107,-0.04081776738166809,0.02104119583964348,-0.010069907642900944,-0.047652121633291245,-0.026624377816915512,0.017637472599744797,0.012720237486064434,0.03164251521229744,0.016426661983132362,-0.01779891550540924,0.023005399852991104,-0.013843600638210773,-0.018337052315473557,-0.004385824780911207,0.02414894290268421,-0.01241080742329359,0.009155073203146458,0.051499806344509125,0.05456719547510147,-0.0008387385169044137,0.032207559794187546,-0.0035315307322889566,0.01722041703760624,-0.006262580864131451,-0.0008812010055407882,0.01404540240764618,-0.013466903939843178,-0.013756153173744678,0.019103899598121643,-0.005468827672302723,-0.020059093832969666,-0.02039542980492115,-0.015188945457339287,0.02494269609451294,0.011812129057943821,0.025009963661432266,0.041624974459409714,-0.013184381648898125,0.008354592137038708,-0.004651530645787716,0.0001839338947320357,-0.01409921608865261,-0.008408406749367714,-0.008226784877479076,-0.02159278839826584,0.006181860342621803,-0.017879635095596313,-0.0016127323033288121,0.037804193794727325,0.03376815840601921,-0.0008383181411772966,0.01814870350062847,-0.001523603219538927,0.0018178974278271198,0.028063897043466568,-0.02304575964808464,-0.011879396624863148,0.008421859703958035,-0.0053611998446285725,0.004611169919371605,-0.006888166535645723,0.021552426740527153,-0.00696216057986021,-0.026879994198679924,-0.006548467092216015,0.008442039601504803,-0.032503534108400345,-0.00047045035171322525,-0.02989356592297554,0.02217128686606884,0.019655490294098854,-0.0013302098959684372,0.02774101495742798,-0.010715672746300697,0.006901619955897331,0.008119157515466213,-0.028225338086485863,-0.02441801130771637,0.019763117656111717,0.032853323966264725,-0.01812179759144783,0.022252006456255913,-0.01359471119940281,-0.009713390842080116,-0.020274348556995392,-0.011791949160397053,0.007688646670430899,-0.014072309248149395,0.015632908791303635,-0.008213330991566181,0.0011511108605191112,-0.031131284311413765,-0.011132730171084404,0.06769776344299316,-0.008805283345282078,0.008576574735343456,0.02097392827272415,-0.01494678296148777,0.005024863872677088,-0.012007203884422779,0.005277115851640701,0.020987382158637047,-0.0036593384575098753,-0.024835068732500076,0.0002877777151297778,0.004056215286254883,-0.013830146752297878,-0.004335374105721712,0.02342245727777481,0.018754109740257263,0.008812010288238525,-0.012013930827379227,0.0008509307517670095,0.012518435716629028,0.020987382158637047,-0.008845643140375614,-0.005741260014474392,-0.017085881903767586,0.020906662568449974,-0.00992191955447197,-0.011966844089329243,-0.004540539346635342,0.03592071309685707,0.02669164538383484,0.014960236847400665,-0.007365764118731022,-0.01044660434126854,-0.02784864231944084,-0.025978611782193184,0.005667265970259905,-0.0040965755470097065,0.027875548228621483,-0.03939170390367508,0.0031649242155253887,0.004587626550346613,0.04038725793361664,-0.028359873220324516,0.036055248230695724,-0.027902456000447273,-0.021552426740527153,0.011132730171084404,0.022359633818268776,-0.015807803720235825,0.025305939838290215,-0.005102220922708511,0.002261861227452755,0.013083480298519135,0.011643961071968079,0.023234108462929726,0.02879038266837597,-0.016117233783006668,0.0093972347676754,0.00861020851880312,-0.023852966725826263,0.008832190185785294,0.020112907513976097,0.001081321039237082,-0.05688118934631348,0.02919398620724678,0.003302822122350335,-0.03191158547997475,0.02287086471915245,-0.02199639193713665,-0.0019053448922932148,-0.041275184601545334,-0.01867338828742504,0.009121439419686794,-0.029651403427124023,0.06037908419966698,-0.02502341754734516,-0.01777200773358345,0.03376815840601921,-0.020260896533727646,-0.017206963151693344,-0.02537320740520954,0.03094293549656868,-0.03403722867369652,0.01964203640818596,-0.006319758016616106,-0.010022819973528385,-0.031104376539587975,0.014637353830039501,0.013218014501035213,-0.020489605143666267,-0.02211747132241726,0.0115834204480052,-0.005505824461579323,0.043777525424957275,0.004540539346635342,-0.02264215610921383,0.0056336321868002415,-0.010594592429697514],"index":0,"object":"embedding"}],"object":"list","usage":{"completion_tokens":0,"prompt_tokens":4,"total_tokens":4,"completion_tokens_details":null,"prompt_tokens_details":null}}'
+ recorded_at: Sun, 06 Apr 2025 06:32:50 GMT
+recorded_with: VCR 6.3.1
diff --git a/spec/fixtures/vcr_cassettes/client_embedding_generation_generates_embeddings_with_custom_dimensions.yml b/spec/fixtures/vcr_cassettes/client_embedding_generation_generates_embeddings_with_custom_dimensions.yml
new file mode 100644
index 0000000..a66a757
--- /dev/null
+++ b/spec/fixtures/vcr_cassettes/client_embedding_generation_generates_embeddings_with_custom_dimensions.yml
@@ -0,0 +1,121 @@
+---
+http_interactions:
+- request:
+ method: post
+ uri: http://localhost:8000/embeddings
+ body:
+ encoding: UTF-8
+ string: '{"input":"Hello, world!","model":"text-embedding-3-small","dimensions":256}'
+ headers:
+ X-Litellm-Timeout:
+ - '120'
+ User-Agent:
+ - Faraday v2.12.2
+ X-Request-Id:
+ - 7544a591-3fed-4047-b4c8-9ae235f17873
+ Content-Type:
+ - application/json
+ Accept-Encoding:
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
+ Accept:
+ - "*/*"
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Date:
+ - Sun, 06 Apr 2025 06:32:49 GMT
+ Server:
+ - uvicorn
+ Content-Length:
+ - '5583'
+ Content-Type:
+ - application/json
+ X-Litellm-Call-Id:
+ - 632088cc-7dcf-421d-93f1-58e082d20d8a
+ X-Litellm-Model-Id:
+ - 4a7f0868c5473e06a5f20ae08390f921cbf173866984f81d99f3a3501adf13e2
+ X-Litellm-Model-Api-Base:
+ - https://api.openai.com/v1
+ X-Litellm-Version:
+ - 1.61.9
+ X-Litellm-Response-Cost:
+ - 8e-08
+ X-Litellm-Key-Spend:
+ - '0.0'
+ X-Litellm-Response-Duration-Ms:
+ - '686.484'
+ X-Litellm-Overhead-Duration-Ms:
+ - '2.684'
+ X-Ratelimit-Limit-Requests:
+ - '5000'
+ X-Ratelimit-Remaining-Requests:
+ - '4999'
+ X-Ratelimit-Limit-Tokens:
+ - '1000000'
+ X-Ratelimit-Remaining-Tokens:
+ - '999997'
+ Llm-Provider-Date:
+ - Sun, 06 Apr 2025 06:32:50 GMT
+ Llm-Provider-Content-Type:
+ - application/json
+ Llm-Provider-Transfer-Encoding:
+ - chunked
+ Llm-Provider-Connection:
+ - keep-alive
+ Llm-Provider-Access-Control-Allow-Origin:
+ - "*"
+ Llm-Provider-Access-Control-Expose-Headers:
+ - X-Request-ID
+ Llm-Provider-Openai-Model:
+ - text-embedding-3-small
+ Llm-Provider-Openai-Organization:
+ - user-s7l904mmsyaeoqfhuynmxjmp
+ Llm-Provider-Openai-Processing-Ms:
+ - '74'
+ Llm-Provider-Openai-Version:
+ - '2020-10-01'
+ Llm-Provider-Strict-Transport-Security:
+ - max-age=31536000; includeSubDomains; preload
+ Llm-Provider-Via:
+ - envoy-router-755cb696bc-42588
+ Llm-Provider-X-Envoy-Upstream-Service-Time:
+ - '65'
+ Llm-Provider-X-Ratelimit-Limit-Requests:
+ - '5000'
+ Llm-Provider-X-Ratelimit-Limit-Tokens:
+ - '1000000'
+ Llm-Provider-X-Ratelimit-Remaining-Requests:
+ - '4999'
+ Llm-Provider-X-Ratelimit-Remaining-Tokens:
+ - '999997'
+ Llm-Provider-X-Ratelimit-Reset-Requests:
+ - 12ms
+ Llm-Provider-X-Ratelimit-Reset-Tokens:
+ - 0s
+ Llm-Provider-X-Request-Id:
+ - req_709033530f18b86c6b744bbde7c18569
+ Llm-Provider-Cf-Cache-Status:
+ - DYNAMIC
+ Llm-Provider-X-Content-Type-Options:
+ - nosniff
+ Llm-Provider-Server:
+ - cloudflare
+ Llm-Provider-Cf-Ray:
+ - 92bf40122869f9f8-MCT
+ Llm-Provider-Content-Encoding:
+ - gzip
+ Llm-Provider-Alt-Svc:
+ - h3=":443"; ma=86400
+ X-Litellm-Model-Group:
+ - text-embedding-3-small
+ X-Litellm-Attempted-Retries:
+ - '0'
+ X-Litellm-Attempted-Fallbacks:
+ - '0'
+ body:
+ encoding: UTF-8
+ string: '{"model":"text-embedding-3-small","data":[{"embedding":[-0.0375906340777874,-0.04953211918473244,-0.0033692517317831516,0.036931611597537994,-0.06621856242418289,-0.038592349737882614,-0.04104391112923622,0.1010676696896553,-0.06294981390237808,-0.05952289700508118,-0.004204562399536371,-0.05678136646747589,-0.004847109317779541,-0.061684492975473404,0.02024516649544239,0.0364571176469326,-0.09041786938905716,0.08124427497386932,0.0008657905855216086,0.08076977729797363,0.10517996549606323,0.003670754376798868,0.0089495237916708,0.019638866186141968,0.09379205852746964,0.004313301295042038,-0.01926981285214424,0.07539215683937073,0.0017480567330494523,-0.10212210565805435,0.10022412240505219,-0.0637933611869812,-0.027494411915540695,-0.02475287951529026,0.02600502222776413,0.036378033459186554,0.003148479387164116,-0.0016038956819102168,-0.024990128353238106,-0.058204855769872665,-0.008705684915184975,-0.03002505749464035,0.05027022585272789,0.017846325412392616,-0.07222884893417358,0.039831310510635376,-0.07976806163787842,-0.005137079395353794,0.06954003870487213,0.09505738317966461,-0.06600768119096756,-0.00478450208902359,0.03382102772593498,0.1488863229751587,0.0018090163357555866,-0.08361675590276718,0.016422836109995842,0.14899177849292755,-0.09263218194246292,0.02955056168138981,0.027916187420487404,0.04839860275387764,0.01998155750334263,-0.0019177549984306097,0.027019916102290154,-0.019797030836343765,-0.04056941717863083,-0.003000199329108,-0.02296033874154091,0.09669175744056702,0.0021434701047837734,0.07412683218717575,-0.03788060322403908,0.011473579332232475,-0.09068147838115692,-0.008903391659259796,-0.04381180554628372,0.017147760838270187,-0.05206276476383209,-0.1066034585237503,-0.08667462319135666,0.03788060322403908,-0.060577332973480225,-0.1183076947927475,-0.03701069578528404,0.008567290380597115,-0.04681694880127907,-0.02356663905084133,-0.03252934291958809,0.004313301295042038,-0.015724273398518562,0.029972337186336517,-0.029313314706087112,0.0244101881980896,0.028417043387889862,-0.054250720888376236,-0.04465535283088684,0.11103208363056183,0.11957301199436188,-0.09658631682395935,0.028627930209040642,-0.0535389743745327,0.025965480133891106,-0.040253084152936935,0.05852118507027626,0.0441017746925354,0.016066964715719223,-0.07971534132957458,-0.05208912491798401,0.008883621543645859,-0.244418203830719,0.01845262572169304,0.06231715530157089,-0.06089366599917412,0.011368135921657085,0.06041916832327843,0.10517996549606323,-0.07750102877616882,0.0458943173289299,-0.10533813387155533,0.017015956342220306,-0.022578105330467224,0.03827601671218872,-0.08198238164186478,-0.08451302349567413,-0.08419669419527054,0.011466989293694496,0.11271918565034866,-0.061684492975473404,0.039014123380184174,0.0772901400923729,0.07802824676036835,0.022090429440140724,-0.0005585214239545166,-0.08925798535346985,0.0036575740668922663,-0.07966262102127075,-0.02634771354496479,-0.09621725976467133,0.09263218194246292,0.11061031371355057,-0.09257946163415909,-0.021339144557714462,-0.019520241767168045,-0.011611973866820335,-0.0807170569896698,-0.017226845026016235,0.05111377313733101,-0.01949388161301613,-0.012257815338671207,0.05952289700508118,0.11883491277694702,-0.10038228332996368,0.050507474690675735,0.007400820963084698,-0.005137079395353794,0.04802954941987991,-0.03295111656188965,-0.054514329880476,0.029497839510440826,0.10797422379255295,0.07755374908447266,-0.08693823218345642,-0.015473844483494759,-0.015961522236466408,0.016673265025019646,-0.02301306091248989,0.004754846449941397,-0.08546201884746552,-0.00440556462854147,0.046975113451480865,0.041017550975084305,-0.04138660430908203,-0.0883617177605629,-0.03766971826553345,0.051614630967378616,0.045947037637233734,-0.09716625511646271,-0.031791239976882935,-0.04945303872227669,0.05588509514927864,0.08899437636137009,0.004491237457841635,0.037406109273433685,-0.05208912491798401,-0.02190590277314186,-0.008764997124671936,-0.013332022354006767,-0.023342572152614594,0.0016780357109382749,-0.06463690847158432,0.11018853634595871,0.045999761670827866,0.0038552808109670877,0.008837489411234856,-0.07170163094997406,0.13127724826335907,0.010517996735870838,-0.04225651174783707,0.04755505174398422,-0.0007640540134161711,0.0248978640884161,-0.10064589232206345,-0.06247531995177269,-0.0458943173289299,-0.08203510195016861,-0.00002793122075672727,0.13886919617652893,-0.016409656032919884,-0.10280748456716537,0.11482805758714676,-0.028759734705090523,-0.10618168115615845,-0.004013446159660816,-0.09663903713226318,-0.03503362834453583,0.0808752253651619,0.04368000105023384,-0.021998165175318718,-0.061948101967573166,-0.15552927553653717,0.14023995399475098,0.1668117344379425,-0.08076977729797363,0.06052461266517639,-0.02613682672381401,-0.016725987195968628,-0.01609332673251629,0.09790436178445816,0.02857520990073681,0.04091210663318634,0.0357980951666832,0.047607775777578354,-0.041992902755737305,-0.020574677735567093,-0.008475027047097683,0.07196523994207382,-0.04183473810553551,-0.011084755882620811,-0.014023995958268642,-0.07591937482357025,-0.0021945445332676172,-0.011829451657831669,0.06711483746767044,0.08941615372896194,-0.03155399113893509,-0.08372219651937485,-0.043917249888181686,0.021787278354167938,0.07987350970506668,0.035191792994737625,0.0533808097243309,0.010616850107908249,-0.039910394698381424,0.03363649919629097,-0.020007917657494545],"index":0,"object":"embedding"}],"object":"list","usage":{"completion_tokens":0,"prompt_tokens":4,"total_tokens":4,"completion_tokens_details":null,"prompt_tokens_details":null}}'
+ recorded_at: Sun, 06 Apr 2025 06:32:50 GMT
+recorded_with: VCR 6.3.1
diff --git a/spec/fixtures/vcr_cassettes/client_image_generation_generates_an_image_url_from_a_prompt.yml b/spec/fixtures/vcr_cassettes/client_image_generation_generates_an_image_url_from_a_prompt.yml
new file mode 100644
index 0000000..288a764
--- /dev/null
+++ b/spec/fixtures/vcr_cassettes/client_image_generation_generates_an_image_url_from_a_prompt.yml
@@ -0,0 +1,51 @@
+---
+http_interactions:
+- request:
+ method: post
+ uri: http://localhost:8000/images/generations
+ body:
+ encoding: UTF-8
+ string: '{"prompt":"A beautiful sunset over a calm ocean","model":"dall-e-2"}'
+ headers:
+ X-Litellm-Timeout:
+ - '120'
+ User-Agent:
+ - Faraday v2.12.2
+ X-Request-Id:
+ - 6f53ddb3-c89b-479a-8625-05fe4b71411d
+ Content-Type:
+ - application/json
+ Accept-Encoding:
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
+ Accept:
+ - "*/*"
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Date:
+ - Sun, 06 Apr 2025 06:32:50 GMT
+ Server:
+ - uvicorn
+ Content-Length:
+ - '681'
+ Content-Type:
+ - application/json
+ X-Litellm-Call-Id:
+ - 573ea61c-16ab-402f-adb3-ec79ba70983a
+ X-Litellm-Model-Id:
+ - ba9b3735b9c65a4d11422edf195d6e52e24a12cfd02d8332ac4252c062f15275
+ X-Litellm-Model-Api-Base:
+ - https://api.openai.com/v1
+ X-Litellm-Version:
+ - 1.61.9
+ X-Litellm-Response-Cost:
+ - '0.019922944'
+ X-Litellm-Key-Spend:
+ - '0.0'
+ body:
+ encoding: UTF-8
+ string: '{"created":1743921182,"data":[{"b64_json":null,"revised_prompt":null,"url":"https://oaidalleapiprodscus.blob.core.windows.net/private/org-PWt02e03ARXCpcUnOuZHyhp7/user-S7L904MmSyaeOqFHUYNMXJMP/img-yhGlOkBjMN8mHO7U9mvK7Ecx.png?st=2025-04-06T05%3A33%3A02Z&se=2025-04-06T07%3A33%3A02Z&sp=r&sv=2024-08-04&sr=b&rscd=inline&rsct=image/png&skoid=d505667d-d6c1-4a0a-bac7-5c84a87759f8&sktid=a48cca56-e6da-484e-a814-9c849652bcb3&skt=2025-04-05T16%3A59%3A10Z&ske=2025-04-06T16%3A59%3A10Z&sks=b&skv=2024-08-04&sig=lgLg1E90Up2uXQMLdjhKBXWAJyRwMKhS8apmtk/52HQ%3D"}],"usage":{"completion_tokens":0,"prompt_tokens":0,"total_tokens":0,"completion_tokens_details":null,"prompt_tokens_details":null}}'
+ recorded_at: Sun, 06 Apr 2025 06:33:02 GMT
+recorded_with: VCR 6.3.1
diff --git a/spec/fixtures/vcr_cassettes/client_models_returns_a_list_of_available_models.yml b/spec/fixtures/vcr_cassettes/client_models_returns_a_list_of_available_models.yml
new file mode 100644
index 0000000..4ec45b3
--- /dev/null
+++ b/spec/fixtures/vcr_cassettes/client_models_returns_a_list_of_available_models.yml
@@ -0,0 +1,37 @@
+---
+http_interactions:
+- request:
+ method: get
+ uri: http://localhost:8000/models
+ body:
+ encoding: US-ASCII
+ string: ''
+ headers:
+ X-Litellm-Timeout:
+ - '120'
+ User-Agent:
+ - Faraday v2.12.2
+ X-Request-Id:
+ - 0cd1535c-af9a-4bc2-875e-130929ec5a01
+ Accept-Encoding:
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
+ Accept:
+ - "*/*"
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Date:
+ - Sun, 06 Apr 2025 06:34:03 GMT
+ Server:
+ - uvicorn
+ Content-Length:
+ - '273'
+ Content-Type:
+ - application/json
+ body:
+ encoding: UTF-8
+ string: '{"data":[{"id":"gpt-3.5-turbo","object":"model","created":1677610602,"owned_by":"openai"},{"id":"dall-e-2","object":"model","created":1677610602,"owned_by":"openai"},{"id":"text-embedding-3-small","object":"model","created":1677610602,"owned_by":"openai"}],"object":"list"}'
+ recorded_at: Sun, 06 Apr 2025 06:34:04 GMT
+recorded_with: VCR 6.3.1
diff --git a/spec/fixtures/vcr_cassettes/client_streaming_responses_supports_streaming_responses.yml b/spec/fixtures/vcr_cassettes/client_streaming_responses_supports_streaming_responses.yml
new file mode 100644
index 0000000..2b1b6e1
--- /dev/null
+++ b/spec/fixtures/vcr_cassettes/client_streaming_responses_supports_streaming_responses.yml
@@ -0,0 +1,131 @@
+---
+http_interactions:
+- request:
+ method: post
+ uri: http://localhost:8000/chat/completions
+ body:
+ encoding: UTF-8
+ string: '{"messages":[{"role":"user","content":"Count from 1 to 3"}],"model":"gpt-3.5-turbo","stream":true}'
+ headers:
+ X-Litellm-Timeout:
+ - '120'
+ User-Agent:
+ - Faraday v2.12.2
+ X-Request-Id:
+ - a46cd82d-5d14-46ba-8292-dd4f76370035
+ Content-Type:
+ - application/json
+ Accept-Encoding:
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
+ Accept:
+ - "*/*"
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Date:
+ - Sun, 06 Apr 2025 06:32:44 GMT
+ Server:
+ - uvicorn
+ X-Litellm-Call-Id:
+ - 652751f8-3bb1-4c69-a9b7-005427d5f92b
+ X-Litellm-Model-Id:
+ - a894f5c6235fa10c0c1755367a3bb2ad54a34654ed3da22bee9da260609709f7
+ X-Litellm-Model-Api-Base:
+ - https://api.openai.com/v1
+ X-Litellm-Version:
+ - 1.61.9
+ X-Litellm-Key-Spend:
+ - '0.0'
+ X-Litellm-Response-Duration-Ms:
+ - '692.1460000000001'
+ X-Litellm-Overhead-Duration-Ms:
+ - '2.875'
+ X-Ratelimit-Limit-Requests:
+ - '5000'
+ X-Ratelimit-Limit-Tokens:
+ - '2000000'
+ X-Ratelimit-Remaining-Requests:
+ - '4999'
+ X-Ratelimit-Remaining-Tokens:
+ - '1999993'
+ X-Ratelimit-Reset-Requests:
+ - 12ms
+ X-Ratelimit-Reset-Tokens:
+ - 0s
+ Llm-Provider-Date:
+ - Sun, 06 Apr 2025 06:32:45 GMT
+ Llm-Provider-Content-Type:
+ - text/event-stream; charset=utf-8
+ Llm-Provider-Transfer-Encoding:
+ - chunked
+ Llm-Provider-Connection:
+ - keep-alive
+ Llm-Provider-Access-Control-Expose-Headers:
+ - X-Request-ID
+ Llm-Provider-Openai-Organization:
+ - user-s7l904mmsyaeoqfhuynmxjmp
+ Llm-Provider-Openai-Processing-Ms:
+ - '254'
+ Llm-Provider-Openai-Version:
+ - '2020-10-01'
+ Llm-Provider-X-Ratelimit-Limit-Requests:
+ - '5000'
+ Llm-Provider-X-Ratelimit-Limit-Tokens:
+ - '2000000'
+ Llm-Provider-X-Ratelimit-Remaining-Requests:
+ - '4999'
+ Llm-Provider-X-Ratelimit-Remaining-Tokens:
+ - '1999993'
+ Llm-Provider-X-Ratelimit-Reset-Requests:
+ - 12ms
+ Llm-Provider-X-Ratelimit-Reset-Tokens:
+ - 0s
+ Llm-Provider-X-Request-Id:
+ - req_294732b36b72e73932fc52b8696deb61
+ Llm-Provider-Strict-Transport-Security:
+ - max-age=31536000; includeSubDomains; preload
+ Llm-Provider-Cf-Cache-Status:
+ - DYNAMIC
+ Llm-Provider-Set-Cookie:
+ - __cf_bm=elSuyvtLU5wPEUGvJlpyCT1XQc2ye_jyGSq6FITgtpw-1743921165-1.0.1.1-GNhwX1.Q6SABWGCP799nAOVQ_LhhVCRAL22r0xsfAzyh2MUVZHkxVUtsMZgUxejMaPNPcLhgIeh8eeqAswUS7ENqpCNioIIsleCLrQyk5QA;
+ path=/; expires=Sun, 06-Apr-25 07:02:45 GMT; domain=.api.openai.com; HttpOnly;
+ Secure; SameSite=None, _cfuvid=cSbsbF4_YWUN80SuRSBvkZjpxHMtQwV.e0F3naBbIGM-1743921165114-0.0.1.1-604800000;
+ path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None
+ Llm-Provider-X-Content-Type-Options:
+ - nosniff
+ Llm-Provider-Server:
+ - cloudflare
+ Llm-Provider-Cf-Ray:
+ - 92bf3fee89f1f9d5-MCT
+ Llm-Provider-Alt-Svc:
+ - h3=":443"; ma=86400
+ Content-Type:
+ - text/event-stream; charset=utf-8
+ Transfer-Encoding:
+ - chunked
+ body:
+ encoding: UTF-8
+ string: |+
+ data: {"id":"chatcmpl-BJDqerNxBLv4EyDlkVM9ra2ICDjHY","created":1743921165,"model":"gpt-3.5-turbo","object":"chat.completion.chunk","choices":[{"index":0,"delta":{"content":"1","role":"assistant"}}],"stream_options":{"include_usage":true}}
+
+ data: {"id":"chatcmpl-BJDqerNxBLv4EyDlkVM9ra2ICDjHY","created":1743921165,"model":"gpt-3.5-turbo","object":"chat.completion.chunk","choices":[{"index":0,"delta":{"content":"\n"}}],"stream_options":{"include_usage":true}}
+
+ data: {"id":"chatcmpl-BJDqerNxBLv4EyDlkVM9ra2ICDjHY","created":1743921165,"model":"gpt-3.5-turbo","object":"chat.completion.chunk","choices":[{"index":0,"delta":{"content":"2"}}],"stream_options":{"include_usage":true}}
+
+ data: {"id":"chatcmpl-BJDqerNxBLv4EyDlkVM9ra2ICDjHY","created":1743921165,"model":"gpt-3.5-turbo","object":"chat.completion.chunk","choices":[{"index":0,"delta":{"content":"\n"}}],"stream_options":{"include_usage":true}}
+
+ data: {"id":"chatcmpl-BJDqerNxBLv4EyDlkVM9ra2ICDjHY","created":1743921165,"model":"gpt-3.5-turbo","object":"chat.completion.chunk","choices":[{"index":0,"delta":{"content":"3"}}],"stream_options":{"include_usage":true}}
+
+ data: {"id":"chatcmpl-BJDqerNxBLv4EyDlkVM9ra2ICDjHY","created":1743921165,"model":"gpt-3.5-turbo","object":"chat.completion.chunk","choices":[{"finish_reason":"stop","index":0,"delta":{}}],"stream_options":{"include_usage":true}}
+
+ data: {"id":"chatcmpl-BJDqerNxBLv4EyDlkVM9ra2ICDjHY","created":1743921165,"model":"gpt-3.5-turbo","object":"chat.completion.chunk","choices":[{"index":0,"delta":{}}],"stream_options":{"include_usage":true}}
+
+ data: {"id":"chatcmpl-BJDqerNxBLv4EyDlkVM9ra2ICDjHY","created":1743921165,"model":"gpt-3.5-turbo","object":"chat.completion.chunk","choices":[{"index":0,"delta":{}}],"stream_options":{"include_usage":true},"usage":{"completion_tokens":6,"prompt_tokens":14,"total_tokens":20,"completion_tokens_details":{"accepted_prediction_tokens":0,"audio_tokens":0,"reasoning_tokens":0,"rejected_prediction_tokens":0},"prompt_tokens_details":{"audio_tokens":0,"cached_tokens":0}}}
+
+ data: [DONE]
+
+ recorded_at: Sun, 06 Apr 2025 06:32:45 GMT
+recorded_with: VCR 6.3.1
+...
diff --git a/spec/fixtures/vcr_cassettes/client_tools_calling_returns_active_for_active_user.yml b/spec/fixtures/vcr_cassettes/client_tools_calling_returns_active_for_active_user.yml
new file mode 100644
index 0000000..ce06338
--- /dev/null
+++ b/spec/fixtures/vcr_cassettes/client_tools_calling_returns_active_for_active_user.yml
@@ -0,0 +1,228 @@
+---
+http_interactions:
+- request:
+ method: post
+ uri: http://localhost:8000/chat/completions
+ body:
+ encoding: UTF-8
+ string: '{"messages":[{"role":"user","content":"What is the status of user_123?"}],"model":"gpt-3.5-turbo","stream":false,"tools":[{"type":"function","function":{"name":"UserStatus__get_user_status","description":"Gets
+ the current status of a user based on their ID","parameters":{"type":"object","properties":{"user_id":{"type":"string","description":"The
+ ID of the user to check"}},"required":[],"additionalProperties":false}}}]}'
+ headers:
+ X-Litellm-Timeout:
+ - '120'
+ User-Agent:
+ - Faraday v2.12.2
+ X-Request-Id:
+ - c91d983c-125f-44cf-badb-7eb15c253366
+ Content-Type:
+ - application/json
+ Accept-Encoding:
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
+ Accept:
+ - "*/*"
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Date:
+ - Sun, 06 Apr 2025 06:32:44 GMT
+ Server:
+ - uvicorn
+ Content-Length:
+ - '751'
+ Content-Type:
+ - application/json
+ X-Litellm-Call-Id:
+ - 9bba9390-ba2d-4f66-8a83-8f8fa69b26ca
+ X-Litellm-Model-Id:
+ - a894f5c6235fa10c0c1755367a3bb2ad54a34654ed3da22bee9da260609709f7
+ X-Litellm-Model-Api-Base:
+ - https://api.openai.com/v1
+ X-Litellm-Version:
+ - 1.61.9
+ X-Litellm-Response-Cost:
+ - 7e-05
+ X-Litellm-Key-Spend:
+ - '0.0'
+ X-Litellm-Response-Duration-Ms:
+ - '669.2510000000001'
+ X-Litellm-Overhead-Duration-Ms:
+ - '3.673'
+ X-Ratelimit-Limit-Requests:
+ - '5000'
+ X-Ratelimit-Remaining-Requests:
+ - '4999'
+ X-Ratelimit-Limit-Tokens:
+ - '2000000'
+ X-Ratelimit-Remaining-Tokens:
+ - '1999989'
+ Llm-Provider-Date:
+ - Sun, 06 Apr 2025 06:32:45 GMT
+ Llm-Provider-Content-Type:
+ - application/json
+ Llm-Provider-Transfer-Encoding:
+ - chunked
+ Llm-Provider-Connection:
+ - keep-alive
+ Llm-Provider-Access-Control-Expose-Headers:
+ - X-Request-ID
+ Llm-Provider-Openai-Organization:
+ - user-s7l904mmsyaeoqfhuynmxjmp
+ Llm-Provider-Openai-Processing-Ms:
+ - '316'
+ Llm-Provider-Openai-Version:
+ - '2020-10-01'
+ Llm-Provider-X-Ratelimit-Limit-Requests:
+ - '5000'
+ Llm-Provider-X-Ratelimit-Limit-Tokens:
+ - '2000000'
+ Llm-Provider-X-Ratelimit-Remaining-Requests:
+ - '4999'
+ Llm-Provider-X-Ratelimit-Remaining-Tokens:
+ - '1999989'
+ Llm-Provider-X-Ratelimit-Reset-Requests:
+ - 12ms
+ Llm-Provider-X-Ratelimit-Reset-Tokens:
+ - 0s
+ Llm-Provider-X-Request-Id:
+ - req_4f7c68f8685dc3e886ad41e8b287cdfc
+ Llm-Provider-Strict-Transport-Security:
+ - max-age=31536000; includeSubDomains; preload
+ Llm-Provider-Cf-Cache-Status:
+ - DYNAMIC
+ Llm-Provider-X-Content-Type-Options:
+ - nosniff
+ Llm-Provider-Server:
+ - cloudflare
+ Llm-Provider-Cf-Ray:
+ - 92bf3ff2e984f9cd-MCT
+ Llm-Provider-Content-Encoding:
+ - gzip
+ Llm-Provider-Alt-Svc:
+ - h3=":443"; ma=86400
+ X-Litellm-Model-Group:
+ - gpt-3.5-turbo
+ X-Litellm-Attempted-Retries:
+ - '0'
+ X-Litellm-Attempted-Fallbacks:
+ - '0'
+ body:
+ encoding: UTF-8
+ string: '{"id":"chatcmpl-BJDqfkuo19St0RsduCCwUoYUNIm3F","created":1743921165,"model":"gpt-3.5-turbo-0125","object":"chat.completion","system_fingerprint":null,"choices":[{"finish_reason":"tool_calls","index":0,"message":{"content":null,"role":"assistant","tool_calls":[{"function":{"arguments":"{\"user_id\":\"user_123\"}","name":"UserStatus__get_user_status"},"id":"call_3kh1HJ1v58U1eYEqqnlu5Q9o","type":"function"}],"function_call":null,"refusal":null,"annotations":[]}}],"usage":{"completion_tokens":22,"prompt_tokens":74,"total_tokens":96,"completion_tokens_details":{"accepted_prediction_tokens":0,"audio_tokens":0,"reasoning_tokens":0,"rejected_prediction_tokens":0},"prompt_tokens_details":{"audio_tokens":0,"cached_tokens":0}},"service_tier":"default"}'
+ recorded_at: Sun, 06 Apr 2025 06:32:45 GMT
+- request:
+ method: post
+ uri: http://localhost:8000/chat/completions
+ body:
+ encoding: UTF-8
+ string: '{"messages":[{"role":"user","content":"What is the status of user_123?"},{"content":null,"role":"assistant","tool_calls":[{"function":{"arguments":"{\"user_id\":\"user_123\"}","name":"UserStatus__get_user_status"},"id":"call_3kh1HJ1v58U1eYEqqnlu5Q9o","type":"function"}],"function_call":null,"refusal":null,"annotations":[]},{"role":"tool","tool_call_id":"call_3kh1HJ1v58U1eYEqqnlu5Q9o","name":"UserStatus__get_user_status","content":"active"}],"model":"gpt-3.5-turbo","stream":false,"tools":[{"type":"function","function":{"name":"UserStatus__get_user_status","description":"Gets
+ the current status of a user based on their ID","parameters":{"type":"object","properties":{"user_id":{"type":"string","description":"The
+ ID of the user to check"}},"required":[],"additionalProperties":false}}}]}'
+ headers:
+ X-Litellm-Timeout:
+ - '120'
+ User-Agent:
+ - Faraday v2.12.2
+ X-Request-Id:
+ - b1345654-c060-42a0-a125-ee0e96d16da9
+ Content-Type:
+ - application/json
+ Accept-Encoding:
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
+ Accept:
+ - "*/*"
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Date:
+ - Sun, 06 Apr 2025 06:32:45 GMT
+ Server:
+ - uvicorn
+ Content-Length:
+ - '633'
+ Content-Type:
+ - application/json
+ X-Litellm-Call-Id:
+ - dc236324-2ae0-4605-ada6-2fe7dee39d57
+ X-Litellm-Model-Id:
+ - a894f5c6235fa10c0c1755367a3bb2ad54a34654ed3da22bee9da260609709f7
+ X-Litellm-Model-Api-Base:
+ - https://api.openai.com/v1
+ X-Litellm-Version:
+ - 1.61.9
+ X-Litellm-Response-Cost:
+ - '7.05e-05'
+ X-Litellm-Key-Spend:
+ - '0.0'
+ X-Litellm-Response-Duration-Ms:
+ - '590.144'
+ X-Litellm-Overhead-Duration-Ms:
+ - '2.487'
+ X-Ratelimit-Limit-Requests:
+ - '5000'
+ X-Ratelimit-Remaining-Requests:
+ - '4999'
+ X-Ratelimit-Limit-Tokens:
+ - '2000000'
+ X-Ratelimit-Remaining-Tokens:
+ - '1999986'
+ Llm-Provider-Date:
+ - Sun, 06 Apr 2025 06:32:46 GMT
+ Llm-Provider-Content-Type:
+ - application/json
+ Llm-Provider-Transfer-Encoding:
+ - chunked
+ Llm-Provider-Connection:
+ - keep-alive
+ Llm-Provider-Access-Control-Expose-Headers:
+ - X-Request-ID
+ Llm-Provider-Openai-Organization:
+ - user-s7l904mmsyaeoqfhuynmxjmp
+ Llm-Provider-Openai-Processing-Ms:
+ - '253'
+ Llm-Provider-Openai-Version:
+ - '2020-10-01'
+ Llm-Provider-X-Ratelimit-Limit-Requests:
+ - '5000'
+ Llm-Provider-X-Ratelimit-Limit-Tokens:
+ - '2000000'
+ Llm-Provider-X-Ratelimit-Remaining-Requests:
+ - '4999'
+ Llm-Provider-X-Ratelimit-Remaining-Tokens:
+ - '1999986'
+ Llm-Provider-X-Ratelimit-Reset-Requests:
+ - 12ms
+ Llm-Provider-X-Ratelimit-Reset-Tokens:
+ - 0s
+ Llm-Provider-X-Request-Id:
+ - req_99ef34f4ecc2a010fdf9d12c9a75a5d3
+ Llm-Provider-Strict-Transport-Security:
+ - max-age=31536000; includeSubDomains; preload
+ Llm-Provider-Cf-Cache-Status:
+ - DYNAMIC
+ Llm-Provider-X-Content-Type-Options:
+ - nosniff
+ Llm-Provider-Server:
+ - cloudflare
+ Llm-Provider-Cf-Ray:
+ - 92bf3ff73826f9cd-MCT
+ Llm-Provider-Content-Encoding:
+ - gzip
+ Llm-Provider-Alt-Svc:
+ - h3=":443"; ma=86400
+ X-Litellm-Model-Group:
+ - gpt-3.5-turbo
+ X-Litellm-Attempted-Retries:
+ - '0'
+ X-Litellm-Attempted-Fallbacks:
+ - '0'
+ body:
+ encoding: UTF-8
+ string: '{"id":"chatcmpl-BJDqgbKhEouKOkokxfoSl1QRBQftL","created":1743921166,"model":"gpt-3.5-turbo-0125","object":"chat.completion","system_fingerprint":null,"choices":[{"finish_reason":"stop","index":0,"message":{"content":"The
+ status of user_123 is active.","role":"assistant","tool_calls":null,"function_call":null,"refusal":null,"annotations":[]}}],"usage":{"completion_tokens":11,"prompt_tokens":108,"total_tokens":119,"completion_tokens_details":{"accepted_prediction_tokens":0,"audio_tokens":0,"reasoning_tokens":0,"rejected_prediction_tokens":0},"prompt_tokens_details":{"audio_tokens":0,"cached_tokens":0}},"service_tier":"default"}'
+ recorded_at: Sun, 06 Apr 2025 06:32:46 GMT
+recorded_with: VCR 6.3.1
diff --git a/spec/fixtures/vcr_cassettes/client_tools_calling_returns_inactive_for_inactive_user.yml b/spec/fixtures/vcr_cassettes/client_tools_calling_returns_inactive_for_inactive_user.yml
new file mode 100644
index 0000000..1f484b6
--- /dev/null
+++ b/spec/fixtures/vcr_cassettes/client_tools_calling_returns_inactive_for_inactive_user.yml
@@ -0,0 +1,228 @@
+---
+http_interactions:
+- request:
+ method: post
+ uri: http://localhost:8000/chat/completions
+ body:
+ encoding: UTF-8
+ string: '{"messages":[{"role":"user","content":"What is the status of user_456?"}],"model":"gpt-3.5-turbo","stream":false,"tools":[{"type":"function","function":{"name":"UserStatus__get_user_status","description":"Gets
+ the current status of a user based on their ID","parameters":{"type":"object","properties":{"user_id":{"type":"string","description":"The
+ ID of the user to check"}},"required":[],"additionalProperties":false}}}]}'
+ headers:
+ X-Litellm-Timeout:
+ - '120'
+ User-Agent:
+ - Faraday v2.12.2
+ X-Request-Id:
+ - b4508d42-3569-4b5c-8432-f88cef94d4e1
+ Content-Type:
+ - application/json
+ Accept-Encoding:
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
+ Accept:
+ - "*/*"
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Date:
+ - Sun, 06 Apr 2025 06:32:46 GMT
+ Server:
+ - uvicorn
+ Content-Length:
+ - '751'
+ Content-Type:
+ - application/json
+ X-Litellm-Call-Id:
+ - 8a7ffccd-202e-4750-b4d5-ab623ad5236b
+ X-Litellm-Model-Id:
+ - a894f5c6235fa10c0c1755367a3bb2ad54a34654ed3da22bee9da260609709f7
+ X-Litellm-Model-Api-Base:
+ - https://api.openai.com/v1
+ X-Litellm-Version:
+ - 1.61.9
+ X-Litellm-Response-Cost:
+ - 7e-05
+ X-Litellm-Key-Spend:
+ - '0.0'
+ X-Litellm-Response-Duration-Ms:
+ - '694.834'
+ X-Litellm-Overhead-Duration-Ms:
+ - '2.501'
+ X-Ratelimit-Limit-Requests:
+ - '5000'
+ X-Ratelimit-Remaining-Requests:
+ - '4999'
+ X-Ratelimit-Limit-Tokens:
+ - '2000000'
+ X-Ratelimit-Remaining-Tokens:
+ - '1999989'
+ Llm-Provider-Date:
+ - Sun, 06 Apr 2025 06:32:47 GMT
+ Llm-Provider-Content-Type:
+ - application/json
+ Llm-Provider-Transfer-Encoding:
+ - chunked
+ Llm-Provider-Connection:
+ - keep-alive
+ Llm-Provider-Access-Control-Expose-Headers:
+ - X-Request-ID
+ Llm-Provider-Openai-Organization:
+ - user-s7l904mmsyaeoqfhuynmxjmp
+ Llm-Provider-Openai-Processing-Ms:
+ - '341'
+ Llm-Provider-Openai-Version:
+ - '2020-10-01'
+ Llm-Provider-X-Ratelimit-Limit-Requests:
+ - '5000'
+ Llm-Provider-X-Ratelimit-Limit-Tokens:
+ - '2000000'
+ Llm-Provider-X-Ratelimit-Remaining-Requests:
+ - '4999'
+ Llm-Provider-X-Ratelimit-Remaining-Tokens:
+ - '1999989'
+ Llm-Provider-X-Ratelimit-Reset-Requests:
+ - 12ms
+ Llm-Provider-X-Ratelimit-Reset-Tokens:
+ - 0s
+ Llm-Provider-X-Request-Id:
+ - req_36fb2f202f7d0879f2316c354b842ad0
+ Llm-Provider-Strict-Transport-Security:
+ - max-age=31536000; includeSubDomains; preload
+ Llm-Provider-Cf-Cache-Status:
+ - DYNAMIC
+ Llm-Provider-X-Content-Type-Options:
+ - nosniff
+ Llm-Provider-Server:
+ - cloudflare
+ Llm-Provider-Cf-Ray:
+ - 92bf3ffb3d63f9cd-MCT
+ Llm-Provider-Content-Encoding:
+ - gzip
+ Llm-Provider-Alt-Svc:
+ - h3=":443"; ma=86400
+ X-Litellm-Model-Group:
+ - gpt-3.5-turbo
+ X-Litellm-Attempted-Retries:
+ - '0'
+ X-Litellm-Attempted-Fallbacks:
+ - '0'
+ body:
+ encoding: UTF-8
+ string: '{"id":"chatcmpl-BJDqgV3VpwZ1kVoOPpjoEbE3Pfqrs","created":1743921166,"model":"gpt-3.5-turbo-0125","object":"chat.completion","system_fingerprint":null,"choices":[{"finish_reason":"tool_calls","index":0,"message":{"content":null,"role":"assistant","tool_calls":[{"function":{"arguments":"{\"user_id\":\"user_456\"}","name":"UserStatus__get_user_status"},"id":"call_zaksGYwLYQV4voRO01nsZvc9","type":"function"}],"function_call":null,"refusal":null,"annotations":[]}}],"usage":{"completion_tokens":22,"prompt_tokens":74,"total_tokens":96,"completion_tokens_details":{"accepted_prediction_tokens":0,"audio_tokens":0,"reasoning_tokens":0,"rejected_prediction_tokens":0},"prompt_tokens_details":{"audio_tokens":0,"cached_tokens":0}},"service_tier":"default"}'
+ recorded_at: Sun, 06 Apr 2025 06:32:47 GMT
+- request:
+ method: post
+ uri: http://localhost:8000/chat/completions
+ body:
+ encoding: UTF-8
+ string: '{"messages":[{"role":"user","content":"What is the status of user_456?"},{"content":null,"role":"assistant","tool_calls":[{"function":{"arguments":"{\"user_id\":\"user_456\"}","name":"UserStatus__get_user_status"},"id":"call_zaksGYwLYQV4voRO01nsZvc9","type":"function"}],"function_call":null,"refusal":null,"annotations":[]},{"role":"tool","tool_call_id":"call_zaksGYwLYQV4voRO01nsZvc9","name":"UserStatus__get_user_status","content":"inactive"}],"model":"gpt-3.5-turbo","stream":false,"tools":[{"type":"function","function":{"name":"UserStatus__get_user_status","description":"Gets
+ the current status of a user based on their ID","parameters":{"type":"object","properties":{"user_id":{"type":"string","description":"The
+ ID of the user to check"}},"required":[],"additionalProperties":false}}}]}'
+ headers:
+ X-Litellm-Timeout:
+ - '120'
+ User-Agent:
+ - Faraday v2.12.2
+ X-Request-Id:
+ - c88a7682-d1a6-47a3-b17a-b5043f3c9391
+ Content-Type:
+ - application/json
+ Accept-Encoding:
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
+ Accept:
+ - "*/*"
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Date:
+ - Sun, 06 Apr 2025 06:32:46 GMT
+ Server:
+ - uvicorn
+ Content-Length:
+ - '635'
+ Content-Type:
+ - application/json
+ X-Litellm-Call-Id:
+ - debbf705-dfc7-46f6-956a-017865f46388
+ X-Litellm-Model-Id:
+ - a894f5c6235fa10c0c1755367a3bb2ad54a34654ed3da22bee9da260609709f7
+ X-Litellm-Model-Api-Base:
+ - https://api.openai.com/v1
+ X-Litellm-Version:
+ - 1.61.9
+ X-Litellm-Response-Cost:
+ - '7.05e-05'
+ X-Litellm-Key-Spend:
+ - '0.0'
+ X-Litellm-Response-Duration-Ms:
+ - '565.209'
+ X-Litellm-Overhead-Duration-Ms:
+ - '2.909'
+ X-Ratelimit-Limit-Requests:
+ - '5000'
+ X-Ratelimit-Remaining-Requests:
+ - '4999'
+ X-Ratelimit-Limit-Tokens:
+ - '2000000'
+ X-Ratelimit-Remaining-Tokens:
+ - '1999986'
+ Llm-Provider-Date:
+ - Sun, 06 Apr 2025 06:32:47 GMT
+ Llm-Provider-Content-Type:
+ - application/json
+ Llm-Provider-Transfer-Encoding:
+ - chunked
+ Llm-Provider-Connection:
+ - keep-alive
+ Llm-Provider-Access-Control-Expose-Headers:
+ - X-Request-ID
+ Llm-Provider-Openai-Organization:
+ - user-s7l904mmsyaeoqfhuynmxjmp
+ Llm-Provider-Openai-Processing-Ms:
+ - '236'
+ Llm-Provider-Openai-Version:
+ - '2020-10-01'
+ Llm-Provider-X-Ratelimit-Limit-Requests:
+ - '5000'
+ Llm-Provider-X-Ratelimit-Limit-Tokens:
+ - '2000000'
+ Llm-Provider-X-Ratelimit-Remaining-Requests:
+ - '4999'
+ Llm-Provider-X-Ratelimit-Remaining-Tokens:
+ - '1999986'
+ Llm-Provider-X-Ratelimit-Reset-Requests:
+ - 12ms
+ Llm-Provider-X-Ratelimit-Reset-Tokens:
+ - 0s
+ Llm-Provider-X-Request-Id:
+ - req_63444aba6cf15a98f5491a069ee37536
+ Llm-Provider-Strict-Transport-Security:
+ - max-age=31536000; includeSubDomains; preload
+ Llm-Provider-Cf-Cache-Status:
+ - DYNAMIC
+ Llm-Provider-X-Content-Type-Options:
+ - nosniff
+ Llm-Provider-Server:
+ - cloudflare
+ Llm-Provider-Cf-Ray:
+ - 92bf3fff7aadf9cd-MCT
+ Llm-Provider-Content-Encoding:
+ - gzip
+ Llm-Provider-Alt-Svc:
+ - h3=":443"; ma=86400
+ X-Litellm-Model-Group:
+ - gpt-3.5-turbo
+ X-Litellm-Attempted-Retries:
+ - '0'
+ X-Litellm-Attempted-Fallbacks:
+ - '0'
+ body:
+ encoding: UTF-8
+ string: '{"id":"chatcmpl-BJDqhAVe3P0acCGrduznw1yCGkVI1","created":1743921167,"model":"gpt-3.5-turbo-0125","object":"chat.completion","system_fingerprint":null,"choices":[{"finish_reason":"stop","index":0,"message":{"content":"The
+ status of user_456 is inactive.","role":"assistant","tool_calls":null,"function_call":null,"refusal":null,"annotations":[]}}],"usage":{"completion_tokens":11,"prompt_tokens":108,"total_tokens":119,"completion_tokens_details":{"accepted_prediction_tokens":0,"audio_tokens":0,"reasoning_tokens":0,"rejected_prediction_tokens":0},"prompt_tokens_details":{"audio_tokens":0,"cached_tokens":0}},"service_tier":"default"}'
+ recorded_at: Sun, 06 Apr 2025 06:32:47 GMT
+recorded_with: VCR 6.3.1
diff --git a/spec/fixtures/vcr_cassettes/client_tools_calling_returns_unknown_for_non-existent_user.yml b/spec/fixtures/vcr_cassettes/client_tools_calling_returns_unknown_for_non-existent_user.yml
new file mode 100644
index 0000000..23486a4
--- /dev/null
+++ b/spec/fixtures/vcr_cassettes/client_tools_calling_returns_unknown_for_non-existent_user.yml
@@ -0,0 +1,228 @@
+---
+http_interactions:
+- request:
+ method: post
+ uri: http://localhost:8000/chat/completions
+ body:
+ encoding: UTF-8
+ string: '{"messages":[{"role":"user","content":"What is the status of user_999?"}],"model":"gpt-3.5-turbo","stream":false,"tools":[{"type":"function","function":{"name":"UserStatus__get_user_status","description":"Gets
+ the current status of a user based on their ID","parameters":{"type":"object","properties":{"user_id":{"type":"string","description":"The
+ ID of the user to check"}},"required":[],"additionalProperties":false}}}]}'
+ headers:
+ X-Litellm-Timeout:
+ - '120'
+ User-Agent:
+ - Faraday v2.12.2
+ X-Request-Id:
+ - 44039542-c825-42b3-83c6-b4bbed29dfe2
+ Content-Type:
+ - application/json
+ Accept-Encoding:
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
+ Accept:
+ - "*/*"
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Date:
+ - Sun, 06 Apr 2025 06:32:47 GMT
+ Server:
+ - uvicorn
+ Content-Length:
+ - '751'
+ Content-Type:
+ - application/json
+ X-Litellm-Call-Id:
+ - a7f0f418-3500-4e6b-b667-78911e4a6805
+ X-Litellm-Model-Id:
+ - a894f5c6235fa10c0c1755367a3bb2ad54a34654ed3da22bee9da260609709f7
+ X-Litellm-Model-Api-Base:
+ - https://api.openai.com/v1
+ X-Litellm-Version:
+ - 1.61.9
+ X-Litellm-Response-Cost:
+ - 7e-05
+ X-Litellm-Key-Spend:
+ - '0.0'
+ X-Litellm-Response-Duration-Ms:
+ - '834.028'
+ X-Litellm-Overhead-Duration-Ms:
+ - '3.331'
+ X-Ratelimit-Limit-Requests:
+ - '5000'
+ X-Ratelimit-Remaining-Requests:
+ - '4999'
+ X-Ratelimit-Limit-Tokens:
+ - '2000000'
+ X-Ratelimit-Remaining-Tokens:
+ - '1999989'
+ Llm-Provider-Date:
+ - Sun, 06 Apr 2025 06:32:48 GMT
+ Llm-Provider-Content-Type:
+ - application/json
+ Llm-Provider-Transfer-Encoding:
+ - chunked
+ Llm-Provider-Connection:
+ - keep-alive
+ Llm-Provider-Access-Control-Expose-Headers:
+ - X-Request-ID
+ Llm-Provider-Openai-Organization:
+ - user-s7l904mmsyaeoqfhuynmxjmp
+ Llm-Provider-Openai-Processing-Ms:
+ - '402'
+ Llm-Provider-Openai-Version:
+ - '2020-10-01'
+ Llm-Provider-X-Ratelimit-Limit-Requests:
+ - '5000'
+ Llm-Provider-X-Ratelimit-Limit-Tokens:
+ - '2000000'
+ Llm-Provider-X-Ratelimit-Remaining-Requests:
+ - '4999'
+ Llm-Provider-X-Ratelimit-Remaining-Tokens:
+ - '1999989'
+ Llm-Provider-X-Ratelimit-Reset-Requests:
+ - 12ms
+ Llm-Provider-X-Ratelimit-Reset-Tokens:
+ - 0s
+ Llm-Provider-X-Request-Id:
+ - req_bbe0040a2d7728142bda0097dc8394e7
+ Llm-Provider-Strict-Transport-Security:
+ - max-age=31536000; includeSubDomains; preload
+ Llm-Provider-Cf-Cache-Status:
+ - DYNAMIC
+ Llm-Provider-X-Content-Type-Options:
+ - nosniff
+ Llm-Provider-Server:
+ - cloudflare
+ Llm-Provider-Cf-Ray:
+ - 92bf40032fbef9cd-MCT
+ Llm-Provider-Content-Encoding:
+ - gzip
+ Llm-Provider-Alt-Svc:
+ - h3=":443"; ma=86400
+ X-Litellm-Model-Group:
+ - gpt-3.5-turbo
+ X-Litellm-Attempted-Retries:
+ - '0'
+ X-Litellm-Attempted-Fallbacks:
+ - '0'
+ body:
+ encoding: UTF-8
+ string: '{"id":"chatcmpl-BJDqiwPVpwQMDdMXVNNoL7Slb0VxF","created":1743921168,"model":"gpt-3.5-turbo-0125","object":"chat.completion","system_fingerprint":null,"choices":[{"finish_reason":"tool_calls","index":0,"message":{"content":null,"role":"assistant","tool_calls":[{"function":{"arguments":"{\"user_id\":\"user_999\"}","name":"UserStatus__get_user_status"},"id":"call_tRK0jS1uHshFMwfIAShScqGh","type":"function"}],"function_call":null,"refusal":null,"annotations":[]}}],"usage":{"completion_tokens":22,"prompt_tokens":74,"total_tokens":96,"completion_tokens_details":{"accepted_prediction_tokens":0,"audio_tokens":0,"reasoning_tokens":0,"rejected_prediction_tokens":0},"prompt_tokens_details":{"audio_tokens":0,"cached_tokens":0}},"service_tier":"default"}'
+ recorded_at: Sun, 06 Apr 2025 06:32:48 GMT
+- request:
+ method: post
+ uri: http://localhost:8000/chat/completions
+ body:
+ encoding: UTF-8
+ string: '{"messages":[{"role":"user","content":"What is the status of user_999?"},{"content":null,"role":"assistant","tool_calls":[{"function":{"arguments":"{\"user_id\":\"user_999\"}","name":"UserStatus__get_user_status"},"id":"call_tRK0jS1uHshFMwfIAShScqGh","type":"function"}],"function_call":null,"refusal":null,"annotations":[]},{"role":"tool","tool_call_id":"call_tRK0jS1uHshFMwfIAShScqGh","name":"UserStatus__get_user_status","content":"unknown"}],"model":"gpt-3.5-turbo","stream":false,"tools":[{"type":"function","function":{"name":"UserStatus__get_user_status","description":"Gets
+ the current status of a user based on their ID","parameters":{"type":"object","properties":{"user_id":{"type":"string","description":"The
+ ID of the user to check"}},"required":[],"additionalProperties":false}}}]}'
+ headers:
+ X-Litellm-Timeout:
+ - '120'
+ User-Agent:
+ - Faraday v2.12.2
+ X-Request-Id:
+ - 9652d23a-4c71-423f-8ff1-e181cf881754
+ Content-Type:
+ - application/json
+ Accept-Encoding:
+ - gzip;q=1.0,deflate;q=0.6,identity;q=0.3
+ Accept:
+ - "*/*"
+ response:
+ status:
+ code: 200
+ message: OK
+ headers:
+ Date:
+ - Sun, 06 Apr 2025 06:32:48 GMT
+ Server:
+ - uvicorn
+ Content-Length:
+ - '644'
+ Content-Type:
+ - application/json
+ X-Litellm-Call-Id:
+ - fc1b4e36-8e0a-4eca-abf0-da54c78ccdec
+ X-Litellm-Model-Id:
+ - a894f5c6235fa10c0c1755367a3bb2ad54a34654ed3da22bee9da260609709f7
+ X-Litellm-Model-Api-Base:
+ - https://api.openai.com/v1
+ X-Litellm-Version:
+ - 1.61.9
+ X-Litellm-Response-Cost:
+ - '7.2e-05'
+ X-Litellm-Key-Spend:
+ - '0.0'
+ X-Litellm-Response-Duration-Ms:
+ - '576.255'
+ X-Litellm-Overhead-Duration-Ms:
+ - '2.872'
+ X-Ratelimit-Limit-Requests:
+ - '5000'
+ X-Ratelimit-Remaining-Requests:
+ - '4999'
+ X-Ratelimit-Limit-Tokens:
+ - '2000000'
+ X-Ratelimit-Remaining-Tokens:
+ - '1999986'
+ Llm-Provider-Date:
+ - Sun, 06 Apr 2025 06:32:49 GMT
+ Llm-Provider-Content-Type:
+ - application/json
+ Llm-Provider-Transfer-Encoding:
+ - chunked
+ Llm-Provider-Connection:
+ - keep-alive
+ Llm-Provider-Access-Control-Expose-Headers:
+ - X-Request-ID
+ Llm-Provider-Openai-Organization:
+ - user-s7l904mmsyaeoqfhuynmxjmp
+ Llm-Provider-Openai-Processing-Ms:
+ - '257'
+ Llm-Provider-Openai-Version:
+ - '2020-10-01'
+ Llm-Provider-X-Ratelimit-Limit-Requests:
+ - '5000'
+ Llm-Provider-X-Ratelimit-Limit-Tokens:
+ - '2000000'
+ Llm-Provider-X-Ratelimit-Remaining-Requests:
+ - '4999'
+ Llm-Provider-X-Ratelimit-Remaining-Tokens:
+ - '1999986'
+ Llm-Provider-X-Ratelimit-Reset-Requests:
+ - 12ms
+ Llm-Provider-X-Ratelimit-Reset-Tokens:
+ - 0s
+ Llm-Provider-X-Request-Id:
+ - req_55edcf519efb981b0a760e5347a4805d
+ Llm-Provider-Strict-Transport-Security:
+ - max-age=31536000; includeSubDomains; preload
+ Llm-Provider-Cf-Cache-Status:
+ - DYNAMIC
+ Llm-Provider-X-Content-Type-Options:
+ - nosniff
+ Llm-Provider-Server:
+ - cloudflare
+ Llm-Provider-Cf-Ray:
+ - 92bf40088f0ff9cd-MCT
+ Llm-Provider-Content-Encoding:
+ - gzip
+ Llm-Provider-Alt-Svc:
+ - h3=":443"; ma=86400
+ X-Litellm-Model-Group:
+ - gpt-3.5-turbo
+ X-Litellm-Attempted-Retries:
+ - '0'
+ X-Litellm-Attempted-Fallbacks:
+ - '0'
+ body:
+ encoding: UTF-8
+ string: '{"id":"chatcmpl-BJDqiYuMDMpUdbQz6rYESgUaogCSK","created":1743921168,"model":"gpt-3.5-turbo-0125","object":"chat.completion","system_fingerprint":null,"choices":[{"finish_reason":"stop","index":0,"message":{"content":"The
+ status of user_999 is currently unknown.","role":"assistant","tool_calls":null,"function_call":null,"refusal":null,"annotations":[]}}],"usage":{"completion_tokens":12,"prompt_tokens":108,"total_tokens":120,"completion_tokens_details":{"accepted_prediction_tokens":0,"audio_tokens":0,"reasoning_tokens":0,"rejected_prediction_tokens":0},"prompt_tokens_details":{"audio_tokens":0,"cached_tokens":0}},"service_tier":"default"}'
+ recorded_at: Sun, 06 Apr 2025 06:32:49 GMT
+recorded_with: VCR 6.3.1
diff --git a/spec/litellm/chat_spec.rb b/spec/litellm/chat_spec.rb
new file mode 100644
index 0000000..3669d72
--- /dev/null
+++ b/spec/litellm/chat_spec.rb
@@ -0,0 +1,43 @@
+# frozen_string_literal: true
+
+require "spec_helper"
+
+RSpec.describe LiteLLM::Client do
+ include_context "with configured LiteLLM"
+
+ describe "basic chat functionality" do
+ it "can have a basic conversation" do
+ messages = [{ role: "user", content: "What's 2 + 2?" }]
+ response = @client.completion(messages: messages, model: "gpt-3.5-turbo")
+
+ expect(response).to be_a(String)
+ expect(response).to include("4")
+ end
+
+ it "can handle multi-turn conversations" do
+ messages = [
+ { role: "user", content: "Who was Ruby's creator?" },
+ { role: "assistant", content: "Yukihiro Matsumoto (Matz)" },
+ { role: "user", content: "What year did he create Ruby?" }
+ ]
+ response = @client.completion(messages: messages, model: "gpt-3.5-turbo")
+
+ expect(response).to be_a(String)
+ expect(response).to include("199")
+ end
+
+ it "successfully uses the system prompt" do
+ messages = [{ role: "user", content: "Tell me about the weather." }]
+ system_message = 'You must respond like a pirate and include the phrase "Arrr matey!" in your response.'
+
+ response = @client.completion(
+ messages: messages,
+ model: "gpt-3.5-turbo",
+ system_message: system_message
+ )
+
+ expect(response).to be_a(String)
+ expect(response).to include("Arrr matey!")
+ end
+ end
+end
diff --git a/spec/litellm/chat_streaming_spec.rb b/spec/litellm/chat_streaming_spec.rb
new file mode 100644
index 0000000..0519c4d
--- /dev/null
+++ b/spec/litellm/chat_streaming_spec.rb
@@ -0,0 +1,23 @@
+# frozen_string_literal: true
+
+require "spec_helper"
+
+RSpec.describe LiteLLM::Client do
+ include_context "with configured LiteLLM"
+
+ describe "streaming responses" do
+ it "supports streaming responses" do
+ chunks = []
+
+ @client.completion(messages: [{ role: "user", content: "Count from 1 to 3" }], model: "gpt-3.5-turbo", stream: true) do |chunk|
+ chunks << chunk
+ end
+
+ expect(chunks).not_to be_empty
+ expect(chunks).to all(be_a(String))
+ expect(chunks.join).to include("1")
+ expect(chunks.join).to include("2")
+ expect(chunks.join).to include("3")
+ end
+ end
+end
diff --git a/spec/litellm/chat_tools_spec.rb b/spec/litellm/chat_tools_spec.rb
new file mode 100644
index 0000000..526e7c2
--- /dev/null
+++ b/spec/litellm/chat_tools_spec.rb
@@ -0,0 +1,61 @@
+# frozen_string_literal: true
+
+require "spec_helper"
+
+RSpec.describe LiteLLM::Client do
+ include_context "with configured LiteLLM"
+
+ class UserStatus
+ include LiteLLM::Utils::ToolDefinition
+
+ define_function :get_user_status, description: "Gets the current status of a user based on their ID" do
+ property :user_id, type: "string", description: "The ID of the user to check"
+ end
+
+ def get_user_status(user_id:)
+ case user_id
+ when "user_123"
+ "active"
+ when "user_456"
+ "inactive"
+ else
+ "unknown"
+ end
+ end
+ end
+
+ describe "tools calling" do
+ it "returns active for active user" do
+ messages = [{ role: "user", content: "What is the status of user_123?" }]
+
+ response = @client.completion(
+ messages: messages,
+ tools: [UserStatus.new]
+ )
+
+ expect(response).to include("active")
+ end
+
+ it "returns inactive for inactive user" do
+ messages = [{ role: "user", content: "What is the status of user_456?" }]
+
+ response = @client.completion(
+ messages: messages,
+ tools: [UserStatus.new]
+ )
+
+ expect(response).to include("inactive")
+ end
+
+ it "returns unknown for non-existent user" do
+ messages = [{ role: "user", content: "What is the status of user_999?" }]
+
+ response = @client.completion(
+ messages: messages,
+ tools: [UserStatus.new]
+ )
+
+ expect(response).to include("unknown")
+ end
+ end
+end
diff --git a/spec/litellm/embedding_spec.rb b/spec/litellm/embedding_spec.rb
new file mode 100644
index 0000000..b32ad2a
--- /dev/null
+++ b/spec/litellm/embedding_spec.rb
@@ -0,0 +1,27 @@
+# frozen_string_literal: true
+
+require "spec_helper"
+
+RSpec.describe LiteLLM::Client do
+ include_context "with configured LiteLLM"
+
+ describe "embedding generation" do
+ it "generates embeddings for text input" do
+ embedding = @client.embedding(input: "Hello, world!")
+
+ expect(embedding).to be_an(Array)
+ expect(embedding).not_to be_empty
+ expect(embedding.first).to be_a(Float)
+ expect(embedding.size).to eq(1536)
+ end
+
+ it "generates embeddings with custom dimensions" do
+ embedding = @client.embedding(input: "Hello, world!", dimensions: 256)
+
+ expect(embedding).to be_an(Array)
+ expect(embedding).not_to be_empty
+ expect(embedding.first).to be_a(Float)
+ expect(embedding.size).to eq(256)
+ end
+ end
+end
\ No newline at end of file
diff --git a/spec/litellm/image_generation_spec.rb b/spec/litellm/image_generation_spec.rb
new file mode 100644
index 0000000..0f5b40a
--- /dev/null
+++ b/spec/litellm/image_generation_spec.rb
@@ -0,0 +1,19 @@
+# frozen_string_literal: true
+
+require "spec_helper"
+
+RSpec.describe LiteLLM::Client do
+ include_context "with configured LiteLLM"
+
+ describe "image generation" do
+ it "generates an image URL from a prompt" do
+ url = @client.image_generation(prompt: "A beautiful sunset over a calm ocean")
+
+ expect(url).to be_a(String)
+ expect(url).to start_with("https://oaidalleapiprodscus.blob.core.windows.net/private/")
+ expect(url).to include("img-")
+ expect(url).to include(".png")
+ expect(url).to include("&rsct=image/png")
+ end
+ end
+end
\ No newline at end of file
diff --git a/spec/litellm/models_spec.rb b/spec/litellm/models_spec.rb
new file mode 100644
index 0000000..8edd3db
--- /dev/null
+++ b/spec/litellm/models_spec.rb
@@ -0,0 +1,17 @@
+# frozen_string_literal: true
+
+require "spec_helper"
+
+RSpec.describe LiteLLM::Client do
+ include_context "with configured LiteLLM"
+
+ describe "#models" do
+ it "returns a list of available models" do
+ models = @client.models
+
+ expect(models).to be_an(Array)
+ expect(models).to all(be_a(String))
+ expect(models).to match_array(DEFAULT_MODELS)
+ end
+ end
+end
diff --git a/spec/spec_helper.rb b/spec/spec_helper.rb
new file mode 100644
index 0000000..c94f543
--- /dev/null
+++ b/spec/spec_helper.rb
@@ -0,0 +1,93 @@
+# frozen_string_literal: true
+
+require "dotenv/load"
+require "vcr"
+require "active_support/core_ext/string"
+require "bundler/setup"
+require "fileutils"
+require "webmock/rspec"
+
+require "litellm"
+
+VCR.configure do |config|
+ config.cassette_library_dir = "spec/fixtures/vcr_cassettes"
+ config.hook_into :webmock
+ config.configure_rspec_metadata!
+
+ config.default_cassette_options = {
+ record: ENV["CI"] ? :none : :new_episodes
+ }
+
+ FileUtils.mkdir_p(config.cassette_library_dir)
+
+ config.allow_http_connections_when_no_cassette = true
+
+ # Filter out API keys from the recorded cassettes
+ config.filter_sensitive_data("") { ENV.fetch("OPENAI_API_KEY", nil) }
+ config.filter_sensitive_data("") { ENV.fetch("ANTHROPIC_API_KEY", nil) }
+ config.filter_sensitive_data("") { ENV.fetch("GEMINI_API_KEY", nil) }
+ config.filter_sensitive_data("") { ENV.fetch("DEEPSEEK_API_KEY", nil) }
+
+ config.filter_sensitive_data("") { ENV.fetch("AWS_ACCESS_KEY_ID", nil) }
+ config.filter_sensitive_data("") do
+ ENV.fetch("AWS_SECRET_ACCESS_KEY", nil)
+ end
+ config.filter_sensitive_data("") { ENV.fetch("AWS_REGION", "us-west-2") }
+ config.filter_sensitive_data("") { ENV.fetch("AWS_SESSION_TOKEN", nil) }
+
+ config.filter_sensitive_data("") do |interaction|
+ interaction.response.headers["Openai-Organization"]&.first
+ end
+ config.filter_sensitive_data("") do |interaction|
+ interaction.response.headers["X-Request-Id"]&.first
+ end
+ config.filter_sensitive_data("") do |interaction|
+ interaction.response.headers["Request-Id"]&.first
+ end
+ config.filter_sensitive_data("") do |interaction|
+ interaction.response.headers["Cf-Ray"]&.first
+ end
+
+ # Filter cookies
+ config.before_record do |interaction|
+ if interaction.response.headers["Set-Cookie"]
+ interaction.response.headers["Set-Cookie"] = interaction.response.headers["Set-Cookie"].map do
+ ""
+ end
+ end
+ end
+end
+
+RSpec.configure do |config|
+ # Enable flags like --only-failures and --next-failure
+ config.example_status_persistence_file_path = ".rspec_status"
+
+ # Disable RSpec exposing methods globally on `Module` and `main`
+ config.disable_monkey_patching!
+
+ config.expect_with :rspec do |c|
+ c.syntax = :expect
+ end
+
+ config.around do |example|
+ cassette_name = example.full_description.parameterize(separator: "_").delete_prefix("litellm_")
+ VCR.use_cassette(cassette_name) do
+ example.run
+ end
+ end
+end
+
+RSpec.shared_context "with configured LiteLLM" do
+ DEFAULT_MODELS = ["gpt-3.5-turbo", "dall-e-2", "text-embedding-3-small"].freeze
+
+ before do
+ LiteLLM.configure do |config|
+ config.base_url = "http://localhost:8000"
+ config.model = "gpt-3.5-turbo"
+ config.embedding_model = "text-embedding-3-small"
+ config.image_model = "dall-e-2"
+ end
+
+ @client = LiteLLM::Client.new
+ end
+end
diff --git a/test_server/litellm_config.yaml b/test_server/litellm_config.yaml
new file mode 100644
index 0000000..729eab8
--- /dev/null
+++ b/test_server/litellm_config.yaml
@@ -0,0 +1,18 @@
+model_list:
+ - model_name: gpt-3.5-turbo
+ litellm_params:
+ model: openai/gpt-3.5-turbo
+ api_base: https://api.openai.com/v1
+ api_key: os.environ/OPENAI_API_KEY
+
+ - model_name: text-embedding-3-small
+ litellm_params:
+ model: openai/text-embedding-3-small
+ api_base: https://api.openai.com/v1
+ api_key: os.environ/OPENAI_API_KEY
+
+ - model_name: dall-e-2
+ litellm_params:
+ model: openai/dall-e-2
+ api_base: https://api.openai.com/v1
+ api_key: os.environ/OPENAI_API_KEY
\ No newline at end of file
diff --git a/test_server/start_litellm.sh b/test_server/start_litellm.sh
new file mode 100755
index 0000000..d5e8fb6
--- /dev/null
+++ b/test_server/start_litellm.sh
@@ -0,0 +1,21 @@
+#!/bin/bash
+
+if [ -f "$(pwd)/../.env" ]; then
+ source "$(pwd)/../.env"
+else
+ echo "Warning: .env file not found in parent directory"
+fi
+
+CONFIG_PATH="$(pwd)/litellm_config.yaml"
+
+if [ ! -f "$CONFIG_PATH" ]; then
+ echo "Error: litellm_config.yaml not found in $(pwd)"
+ exit 1
+fi
+
+docker run \
+ -v "$CONFIG_PATH":/app/config.yaml \
+ -e OPENAI_API_KEY="$OPENAI_API_KEY" \
+ -p 8000:4000 \
+ ghcr.io/berriai/litellm:main-latest \
+ --config /app/config.yaml --detailed_debug
\ No newline at end of file