├── .circleci └── config.yml ├── .devcontainer ├── Dockerfile ├── devcontainer.json └── docker-compose.yml ├── .github ├── FUNDING.yml ├── ISSUE_TEMPLATE │ ├── bug_report.md │ └── feature_request.md └── dependabot.yml ├── .gitignore ├── .rspec ├── .rubocop.yml ├── CHANGELOG.md ├── CODE_OF_CONDUCT.md ├── CONTRIBUTING.md ├── Gemfile ├── Gemfile.lock ├── LICENSE.txt ├── README.md ├── Rakefile ├── bin ├── console └── setup ├── lib ├── openai.rb ├── openai │ ├── assistants.rb │ ├── audio.rb │ ├── batches.rb │ ├── client.rb │ ├── compatibility.rb │ ├── files.rb │ ├── finetunes.rb │ ├── http.rb │ ├── http_headers.rb │ ├── images.rb │ ├── messages.rb │ ├── models.rb │ ├── run_steps.rb │ ├── runs.rb │ ├── threads.rb │ ├── vector_store_file_batches.rb │ ├── vector_store_files.rb │ ├── vector_stores.rb │ └── version.rb └── ruby │ └── openai.rb ├── pull_request_template.md ├── ruby-openai.gemspec └── spec ├── compatibility_spec.rb ├── fixtures ├── cassettes │ ├── assistants_create.yml │ ├── assistants_delete.yml │ ├── assistants_delete_setup.yml │ ├── assistants_list.yml │ ├── assistants_list_setup.yml │ ├── assistants_modify.yml │ ├── assistants_modify_setup.yml │ ├── assistants_retrieve.yml │ ├── assistants_retrieve_setup.yml │ ├── audio_whisper-1_transcribe.yml │ ├── audio_whisper-1_translate.yml │ ├── batches_cancel.yml │ ├── batches_cancel_input.yml │ ├── batches_cancel_setup.yml │ ├── batches_create.yml │ ├── batches_create_input.yml │ ├── batches_list.yml │ ├── batches_list_input.yml │ ├── batches_list_setup.yml │ ├── batches_retrieve.yml │ ├── batches_retrieve_input.yml │ ├── batches_retrieve_setup.yml │ ├── files_content.yml │ ├── files_content_upload.yml │ ├── files_delete.yml │ ├── files_delete_retrieve.yml │ ├── files_delete_upload.yml │ ├── files_list.yml │ ├── files_list_upload.yml │ ├── files_retrieve.yml │ ├── files_retrieve_upload.yml │ ├── files_upload_file.yml │ ├── files_upload_stringio.yml │ ├── files_upload_vision.yml │ ├── finetunes_cancel.yml │ ├── finetunes_create.yml │ ├── finetunes_event_list.yml │ ├── finetunes_files_upload.yml │ ├── finetunes_list.yml │ ├── finetunes_retrieve.yml │ ├── finetunes_retrieve_for_create.yml │ ├── gpt-3_5-turbo-0301_chat.yml │ ├── gpt-3_5-turbo-instruct_completions_once_upon_a_time.yml │ ├── gpt-3_5-turbo_chat.yml │ ├── gpt-3_5-turbo_streamed_chat.yml │ ├── gpt-3_5-turbo_streamed_chat_with_error_response.yml │ ├── gpt-3_5-turbo_streamed_chat_with_json_error_response.yml │ ├── gpt-3_5-turbo_streamed_chat_without_proc.yml │ ├── gpt-3_5-turbo_valid_tool_call_chat.yml │ ├── groq_llama3-8b-8192_streamed_chat.yml │ ├── http_get_with_error_response.yml │ ├── images_edit_image_png_A_solid_red_Ruby_on_a_blue_background.yml │ ├── images_generate_A_baby_sea_otter_cooking_pasta_wearing_a_hat_of_some_sort.yml │ ├── images_generate_A_lion_cooking_pasta_wearing_a_hat_of_some_sort.yml │ ├── images_generate_A_springer_spaniel_cooking_pasta_wearing_a_hat_of_some_sort.yml │ ├── images_variations_image_png.yml │ ├── messages_create.yml │ ├── messages_create_thread_setup.yml │ ├── messages_list.yml │ ├── messages_list_thread_setup.yml │ ├── messages_modify.yml │ ├── messages_modify_message_setup.yml │ ├── messages_modify_thread_setup.yml │ ├── messages_retrieve.yml │ ├── messages_retrieve_message_setup.yml │ ├── messages_retrieve_thread_setup.yml │ ├── models_list.yml │ ├── models_retrieve.yml │ ├── moderations_i_m_worried_about_that_.yml │ ├── ollama_llama3_chat.yml │ ├── run_steps_list.yml │ ├── run_steps_list_assistant_setup.yml │ ├── run_steps_list_run_setup.yml │ ├── run_steps_list_thread_setup.yml │ ├── run_steps_retrieve.yml │ ├── run_steps_retrieve_assistant_setup.yml │ ├── run_steps_retrieve_run_setup.yml │ ├── run_steps_retrieve_thread_setup.yml │ ├── runs_cancel.yml │ ├── runs_cancel_assistant_setup.yml │ ├── runs_cancel_run_setup.yml │ ├── runs_cancel_thread_setup.yml │ ├── runs_create.yml │ ├── runs_create_assistant_setup.yml │ ├── runs_create_thread_and_run.yml │ ├── runs_create_thread_and_run_assistant_setup.yml │ ├── runs_create_thread_setup.yml │ ├── runs_list.yml │ ├── runs_list_assistant_setup.yml │ ├── runs_list_run_setup.yml │ ├── runs_list_thread_setup.yml │ ├── runs_modify.yml │ ├── runs_modify_assistant_setup.yml │ ├── runs_modify_run_setup.yml │ ├── runs_modify_thread_setup.yml │ ├── runs_retrieve.yml │ ├── runs_retrieve_assistant_setup.yml │ ├── runs_retrieve_run_setup.yml │ ├── runs_retrieve_thread_setup.yml │ ├── runs_streamed_create.yml │ ├── runs_streamed_create_assistant_setup.yml │ ├── runs_streamed_create_thread_setup.yml │ ├── runs_submit_tool_outputs.yml │ ├── runs_submit_tool_outputs_assistant_setup.yml │ ├── runs_submit_tool_outputs_run_setup.yml │ ├── runs_submit_tool_outputs_thread_setup.yml │ ├── speech_tts-1_test.yml │ ├── text-embedding-ada-002_embeddings_the_food_was_delicious_and_the_waiter_.yml │ ├── threads_create.yml │ ├── threads_delete.yml │ ├── threads_delete_setup.yml │ ├── threads_modify.yml │ ├── threads_modify_setup.yml │ ├── threads_retrieve.yml │ ├── threads_retrieve_setup.yml │ ├── vector_store_file_batches_cancel.yml │ ├── vector_store_file_batches_cancel_file_setup.yml │ ├── vector_store_file_batches_cancel_vector_store_file_batch_setup.yml │ ├── vector_store_file_batches_cancel_vector_store_setup.yml │ ├── vector_store_file_batches_create.yml │ ├── vector_store_file_batches_create_file_setup.yml │ ├── vector_store_file_batches_create_vector_store_setup.yml │ ├── vector_store_file_batches_list.yml │ ├── vector_store_file_batches_list_file_setup.yml │ ├── vector_store_file_batches_list_vector_store_file_batch_setup.yml │ ├── vector_store_file_batches_list_vector_store_setup.yml │ ├── vector_store_file_batches_retrieve.yml │ ├── vector_store_file_batches_retrieve_file_setup.yml │ ├── vector_store_file_batches_retrieve_vector_store_file_batch_setup.yml │ ├── vector_store_file_batches_retrieve_vector_store_setup.yml │ ├── vector_store_files_create.yml │ ├── vector_store_files_create_file_setup.yml │ ├── vector_store_files_create_vector_store_setup.yml │ ├── vector_store_files_delete.yml │ ├── vector_store_files_delete_file_setup.yml │ ├── vector_store_files_delete_vector_store_file_setup.yml │ ├── vector_store_files_delete_vector_store_setup.yml │ ├── vector_store_files_list.yml │ ├── vector_store_files_list_file_setup.yml │ ├── vector_store_files_list_vector_store_file_setup.yml │ ├── vector_store_files_list_vector_store_setup.yml │ ├── vector_store_files_retrieve.yml │ ├── vector_store_files_retrieve_file_setup.yml │ ├── vector_store_files_retrieve_vector_store_file_setup.yml │ ├── vector_store_files_retrieve_vector_store_setup.yml │ ├── vector_stores_create.yml │ ├── vector_stores_delete.yml │ ├── vector_stores_delete_setup.yml │ ├── vector_stores_list.yml │ ├── vector_stores_list_setup.yml │ ├── vector_stores_modify.yml │ ├── vector_stores_modify_setup.yml │ ├── vector_stores_retrieve.yml │ └── vector_stores_retrieve_setup.yml └── files │ ├── audio_sample.mp3 │ ├── batch.jsonl │ ├── errors │ └── missing_quote.jsonl │ ├── image.png │ ├── mask.png │ ├── sarcastic.jsonl │ ├── sentiment.jsonl │ ├── text.txt │ └── train.jsonl ├── openai └── client │ ├── assistants_spec.rb │ ├── audio_spec.rb │ ├── batches_spec.rb │ ├── chat_spec.rb │ ├── client_spec.rb │ ├── completions_spec.rb │ ├── embeddings_spec.rb │ ├── files_spec.rb │ ├── finetunes_spec.rb │ ├── http_spec.rb │ ├── images_spec.rb │ ├── messages_spec.rb │ ├── models_spec.rb │ ├── moderations_spec.rb │ ├── run_steps_spec.rb │ ├── runs_spec.rb │ ├── threads_spec.rb │ ├── vector_store_file_batches_spec.rb │ ├── vector_store_files_spec.rb │ └── vector_stores_spec.rb ├── openai_spec.rb ├── spec_helper.rb └── support └── vcr_multipart_matcher.rb /.circleci/config.yml: -------------------------------------------------------------------------------- 1 | version: 2.1 # Use 2.1 to enable using orbs and other features. 2 | 3 | # Declare the orbs that we'll use in our config. 4 | orbs: 5 | ruby: circleci/ruby@1.0 6 | 7 | jobs: 8 | rubocop: 9 | parallelism: 1 10 | docker: 11 | - image: cimg/ruby:3.2-node 12 | steps: 13 | - checkout 14 | - ruby/install-deps 15 | - run: 16 | name: Run Rubocop 17 | command: bundle exec rubocop 18 | test: 19 | parameters: 20 | ruby-image: 21 | type: string 22 | parallelism: 1 23 | docker: 24 | - image: << parameters.ruby-image >> 25 | steps: 26 | - checkout 27 | - ruby/install-deps 28 | - run: 29 | name: Run tests 30 | command: bundle exec rspec -fd 31 | 32 | workflows: 33 | version: 2 34 | checks: 35 | jobs: 36 | - rubocop 37 | - test: 38 | matrix: 39 | parameters: 40 | ruby-image: 41 | - cimg/ruby:2.6-node 42 | - cimg/ruby:2.7-node 43 | - cimg/ruby:3.0-node 44 | - cimg/ruby:3.1-node 45 | - cimg/ruby:3.2-node 46 | - cimg/ruby:3.3-node 47 | -------------------------------------------------------------------------------- /.devcontainer/Dockerfile: -------------------------------------------------------------------------------- 1 | FROM ruby:3.2.2-slim-bullseye 2 | 3 | ENV TZ="Europe/London" 4 | 5 | RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \ 6 | && apt-get -y install --no-install-recommends \ 7 | apt-utils \ 8 | build-essential \ 9 | curl \ 10 | git \ 11 | vim \ 12 | zsh 13 | 14 | RUN gem install bundler 15 | 16 | WORKDIR /workspace 17 | -------------------------------------------------------------------------------- /.devcontainer/devcontainer.json: -------------------------------------------------------------------------------- 1 | // For format details, see https://aka.ms/devcontainer.json. For config options, see the README at: 2 | // https://github.com/microsoft/vscode-dev-containers/tree/v0.245.2/containers/ruby-rails-postgres 3 | // Update the VARIANT arg in docker-compose.yml to pick a Ruby version 4 | { 5 | "name": "ruby-openai", 6 | "dockerComposeFile": "docker-compose.yml", 7 | "service": "app", 8 | "workspaceFolder": "/workspace", 9 | "containerEnv": { 10 | "GITHUB_TOKEN": "${localEnv:GITHUB_TOKEN}", 11 | "GITHUB_USER": "${localEnv:GITHUB_USER}" 12 | }, 13 | // Configure tool-specific properties. 14 | "customizations": { 15 | // Configure properties specific to VS Code. 16 | "vscode": { 17 | // Add the IDs of extensions you want installed when the container is created. 18 | "extensions": [ 19 | "rebornix.Ruby", 20 | "sleistner.vscode-fileutils", 21 | "ms-azuretools.vscode-docker", 22 | "samverschueren.final-newline", 23 | "GitHub.copilot", 24 | "usernamehw.remove-empty-lines", 25 | "wingrunr21.vscode-ruby", 26 | ] 27 | } 28 | }, 29 | // Use 'postCreateCommand' to run commands after the container is created. 30 | "postCreateCommand": "bundle install", 31 | // Comment out to connect as root instead. More info: https://aka.ms/vscode-remote/containers/non-root. 32 | "features": { 33 | "git": "os-provided", 34 | "github-cli": "latest" 35 | } 36 | } 37 | -------------------------------------------------------------------------------- /.devcontainer/docker-compose.yml: -------------------------------------------------------------------------------- 1 | version: "3" 2 | 3 | services: 4 | app: 5 | build: 6 | context: .. 7 | dockerfile: .devcontainer/Dockerfile 8 | 9 | volumes: 10 | - ..:/workspace:cached 11 | - bundle_cache:/bundle 12 | 13 | command: sleep infinity 14 | 15 | environment: 16 | TZ: Europe/London 17 | 18 | volumes: 19 | bundle_cache: 20 | -------------------------------------------------------------------------------- /.github/FUNDING.yml: -------------------------------------------------------------------------------- 1 | # These are supported funding model platforms 2 | 3 | github: alexrudall 4 | patreon: # Replace with a single Patreon username 5 | open_collective: # Replace with a single Open Collective username 6 | ko_fi: # Replace with a single Ko-fi username 7 | tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel 8 | community_bridge: # Replace with a single Community Bridge project-name e.g., cloud-foundry 9 | liberapay: # Replace with a single Liberapay username 10 | issuehunt: # Replace with a single IssueHunt username 11 | otechie: # Replace with a single Otechie username 12 | lfx_crowdfunding: # Replace with a single LFX Crowdfunding project-name e.g., cloud-foundry 13 | custom: # Replace with up to 4 custom sponsorship URLs e.g., ['link1', 'link2'] 14 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/bug_report.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Bug report 3 | about: Create a report to help us improve 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Describe the bug** 11 | A clear and concise description of what the bug is. 12 | 13 | **To Reproduce** 14 | Steps to reproduce the behavior: 15 | 1. Go to '...' 16 | 2. Click on '....' 17 | 3. Scroll down to '....' 18 | 4. See error 19 | 20 | **Expected behavior** 21 | A clear and concise description of what you expected to happen. 22 | 23 | **Screenshots** 24 | If applicable, add screenshots to help explain your problem. 25 | 26 | **Desktop (please complete the following information):** 27 | - OS: [e.g. iOS] 28 | - Browser [e.g. chrome, safari] 29 | - Version [e.g. 22] 30 | 31 | **Smartphone (please complete the following information):** 32 | - Device: [e.g. iPhone6] 33 | - OS: [e.g. iOS8.1] 34 | - Browser [e.g. stock browser, safari] 35 | - Version [e.g. 22] 36 | 37 | **Additional context** 38 | Add any other context about the problem here. 39 | -------------------------------------------------------------------------------- /.github/ISSUE_TEMPLATE/feature_request.md: -------------------------------------------------------------------------------- 1 | --- 2 | name: Feature request 3 | about: Suggest an idea for this project 4 | title: '' 5 | labels: '' 6 | assignees: '' 7 | 8 | --- 9 | 10 | **Is your feature request related to a problem? Please describe.** 11 | A clear and concise description of what the problem is. Ex. I'm always frustrated when [...] 12 | 13 | **Describe the solution you'd like** 14 | A clear and concise description of what you want to happen. 15 | 16 | **Describe alternatives you've considered** 17 | A clear and concise description of any alternative solutions or features you've considered. 18 | 19 | **Additional context** 20 | Add any other context or screenshots about the feature request here. 21 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: bundler 4 | directory: "/" 5 | schedule: 6 | interval: daily 7 | open-pull-requests-limit: 10 8 | ignore: 9 | - dependency-name: webmock 10 | versions: 11 | - 3.11.1 12 | - 3.11.3 13 | - dependency-name: rspec 14 | versions: 15 | - 3.10.0 16 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | ### Ruby ### 2 | *.gem 3 | *.rbc 4 | /.config 5 | /coverage/ 6 | /InstalledFiles 7 | /pkg/ 8 | /spec/reports/ 9 | /spec/examples.txt 10 | /test/tmp/ 11 | /test/version_tmp/ 12 | /tmp/ 13 | 14 | # Used by dotenv library to load environment variables. 15 | .env 16 | 17 | # Ignore Byebug command history file. 18 | .byebug_history 19 | 20 | ## Specific to RubyMotion: 21 | .dat* 22 | .repl_history 23 | build/ 24 | *.bridgesupport 25 | build-iPhoneOS/ 26 | build-iPhoneSimulator/ 27 | 28 | ## Specific to RubyMotion (use of CocoaPods): 29 | # 30 | # We recommend against adding the Pods directory to your .gitignore. However 31 | # you should judge for yourself, the pros and cons are mentioned at: 32 | # https://guides.cocoapods.org/using/using-cocoapods.html#should-i-check-the-pods-directory-into-source-control 33 | # vendor/Pods/ 34 | 35 | ## Documentation cache and generated files: 36 | /.yardoc/ 37 | /_yardoc/ 38 | /doc/ 39 | /rdoc/ 40 | 41 | ## Environment normalization: 42 | /.bundle/ 43 | /vendor/bundle 44 | /lib/bundler/man/ 45 | 46 | # for a library or gem, you might want to ignore these files since the code is 47 | # intended to run in multiple environments; otherwise, check them in: 48 | # Gemfile.lock 49 | # .ruby-version 50 | # .ruby-gemset 51 | 52 | # unless supporting rvm < 1.11.0 or doing something fancy, ignore this: 53 | .rvmrc 54 | 55 | # Used by RuboCop. Remote config files pulled in from inherit_from directive. 56 | # .rubocop-https?--* 57 | 58 | # rspec failure tracking 59 | .rspec_status 60 | 61 | # IDE 62 | .idea 63 | .idea/ 64 | .idea/* 65 | .vscode 66 | .vs/ 67 | 68 | # Mac 69 | .DS_Store 70 | -------------------------------------------------------------------------------- /.rspec: -------------------------------------------------------------------------------- 1 | --format documentation 2 | --color 3 | --require spec_helper 4 | -------------------------------------------------------------------------------- /.rubocop.yml: -------------------------------------------------------------------------------- 1 | AllCops: 2 | TargetRubyVersion: 2.6 3 | NewCops: enable 4 | SuggestExtensions: false 5 | 6 | Style/Documentation: 7 | # Skips checking to make sure top level modules / classes have a comment. 8 | Enabled: false 9 | 10 | Layout/LineLength: 11 | Max: 100 12 | Exclude: 13 | - "**/*.gemspec" 14 | 15 | Lint/AmbiguousOperator: 16 | # https://github.com/rubocop/rubocop/issues/4294 17 | Exclude: 18 | - "lib/openai/client.rb" 19 | 20 | Metrics/AbcSize: 21 | Max: 20 22 | 23 | Metrics/BlockLength: 24 | Exclude: 25 | - "spec/**/*" 26 | 27 | Style/StringLiterals: 28 | EnforcedStyle: double_quotes 29 | 30 | Style/FrozenStringLiteralComment: 31 | Enabled: false 32 | -------------------------------------------------------------------------------- /CONTRIBUTING.md: -------------------------------------------------------------------------------- 1 | ## Contributing 2 | 3 | Bug reports and pull requests are welcome on GitHub at https://github.com/alexrudall/ruby-openai. This project is intended to be a safe, welcoming space for collaboration, and contributors are expected to adhere to the [code of conduct](https://github.com/alexrudall/ruby-openai/blob/main/CODE_OF_CONDUCT.md). 4 | -------------------------------------------------------------------------------- /Gemfile: -------------------------------------------------------------------------------- 1 | source "https://rubygems.org" 2 | 3 | # Include gem dependencies from ruby-openai.gemspec 4 | gemspec 5 | 6 | gem "byebug", "~> 11.1.3" 7 | gem "dotenv", "~> 2.8.1" 8 | gem "rake", "~> 13.2" 9 | gem "rspec", "~> 3.13" 10 | gem "rubocop", "~> 1.50.2" 11 | gem "vcr", "~> 6.1.0" 12 | gem "webmock", "~> 3.23.1" 13 | -------------------------------------------------------------------------------- /Gemfile.lock: -------------------------------------------------------------------------------- 1 | PATH 2 | remote: . 3 | specs: 4 | ruby-openai (7.1.0) 5 | event_stream_parser (>= 0.3.0, < 2.0.0) 6 | faraday (>= 1) 7 | faraday-multipart (>= 1) 8 | 9 | GEM 10 | remote: https://rubygems.org/ 11 | specs: 12 | addressable (2.8.6) 13 | public_suffix (>= 2.0.2, < 6.0) 14 | ast (2.4.2) 15 | base64 (0.2.0) 16 | bigdecimal (3.1.8) 17 | byebug (11.1.3) 18 | crack (1.0.0) 19 | bigdecimal 20 | rexml 21 | diff-lcs (1.5.1) 22 | dotenv (2.8.1) 23 | event_stream_parser (1.0.0) 24 | faraday (2.8.1) 25 | base64 26 | faraday-net_http (>= 2.0, < 3.1) 27 | ruby2_keywords (>= 0.0.4) 28 | faraday-multipart (1.0.4) 29 | multipart-post (~> 2) 30 | faraday-net_http (3.0.2) 31 | hashdiff (1.1.0) 32 | json (2.6.3) 33 | multipart-post (2.3.0) 34 | parallel (1.22.1) 35 | parser (3.2.2.0) 36 | ast (~> 2.4.1) 37 | public_suffix (5.0.5) 38 | rainbow (3.1.1) 39 | rake (13.2.1) 40 | regexp_parser (2.8.0) 41 | rexml (3.2.9) 42 | strscan 43 | rspec (3.13.0) 44 | rspec-core (~> 3.13.0) 45 | rspec-expectations (~> 3.13.0) 46 | rspec-mocks (~> 3.13.0) 47 | rspec-core (3.13.0) 48 | rspec-support (~> 3.13.0) 49 | rspec-expectations (3.13.0) 50 | diff-lcs (>= 1.2.0, < 2.0) 51 | rspec-support (~> 3.13.0) 52 | rspec-mocks (3.13.0) 53 | diff-lcs (>= 1.2.0, < 2.0) 54 | rspec-support (~> 3.13.0) 55 | rspec-support (3.13.1) 56 | rubocop (1.50.2) 57 | json (~> 2.3) 58 | parallel (~> 1.10) 59 | parser (>= 3.2.0.0) 60 | rainbow (>= 2.2.2, < 4.0) 61 | regexp_parser (>= 1.8, < 3.0) 62 | rexml (>= 3.2.5, < 4.0) 63 | rubocop-ast (>= 1.28.0, < 2.0) 64 | ruby-progressbar (~> 1.7) 65 | unicode-display_width (>= 2.4.0, < 3.0) 66 | rubocop-ast (1.28.0) 67 | parser (>= 3.2.1.0) 68 | ruby-progressbar (1.13.0) 69 | ruby2_keywords (0.0.5) 70 | strscan (3.1.0) 71 | unicode-display_width (2.4.2) 72 | vcr (6.1.0) 73 | webmock (3.23.1) 74 | addressable (>= 2.8.0) 75 | crack (>= 0.3.2) 76 | hashdiff (>= 0.4.0, < 2.0.0) 77 | 78 | PLATFORMS 79 | ruby 80 | 81 | DEPENDENCIES 82 | byebug (~> 11.1.3) 83 | dotenv (~> 2.8.1) 84 | rake (~> 13.2) 85 | rspec (~> 3.13) 86 | rubocop (~> 1.50.2) 87 | ruby-openai! 88 | vcr (~> 6.1.0) 89 | webmock (~> 3.23.1) 90 | 91 | BUNDLED WITH 92 | 2.4.5 93 | -------------------------------------------------------------------------------- /LICENSE.txt: -------------------------------------------------------------------------------- 1 | The MIT License (MIT) 2 | 3 | Copyright (c) 2020 Alex 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in 13 | all copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN 21 | THE SOFTWARE. 22 | -------------------------------------------------------------------------------- /Rakefile: -------------------------------------------------------------------------------- 1 | require "bundler/gem_tasks" 2 | require "rspec/core/rake_task" 3 | require "rubocop/rake_task" 4 | 5 | RSpec::Core::RakeTask.new(:spec) 6 | 7 | task :default do 8 | Rake::Task["test"].invoke 9 | Rake::Task["lint"].invoke 10 | end 11 | 12 | task :test do 13 | Rake::Task["spec"].invoke 14 | end 15 | 16 | task :lint do 17 | RuboCop::RakeTask.new(:rubocop) 18 | Rake::Task["rubocop"].invoke 19 | end 20 | -------------------------------------------------------------------------------- /bin/console: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env ruby 2 | 3 | require "bundler/setup" 4 | require "openai" 5 | 6 | # You can add fixtures and/or initialization code here to make experimenting 7 | # with your gem easier. You can also use a different console, if you like. 8 | 9 | # (If you use this, don't forget to add pry to your Gemfile!) 10 | # require "pry" 11 | # Pry.start 12 | 13 | require "irb" 14 | IRB.start(__FILE__) 15 | -------------------------------------------------------------------------------- /bin/setup: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | set -euo pipefail 3 | IFS=$'\n\t' 4 | set -vx 5 | 6 | bundle install 7 | 8 | # Do any other automated setup that you need to do here 9 | -------------------------------------------------------------------------------- /lib/openai.rb: -------------------------------------------------------------------------------- 1 | require "faraday" 2 | require "faraday/multipart" 3 | 4 | require_relative "openai/http" 5 | require_relative "openai/client" 6 | require_relative "openai/files" 7 | require_relative "openai/finetunes" 8 | require_relative "openai/images" 9 | require_relative "openai/models" 10 | require_relative "openai/assistants" 11 | require_relative "openai/threads" 12 | require_relative "openai/messages" 13 | require_relative "openai/runs" 14 | require_relative "openai/run_steps" 15 | require_relative "openai/vector_stores" 16 | require_relative "openai/vector_store_files" 17 | require_relative "openai/vector_store_file_batches" 18 | require_relative "openai/audio" 19 | require_relative "openai/version" 20 | require_relative "openai/batches" 21 | 22 | module OpenAI 23 | class Error < StandardError; end 24 | class ConfigurationError < Error; end 25 | 26 | class MiddlewareErrors < Faraday::Middleware 27 | def call(env) 28 | @app.call(env) 29 | rescue Faraday::Error => e 30 | raise e unless e.response.is_a?(Hash) 31 | 32 | logger = Logger.new($stdout) 33 | logger.formatter = proc do |_severity, _datetime, _progname, msg| 34 | "\033[31mOpenAI HTTP Error (spotted in ruby-openai #{VERSION}): #{msg}\n\033[0m" 35 | end 36 | logger.error(e.response[:body]) 37 | 38 | raise e 39 | end 40 | end 41 | 42 | class Configuration 43 | attr_accessor :access_token, 44 | :api_type, 45 | :api_version, 46 | :log_errors, 47 | :organization_id, 48 | :uri_base, 49 | :request_timeout, 50 | :extra_headers 51 | 52 | DEFAULT_API_VERSION = "v1".freeze 53 | DEFAULT_URI_BASE = "https://api.openai.com/".freeze 54 | DEFAULT_REQUEST_TIMEOUT = 120 55 | DEFAULT_LOG_ERRORS = false 56 | 57 | def initialize 58 | @access_token = nil 59 | @api_type = nil 60 | @api_version = DEFAULT_API_VERSION 61 | @log_errors = DEFAULT_LOG_ERRORS 62 | @organization_id = nil 63 | @uri_base = DEFAULT_URI_BASE 64 | @request_timeout = DEFAULT_REQUEST_TIMEOUT 65 | @extra_headers = {} 66 | end 67 | end 68 | 69 | class << self 70 | attr_writer :configuration 71 | end 72 | 73 | def self.configuration 74 | @configuration ||= OpenAI::Configuration.new 75 | end 76 | 77 | def self.configure 78 | yield(configuration) 79 | end 80 | 81 | # Estimate the number of tokens in a string, using the rules of thumb from OpenAI: 82 | # https://help.openai.com/en/articles/4936856-what-are-tokens-and-how-to-count-them 83 | def self.rough_token_count(content = "") 84 | raise ArgumentError, "rough_token_count requires a string" unless content.is_a? String 85 | return 0 if content.empty? 86 | 87 | count_by_chars = content.size / 4.0 88 | count_by_words = content.split.size * 4.0 / 3 89 | estimate = ((count_by_chars + count_by_words) / 2.0).round 90 | [1, estimate].max 91 | end 92 | end 93 | -------------------------------------------------------------------------------- /lib/openai/assistants.rb: -------------------------------------------------------------------------------- 1 | module OpenAI 2 | class Assistants 3 | BETA_VERSION = "v2".freeze 4 | 5 | def initialize(client:) 6 | @client = client.beta(assistants: OpenAI::Assistants::BETA_VERSION) 7 | end 8 | 9 | def list 10 | @client.get(path: "/assistants") 11 | end 12 | 13 | def retrieve(id:) 14 | @client.get(path: "/assistants/#{id}") 15 | end 16 | 17 | def create(parameters: {}) 18 | @client.json_post(path: "/assistants", parameters: parameters) 19 | end 20 | 21 | def modify(id:, parameters: {}) 22 | @client.json_post(path: "/assistants/#{id}", parameters: parameters) 23 | end 24 | 25 | def delete(id:) 26 | @client.delete(path: "/assistants/#{id}") 27 | end 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /lib/openai/audio.rb: -------------------------------------------------------------------------------- 1 | module OpenAI 2 | class Audio 3 | def initialize(client:) 4 | @client = client 5 | end 6 | 7 | def transcribe(parameters: {}) 8 | @client.multipart_post(path: "/audio/transcriptions", parameters: parameters) 9 | end 10 | 11 | def translate(parameters: {}) 12 | @client.multipart_post(path: "/audio/translations", parameters: parameters) 13 | end 14 | 15 | def speech(parameters: {}) 16 | @client.json_post(path: "/audio/speech", parameters: parameters) 17 | end 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /lib/openai/batches.rb: -------------------------------------------------------------------------------- 1 | module OpenAI 2 | class Batches 3 | def initialize(client:) 4 | @client = client.beta(assistants: OpenAI::Assistants::BETA_VERSION) 5 | end 6 | 7 | def list(parameters: {}) 8 | @client.get(path: "/batches", parameters: parameters) 9 | end 10 | 11 | def retrieve(id:) 12 | @client.get(path: "/batches/#{id}") 13 | end 14 | 15 | def create(parameters: {}) 16 | @client.json_post(path: "/batches", parameters: parameters) 17 | end 18 | 19 | def cancel(id:) 20 | @client.post(path: "/batches/#{id}/cancel") 21 | end 22 | end 23 | end 24 | -------------------------------------------------------------------------------- /lib/openai/compatibility.rb: -------------------------------------------------------------------------------- 1 | module Ruby 2 | module OpenAI 3 | VERSION = ::OpenAI::VERSION 4 | 5 | Error = ::OpenAI::Error 6 | ConfigurationError = ::OpenAI::ConfigurationError 7 | Configuration = ::OpenAI::Configuration 8 | MiddlewareErrors = ::OpenAI::MiddlewareErrors 9 | end 10 | end 11 | -------------------------------------------------------------------------------- /lib/openai/files.rb: -------------------------------------------------------------------------------- 1 | module OpenAI 2 | class Files 3 | PURPOSES = %w[ 4 | assistants 5 | batch 6 | fine-tune 7 | vision 8 | ].freeze 9 | 10 | def initialize(client:) 11 | @client = client 12 | end 13 | 14 | def list 15 | @client.get(path: "/files") 16 | end 17 | 18 | def upload(parameters: {}) 19 | file_input = parameters[:file] 20 | file = prepare_file_input(file_input: file_input) 21 | 22 | validate(file: file, purpose: parameters[:purpose], file_input: file_input) 23 | 24 | @client.multipart_post( 25 | path: "/files", 26 | parameters: parameters.merge(file: file) 27 | ) 28 | ensure 29 | file.close if file.is_a?(File) 30 | end 31 | 32 | def retrieve(id:) 33 | @client.get(path: "/files/#{id}") 34 | end 35 | 36 | def content(id:) 37 | @client.get(path: "/files/#{id}/content") 38 | end 39 | 40 | def delete(id:) 41 | @client.delete(path: "/files/#{id}") 42 | end 43 | 44 | private 45 | 46 | def prepare_file_input(file_input:) 47 | if file_input.is_a?(String) 48 | File.open(file_input) 49 | elsif file_input.respond_to?(:read) && file_input.respond_to?(:rewind) 50 | file_input 51 | else 52 | raise ArgumentError, "Invalid file - must be a StringIO object or a path to a file." 53 | end 54 | end 55 | 56 | def validate(file:, purpose:, file_input:) 57 | raise ArgumentError, "`file` is required" if file.nil? 58 | unless PURPOSES.include?(purpose) 59 | raise ArgumentError, "`purpose` must be one of `#{PURPOSES.join(',')}`" 60 | end 61 | 62 | validate_jsonl(file: file) if file_input.is_a?(String) && file_input.end_with?(".jsonl") 63 | end 64 | 65 | def validate_jsonl(file:) 66 | file.each_line.with_index do |line, index| 67 | JSON.parse(line) 68 | rescue JSON::ParserError => e 69 | raise JSON::ParserError, "#{e.message} - found on line #{index + 1} of #{file}" 70 | end 71 | ensure 72 | file.rewind 73 | end 74 | end 75 | end 76 | -------------------------------------------------------------------------------- /lib/openai/finetunes.rb: -------------------------------------------------------------------------------- 1 | module OpenAI 2 | class Finetunes 3 | def initialize(client:) 4 | @client = client 5 | end 6 | 7 | def list 8 | @client.get(path: "/fine_tuning/jobs") 9 | end 10 | 11 | def create(parameters: {}) 12 | @client.json_post(path: "/fine_tuning/jobs", parameters: parameters) 13 | end 14 | 15 | def retrieve(id:) 16 | @client.get(path: "/fine_tuning/jobs/#{id}") 17 | end 18 | 19 | def cancel(id:) 20 | @client.json_post(path: "/fine_tuning/jobs/#{id}/cancel", parameters: {}) 21 | end 22 | 23 | def list_events(id:) 24 | @client.get(path: "/fine_tuning/jobs/#{id}/events") 25 | end 26 | end 27 | end 28 | -------------------------------------------------------------------------------- /lib/openai/http_headers.rb: -------------------------------------------------------------------------------- 1 | module OpenAI 2 | module HTTPHeaders 3 | def add_headers(headers) 4 | @extra_headers = extra_headers.merge(headers.transform_keys(&:to_s)) 5 | end 6 | 7 | private 8 | 9 | def headers 10 | if azure? 11 | azure_headers 12 | else 13 | openai_headers 14 | end.merge(extra_headers) 15 | end 16 | 17 | def openai_headers 18 | { 19 | "Content-Type" => "application/json", 20 | "Authorization" => "Bearer #{@access_token}", 21 | "OpenAI-Organization" => @organization_id 22 | }.compact 23 | end 24 | 25 | def azure_headers 26 | { 27 | "Content-Type" => "application/json", 28 | "api-key" => @access_token 29 | } 30 | end 31 | 32 | def extra_headers 33 | @extra_headers ||= {} 34 | end 35 | end 36 | end 37 | -------------------------------------------------------------------------------- /lib/openai/images.rb: -------------------------------------------------------------------------------- 1 | module OpenAI 2 | class Images 3 | def initialize(client: nil) 4 | @client = client 5 | end 6 | 7 | def generate(parameters: {}) 8 | @client.json_post(path: "/images/generations", parameters: parameters) 9 | end 10 | 11 | def edit(parameters: {}) 12 | @client.multipart_post(path: "/images/edits", parameters: open_files(parameters)) 13 | end 14 | 15 | def variations(parameters: {}) 16 | @client.multipart_post(path: "/images/variations", parameters: open_files(parameters)) 17 | end 18 | 19 | private 20 | 21 | def open_files(parameters) 22 | parameters = parameters.merge(image: File.open(parameters[:image])) 23 | parameters = parameters.merge(mask: File.open(parameters[:mask])) if parameters[:mask] 24 | parameters 25 | end 26 | end 27 | end 28 | -------------------------------------------------------------------------------- /lib/openai/messages.rb: -------------------------------------------------------------------------------- 1 | module OpenAI 2 | class Messages 3 | def initialize(client:) 4 | @client = client.beta(assistants: OpenAI::Assistants::BETA_VERSION) 5 | end 6 | 7 | def list(thread_id:, parameters: {}) 8 | @client.get(path: "/threads/#{thread_id}/messages", parameters: parameters) 9 | end 10 | 11 | def retrieve(thread_id:, id:) 12 | @client.get(path: "/threads/#{thread_id}/messages/#{id}") 13 | end 14 | 15 | def create(thread_id:, parameters: {}) 16 | @client.json_post(path: "/threads/#{thread_id}/messages", parameters: parameters) 17 | end 18 | 19 | def modify(id:, thread_id:, parameters: {}) 20 | @client.json_post(path: "/threads/#{thread_id}/messages/#{id}", parameters: parameters) 21 | end 22 | end 23 | end 24 | -------------------------------------------------------------------------------- /lib/openai/models.rb: -------------------------------------------------------------------------------- 1 | module OpenAI 2 | class Models 3 | def initialize(client:) 4 | @client = client 5 | end 6 | 7 | def list 8 | @client.get(path: "/models") 9 | end 10 | 11 | def retrieve(id:) 12 | @client.get(path: "/models/#{id}") 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /lib/openai/run_steps.rb: -------------------------------------------------------------------------------- 1 | module OpenAI 2 | class RunSteps 3 | def initialize(client:) 4 | @client = client.beta(assistants: OpenAI::Assistants::BETA_VERSION) 5 | end 6 | 7 | def list(thread_id:, run_id:, parameters: {}) 8 | @client.get(path: "/threads/#{thread_id}/runs/#{run_id}/steps", parameters: parameters) 9 | end 10 | 11 | def retrieve(thread_id:, run_id:, id:) 12 | @client.get(path: "/threads/#{thread_id}/runs/#{run_id}/steps/#{id}") 13 | end 14 | end 15 | end 16 | -------------------------------------------------------------------------------- /lib/openai/runs.rb: -------------------------------------------------------------------------------- 1 | module OpenAI 2 | class Runs 3 | def initialize(client:) 4 | @client = client.beta(assistants: OpenAI::Assistants::BETA_VERSION) 5 | end 6 | 7 | def list(thread_id:, parameters: {}) 8 | @client.get(path: "/threads/#{thread_id}/runs", parameters: parameters) 9 | end 10 | 11 | def retrieve(thread_id:, id:) 12 | @client.get(path: "/threads/#{thread_id}/runs/#{id}") 13 | end 14 | 15 | def create(thread_id:, parameters: {}) 16 | @client.json_post(path: "/threads/#{thread_id}/runs", parameters: parameters) 17 | end 18 | 19 | def modify(id:, thread_id:, parameters: {}) 20 | @client.json_post(path: "/threads/#{thread_id}/runs/#{id}", parameters: parameters) 21 | end 22 | 23 | def cancel(id:, thread_id:) 24 | @client.post(path: "/threads/#{thread_id}/runs/#{id}/cancel") 25 | end 26 | 27 | def create_thread_and_run(parameters: {}) 28 | @client.json_post(path: "/threads/runs", parameters: parameters) 29 | end 30 | 31 | def submit_tool_outputs(thread_id:, run_id:, parameters: {}) 32 | @client.json_post(path: "/threads/#{thread_id}/runs/#{run_id}/submit_tool_outputs", 33 | parameters: parameters) 34 | end 35 | end 36 | end 37 | -------------------------------------------------------------------------------- /lib/openai/threads.rb: -------------------------------------------------------------------------------- 1 | module OpenAI 2 | class Threads 3 | def initialize(client:) 4 | @client = client.beta(assistants: OpenAI::Assistants::BETA_VERSION) 5 | end 6 | 7 | def retrieve(id:) 8 | @client.get(path: "/threads/#{id}") 9 | end 10 | 11 | def create(parameters: {}) 12 | @client.json_post(path: "/threads", parameters: parameters) 13 | end 14 | 15 | def modify(id:, parameters: {}) 16 | @client.json_post(path: "/threads/#{id}", parameters: parameters) 17 | end 18 | 19 | def delete(id:) 20 | @client.delete(path: "/threads/#{id}") 21 | end 22 | end 23 | end 24 | -------------------------------------------------------------------------------- /lib/openai/vector_store_file_batches.rb: -------------------------------------------------------------------------------- 1 | module OpenAI 2 | class VectorStoreFileBatches 3 | def initialize(client:) 4 | @client = client.beta(assistants: OpenAI::Assistants::BETA_VERSION) 5 | end 6 | 7 | def list(vector_store_id:, id:, parameters: {}) 8 | @client.get( 9 | path: "/vector_stores/#{vector_store_id}/file_batches/#{id}/files", 10 | parameters: parameters 11 | ) 12 | end 13 | 14 | def retrieve(vector_store_id:, id:) 15 | @client.get(path: "/vector_stores/#{vector_store_id}/file_batches/#{id}") 16 | end 17 | 18 | def create(vector_store_id:, parameters: {}) 19 | @client.json_post( 20 | path: "/vector_stores/#{vector_store_id}/file_batches", 21 | parameters: parameters 22 | ) 23 | end 24 | 25 | def cancel(vector_store_id:, id:) 26 | @client.post(path: "/vector_stores/#{vector_store_id}/file_batches/#{id}/cancel") 27 | end 28 | end 29 | end 30 | -------------------------------------------------------------------------------- /lib/openai/vector_store_files.rb: -------------------------------------------------------------------------------- 1 | module OpenAI 2 | class VectorStoreFiles 3 | def initialize(client:) 4 | @client = client.beta(assistants: OpenAI::Assistants::BETA_VERSION) 5 | end 6 | 7 | def list(vector_store_id:, parameters: {}) 8 | @client.get(path: "/vector_stores/#{vector_store_id}/files", parameters: parameters) 9 | end 10 | 11 | def retrieve(vector_store_id:, id:) 12 | @client.get(path: "/vector_stores/#{vector_store_id}/files/#{id}") 13 | end 14 | 15 | def create(vector_store_id:, parameters: {}) 16 | @client.json_post(path: "/vector_stores/#{vector_store_id}/files", parameters: parameters) 17 | end 18 | 19 | def delete(vector_store_id:, id:) 20 | @client.delete(path: "/vector_stores/#{vector_store_id}/files/#{id}") 21 | end 22 | end 23 | end 24 | -------------------------------------------------------------------------------- /lib/openai/vector_stores.rb: -------------------------------------------------------------------------------- 1 | module OpenAI 2 | class VectorStores 3 | def initialize(client:) 4 | @client = client.beta(assistants: OpenAI::Assistants::BETA_VERSION) 5 | end 6 | 7 | def list(parameters: {}) 8 | @client.get(path: "/vector_stores", parameters: parameters) 9 | end 10 | 11 | def retrieve(id:) 12 | @client.get(path: "/vector_stores/#{id}") 13 | end 14 | 15 | def create(parameters: {}) 16 | @client.json_post(path: "/vector_stores", parameters: parameters) 17 | end 18 | 19 | def modify(id:, parameters: {}) 20 | @client.json_post(path: "/vector_stores/#{id}", parameters: parameters) 21 | end 22 | 23 | def delete(id:) 24 | @client.delete(path: "/vector_stores/#{id}") 25 | end 26 | end 27 | end 28 | -------------------------------------------------------------------------------- /lib/openai/version.rb: -------------------------------------------------------------------------------- 1 | module OpenAI 2 | VERSION = "7.1.0".freeze 3 | end 4 | -------------------------------------------------------------------------------- /lib/ruby/openai.rb: -------------------------------------------------------------------------------- 1 | require_relative "../openai" 2 | require_relative "../openai/compatibility" 3 | -------------------------------------------------------------------------------- /pull_request_template.md: -------------------------------------------------------------------------------- 1 | ## All Submissions: 2 | 3 | * [ ] Have you followed the guidelines in our [Contributing document](../blob/main/CONTRIBUTING.md)? 4 | * [ ] Have you checked to ensure there aren't other open [Pull Requests](../pulls) for the same update/change? 5 | * [ ] Have you added an explanation of what your changes do and why you'd like us to include them? 6 | -------------------------------------------------------------------------------- /ruby-openai.gemspec: -------------------------------------------------------------------------------- 1 | require_relative "lib/openai/version" 2 | 3 | Gem::Specification.new do |spec| 4 | spec.name = "ruby-openai" 5 | spec.version = OpenAI::VERSION 6 | spec.authors = ["Alex"] 7 | spec.email = ["alexrudall@users.noreply.github.com"] 8 | 9 | spec.summary = "OpenAI API + Ruby! 🤖❤️" 10 | spec.homepage = "https://github.com/alexrudall/ruby-openai" 11 | spec.license = "MIT" 12 | spec.required_ruby_version = Gem::Requirement.new(">= 2.6.0") 13 | 14 | spec.metadata["homepage_uri"] = spec.homepage 15 | spec.metadata["source_code_uri"] = "https://github.com/alexrudall/ruby-openai" 16 | spec.metadata["changelog_uri"] = "https://github.com/alexrudall/ruby-openai/blob/main/CHANGELOG.md" 17 | spec.metadata["rubygems_mfa_required"] = "true" 18 | spec.metadata["funding_uri"] = "https://github.com/sponsors/alexrudall" 19 | 20 | # Specify which files should be added to the gem when it is released. 21 | # The `git ls-files -z` loads the files in the RubyGem that have been added into git. 22 | spec.files = Dir.chdir(File.expand_path(__dir__)) do 23 | `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) } 24 | end 25 | spec.bindir = "exe" 26 | spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) } 27 | spec.require_paths = ["lib"] 28 | 29 | spec.add_dependency "event_stream_parser", ">= 0.3.0", "< 2.0.0" 30 | spec.add_dependency "faraday", ">= 1" 31 | spec.add_dependency "faraday-multipart", ">= 1" 32 | end 33 | -------------------------------------------------------------------------------- /spec/compatibility_spec.rb: -------------------------------------------------------------------------------- 1 | RSpec.describe "compatibility" do 2 | context "for moved constants" do 3 | describe "::Ruby::OpenAI::VERSION" do 4 | it "is mapped to ::OpenAI::VERSION" do 5 | expect(Ruby::OpenAI::VERSION).to eq(OpenAI::VERSION) 6 | end 7 | end 8 | 9 | describe "::Ruby::OpenAI::Error" do 10 | it "is mapped to ::OpenAI::Error" do 11 | expect(Ruby::OpenAI::Error).to eq(OpenAI::Error) 12 | expect(Ruby::OpenAI::Error.new).to be_a(OpenAI::Error) 13 | expect(OpenAI::Error.new).to be_a(Ruby::OpenAI::Error) 14 | end 15 | end 16 | 17 | describe "::Ruby::OpenAI::ConfigurationError" do 18 | it "is mapped to ::OpenAI::ConfigurationError" do 19 | expect(Ruby::OpenAI::ConfigurationError).to eq(OpenAI::ConfigurationError) 20 | expect(Ruby::OpenAI::ConfigurationError.new).to be_a(OpenAI::ConfigurationError) 21 | expect(OpenAI::ConfigurationError.new).to be_a(Ruby::OpenAI::ConfigurationError) 22 | end 23 | end 24 | 25 | describe "::Ruby::OpenAI::Configuration" do 26 | it "is mapped to ::OpenAI::Configuration" do 27 | expect(Ruby::OpenAI::Configuration).to eq(OpenAI::Configuration) 28 | expect(Ruby::OpenAI::Configuration.new).to be_a(OpenAI::Configuration) 29 | expect(OpenAI::Configuration.new).to be_a(Ruby::OpenAI::Configuration) 30 | end 31 | end 32 | end 33 | end 34 | -------------------------------------------------------------------------------- /spec/fixtures/cassettes/files_content.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_interactions: 3 | - request: 4 | method: get 5 | uri: https://api.openai.com/v1/files/file-VAyM3yAs580Dk9SbTBzwl8yN/content 6 | body: 7 | encoding: US-ASCII 8 | string: '' 9 | headers: 10 | Content-Type: 11 | - application/json 12 | Authorization: 13 | - Bearer 14 | Accept-Encoding: 15 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 16 | Accept: 17 | - "*/*" 18 | User-Agent: 19 | - Ruby 20 | response: 21 | status: 22 | code: 200 23 | message: OK 24 | headers: 25 | Date: 26 | - Tue, 14 Nov 2023 21:48:50 GMT 27 | Content-Type: 28 | - application/octet-stream 29 | Transfer-Encoding: 30 | - chunked 31 | Connection: 32 | - keep-alive 33 | Content-Disposition: 34 | - attachment; filename="sentiment.jsonl" 35 | Openai-Version: 36 | - '2020-10-01' 37 | Openai-Organization: 38 | - user-jxm65ijkzc1qrfhc0ij8moic 39 | X-Request-Id: 40 | - f575ab5b400a1b9a6dc1aa23b557b573 41 | Openai-Processing-Ms: 42 | - '84' 43 | Access-Control-Allow-Origin: 44 | - "*" 45 | Strict-Transport-Security: 46 | - max-age=15724800; includeSubDomains 47 | Cf-Cache-Status: 48 | - DYNAMIC 49 | Set-Cookie: 50 | - __cf_bm=ecSdU_k92m9twb0uhcvFUGUN8vVuggCX_JJ0KYz6ak8-1699998530-0-AcC5oe+KBr+tR5Gx3VG8GaSvfsjW525sXA354DzrfRyJL3h0gGOV4VonFoqGTZDi5lj1JgocQljmGlHH6phvf1E=; 51 | path=/; expires=Tue, 14-Nov-23 22:18:50 GMT; domain=.api.openai.com; HttpOnly; 52 | Secure; SameSite=None 53 | - _cfuvid=3CDLlmcUZ9S___3_KPOZS.7YWwNLzflYxFAf9bwKDtE-1699998530242-0-604800000; 54 | path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None 55 | Server: 56 | - cloudflare 57 | Cf-Ray: 58 | - 826275fa9e076328-LHR 59 | Alt-Svc: 60 | - h3=":443"; ma=86400 61 | body: 62 | encoding: UTF-8 63 | string: | 64 | {"prompt":"Overjoyed with my new phone! ->", "completion":" positive"} 65 | {"prompt":"@lakers disappoint for a third straight night ->", "completion":" negative"} 66 | recorded_at: Tue, 14 Nov 2023 21:48:50 GMT 67 | recorded_with: VCR 6.1.0 68 | -------------------------------------------------------------------------------- /spec/fixtures/cassettes/files_content_upload.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_interactions: 3 | - request: 4 | method: post 5 | uri: https://api.openai.com/v1/files 6 | body: 7 | encoding: UTF-8 8 | string: "-------------RubyMultipartPost-40383c666647fd96a63d91c94f1afeff\r\nContent-Disposition: 9 | form-data; name=\"file\"; filename=\"sentiment.jsonl\"\r\nContent-Length: 10 | 159\r\nContent-Type: \r\nContent-Transfer-Encoding: binary\r\n\r\n{\"prompt\":\"Overjoyed 11 | with my new phone! ->\", \"completion\":\" positive\"}\n{\"prompt\":\"@lakers 12 | disappoint for a third straight night ->\", \"completion\":\" negative\"}\n\r\n-------------RubyMultipartPost-40383c666647fd96a63d91c94f1afeff\r\nContent-Disposition: 13 | form-data; name=\"purpose\"\r\n\r\nfine-tune\r\n-------------RubyMultipartPost-40383c666647fd96a63d91c94f1afeff--\r\n" 14 | headers: 15 | Content-Type: 16 | - multipart/form-data; boundary=-----------RubyMultipartPost-40383c666647fd96a63d91c94f1afeff 17 | Authorization: 18 | - Bearer 19 | Content-Length: 20 | - '566' 21 | Accept-Encoding: 22 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 23 | Accept: 24 | - "*/*" 25 | User-Agent: 26 | - Ruby 27 | response: 28 | status: 29 | code: 200 30 | message: OK 31 | headers: 32 | Date: 33 | - Tue, 14 Nov 2023 21:48:49 GMT 34 | Content-Type: 35 | - application/json 36 | Transfer-Encoding: 37 | - chunked 38 | Connection: 39 | - keep-alive 40 | Openai-Version: 41 | - '2020-10-01' 42 | Openai-Organization: 43 | - user-jxm65ijkzc1qrfhc0ij8moic 44 | X-Request-Id: 45 | - 752f8b68d923b6be3f0550f879471424 46 | Openai-Processing-Ms: 47 | - '658' 48 | Access-Control-Allow-Origin: 49 | - "*" 50 | Strict-Transport-Security: 51 | - max-age=15724800; includeSubDomains 52 | Cf-Cache-Status: 53 | - DYNAMIC 54 | Set-Cookie: 55 | - __cf_bm=j12fQcYh9xUEd7A23e_RJuO4567R6kh.6pQpRvO.sVU-1699998529-0-ATKhv8iC/CvjVEHyko1c1wJmphRzwROakwJ/SgnfGr8xXVcxyAlVWZ+nb4291Gx3/33lmxK2n9j1fymC6jSD79k=; 56 | path=/; expires=Tue, 14-Nov-23 22:18:49 GMT; domain=.api.openai.com; HttpOnly; 57 | Secure; SameSite=None 58 | - _cfuvid=HazGdvg6ThkIeBkplPCVMQo3RPIMc3vS_rWM.stvQ.E-1699998529560-0-604800000; 59 | path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None 60 | Server: 61 | - cloudflare 62 | Cf-Ray: 63 | - 826275f4b8d676f5-LHR 64 | Alt-Svc: 65 | - h3=":443"; ma=86400 66 | body: 67 | encoding: ASCII-8BIT 68 | string: | 69 | { 70 | "object": "file", 71 | "id": "file-VAyM3yAs580Dk9SbTBzwl8yN", 72 | "purpose": "fine-tune", 73 | "filename": "sentiment.jsonl", 74 | "bytes": 159, 75 | "created_at": 1699998529, 76 | "status": "uploaded", 77 | "status_details": null 78 | } 79 | recorded_at: Tue, 14 Nov 2023 21:48:49 GMT 80 | recorded_with: VCR 6.1.0 81 | -------------------------------------------------------------------------------- /spec/fixtures/cassettes/files_delete.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_interactions: 3 | - request: 4 | method: delete 5 | uri: https://api.openai.com/v1/files/file-0jvap1eP3CIIUYbypdaX5y5w 6 | body: 7 | encoding: US-ASCII 8 | string: '' 9 | headers: 10 | Content-Type: 11 | - application/json 12 | Authorization: 13 | - Bearer 14 | Accept-Encoding: 15 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 16 | Accept: 17 | - "*/*" 18 | User-Agent: 19 | - Ruby 20 | response: 21 | status: 22 | code: 200 23 | message: OK 24 | headers: 25 | Date: 26 | - Tue, 14 Nov 2023 21:48:54 GMT 27 | Content-Type: 28 | - application/json 29 | Transfer-Encoding: 30 | - chunked 31 | Connection: 32 | - keep-alive 33 | Openai-Version: 34 | - '2020-10-01' 35 | Openai-Organization: 36 | - user-jxm65ijkzc1qrfhc0ij8moic 37 | X-Request-Id: 38 | - a8c569e1f75bde44f7c3d11c7e1c3242 39 | Openai-Processing-Ms: 40 | - '352' 41 | Access-Control-Allow-Origin: 42 | - "*" 43 | Strict-Transport-Security: 44 | - max-age=15724800; includeSubDomains 45 | Cf-Cache-Status: 46 | - DYNAMIC 47 | Set-Cookie: 48 | - __cf_bm=_jN6PztHSdGfDF66QrtGMrgjK1A3fc5w81J5RJxKZLg-1699998534-0-AUwU8+Q6fowOdxVXi0taQXWbazehLr3zYWNfsljazP95z+SSEjQXq5SBfEDeV1S9DzaJfs4CyZslCXVIfsY69k0=; 49 | path=/; expires=Tue, 14-Nov-23 22:18:54 GMT; domain=.api.openai.com; HttpOnly; 50 | Secure; SameSite=None 51 | - _cfuvid=HCBE4v9ApanLwMZmt7PVXApTOrN1wLxFuCK9IW.hJDk-1699998534520-0-604800000; 52 | path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None 53 | Server: 54 | - cloudflare 55 | Cf-Ray: 56 | - 82627615bb5863f9-LHR 57 | Alt-Svc: 58 | - h3=":443"; ma=86400 59 | body: 60 | encoding: ASCII-8BIT 61 | string: | 62 | { 63 | "object": "file", 64 | "id": "file-0jvap1eP3CIIUYbypdaX5y5w", 65 | "deleted": true 66 | } 67 | recorded_at: Tue, 14 Nov 2023 21:48:54 GMT 68 | recorded_with: VCR 6.1.0 69 | -------------------------------------------------------------------------------- /spec/fixtures/cassettes/files_delete_retrieve.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_interactions: 3 | - request: 4 | method: get 5 | uri: https://api.openai.com/v1/files/file-0jvap1eP3CIIUYbypdaX5y5w 6 | body: 7 | encoding: US-ASCII 8 | string: '' 9 | headers: 10 | Content-Type: 11 | - application/json 12 | Authorization: 13 | - Bearer 14 | Accept-Encoding: 15 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 16 | Accept: 17 | - "*/*" 18 | User-Agent: 19 | - Ruby 20 | response: 21 | status: 22 | code: 200 23 | message: OK 24 | headers: 25 | Date: 26 | - Tue, 14 Nov 2023 21:48:53 GMT 27 | Content-Type: 28 | - application/json 29 | Transfer-Encoding: 30 | - chunked 31 | Connection: 32 | - keep-alive 33 | Openai-Version: 34 | - '2020-10-01' 35 | Openai-Organization: 36 | - user-jxm65ijkzc1qrfhc0ij8moic 37 | X-Request-Id: 38 | - 39216740bed70cc6636969f0fe841078 39 | Openai-Processing-Ms: 40 | - '42' 41 | Access-Control-Allow-Origin: 42 | - "*" 43 | Strict-Transport-Security: 44 | - max-age=15724800; includeSubDomains 45 | Cf-Cache-Status: 46 | - DYNAMIC 47 | Set-Cookie: 48 | - __cf_bm=bDxlDrQ6uT8u9xNzMBrdbDidTTGF.cMZi7sVcXPpwvM-1699998533-0-AVghPBJqCnm7x9sulaj53TigrscDreOUcVevVXTLvv2OYXng71QfZfYtrCdQN/K1IH6+tuypM9GrxqG8tBUFrgs=; 49 | path=/; expires=Tue, 14-Nov-23 22:18:53 GMT; domain=.api.openai.com; HttpOnly; 50 | Secure; SameSite=None 51 | - _cfuvid=puIaxHTBwhbiSu9qWC5ZoJsF1fZJGIuL16FoNATKZ94-1699998533962-0-604800000; 52 | path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None 53 | Server: 54 | - cloudflare 55 | Cf-Ray: 56 | - 826276141c3d6538-LHR 57 | Alt-Svc: 58 | - h3=":443"; ma=86400 59 | body: 60 | encoding: ASCII-8BIT 61 | string: | 62 | { 63 | "object": "file", 64 | "id": "file-0jvap1eP3CIIUYbypdaX5y5w", 65 | "purpose": "fine-tune", 66 | "filename": "sentiment.jsonl", 67 | "bytes": 159, 68 | "created_at": 1699998530, 69 | "status": "processed", 70 | "status_details": null 71 | } 72 | recorded_at: Tue, 14 Nov 2023 21:48:53 GMT 73 | recorded_with: VCR 6.1.0 74 | -------------------------------------------------------------------------------- /spec/fixtures/cassettes/files_delete_upload.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_interactions: 3 | - request: 4 | method: post 5 | uri: https://api.openai.com/v1/files 6 | body: 7 | encoding: UTF-8 8 | string: "-------------RubyMultipartPost-fa07165695179ac71d25d2e3c3783a98\r\nContent-Disposition: 9 | form-data; name=\"file\"; filename=\"sentiment.jsonl\"\r\nContent-Length: 10 | 159\r\nContent-Type: \r\nContent-Transfer-Encoding: binary\r\n\r\n{\"prompt\":\"Overjoyed 11 | with my new phone! ->\", \"completion\":\" positive\"}\n{\"prompt\":\"@lakers 12 | disappoint for a third straight night ->\", \"completion\":\" negative\"}\n\r\n-------------RubyMultipartPost-fa07165695179ac71d25d2e3c3783a98\r\nContent-Disposition: 13 | form-data; name=\"purpose\"\r\n\r\nfine-tune\r\n-------------RubyMultipartPost-fa07165695179ac71d25d2e3c3783a98--\r\n" 14 | headers: 15 | Content-Type: 16 | - multipart/form-data; boundary=-----------RubyMultipartPost-fa07165695179ac71d25d2e3c3783a98 17 | Authorization: 18 | - Bearer 19 | Content-Length: 20 | - '566' 21 | Accept-Encoding: 22 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 23 | Accept: 24 | - "*/*" 25 | User-Agent: 26 | - Ruby 27 | response: 28 | status: 29 | code: 200 30 | message: OK 31 | headers: 32 | Date: 33 | - Tue, 14 Nov 2023 21:48:51 GMT 34 | Content-Type: 35 | - application/json 36 | Transfer-Encoding: 37 | - chunked 38 | Connection: 39 | - keep-alive 40 | Openai-Version: 41 | - '2020-10-01' 42 | Openai-Organization: 43 | - user-jxm65ijkzc1qrfhc0ij8moic 44 | X-Request-Id: 45 | - ee14c796f4509398efcfe41df8ff14c2 46 | Openai-Processing-Ms: 47 | - '513' 48 | Access-Control-Allow-Origin: 49 | - "*" 50 | Strict-Transport-Security: 51 | - max-age=15724800; includeSubDomains 52 | Cf-Cache-Status: 53 | - DYNAMIC 54 | Set-Cookie: 55 | - __cf_bm=XjRMkiOOm1GYzM3JIxiV7DWthXzjWRJWipvhM5W3nb0-1699998531-0-AQk3Y9qO+mKcbo5X9sNtCLlDs6Uj061t4NKzzYBo8ftQoDZDksdwm7jLgC4VCbeM+c29VdIxtR1tgko3/M2yk1M=; 56 | path=/; expires=Tue, 14-Nov-23 22:18:51 GMT; domain=.api.openai.com; HttpOnly; 57 | Secure; SameSite=None 58 | - _cfuvid=PqBvBQCBGTL4SPQJcxkEhpdpicxI2ifbbF4ptMp.1AU-1699998531067-0-604800000; 59 | path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None 60 | Server: 61 | - cloudflare 62 | Cf-Ray: 63 | - 826275ff1ba988a4-LHR 64 | Alt-Svc: 65 | - h3=":443"; ma=86400 66 | body: 67 | encoding: ASCII-8BIT 68 | string: | 69 | { 70 | "object": "file", 71 | "id": "file-0jvap1eP3CIIUYbypdaX5y5w", 72 | "purpose": "fine-tune", 73 | "filename": "sentiment.jsonl", 74 | "bytes": 159, 75 | "created_at": 1699998530, 76 | "status": "uploaded", 77 | "status_details": null 78 | } 79 | recorded_at: Tue, 14 Nov 2023 21:48:51 GMT 80 | recorded_with: VCR 6.1.0 81 | -------------------------------------------------------------------------------- /spec/fixtures/cassettes/files_list_upload.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_interactions: 3 | - request: 4 | method: post 5 | uri: https://api.openai.com/v1/files 6 | body: 7 | encoding: UTF-8 8 | string: "-------------RubyMultipartPost-ea5949c6782f24511aee0ffa21193119\r\nContent-Disposition: 9 | form-data; name=\"file\"; filename=\"sentiment.jsonl\"\r\nContent-Length: 10 | 159\r\nContent-Type: \r\nContent-Transfer-Encoding: binary\r\n\r\n{\"prompt\":\"Overjoyed 11 | with my new phone! ->\", \"completion\":\" positive\"}\n{\"prompt\":\"@lakers 12 | disappoint for a third straight night ->\", \"completion\":\" negative\"}\n\r\n-------------RubyMultipartPost-ea5949c6782f24511aee0ffa21193119\r\nContent-Disposition: 13 | form-data; name=\"purpose\"\r\n\r\nfine-tune\r\n-------------RubyMultipartPost-ea5949c6782f24511aee0ffa21193119--\r\n" 14 | headers: 15 | Content-Type: 16 | - multipart/form-data; boundary=-----------RubyMultipartPost-ea5949c6782f24511aee0ffa21193119 17 | Authorization: 18 | - Bearer 19 | Content-Length: 20 | - '566' 21 | Accept-Encoding: 22 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 23 | Accept: 24 | - "*/*" 25 | User-Agent: 26 | - Ruby 27 | response: 28 | status: 29 | code: 200 30 | message: OK 31 | headers: 32 | Date: 33 | - Tue, 14 Nov 2023 21:48:45 GMT 34 | Content-Type: 35 | - application/json 36 | Transfer-Encoding: 37 | - chunked 38 | Connection: 39 | - keep-alive 40 | Openai-Version: 41 | - '2020-10-01' 42 | Openai-Organization: 43 | - user-jxm65ijkzc1qrfhc0ij8moic 44 | X-Request-Id: 45 | - 654149fba40d1c976b67550493add6bd 46 | Openai-Processing-Ms: 47 | - '440' 48 | Access-Control-Allow-Origin: 49 | - "*" 50 | Strict-Transport-Security: 51 | - max-age=15724800; includeSubDomains 52 | Cf-Cache-Status: 53 | - DYNAMIC 54 | Set-Cookie: 55 | - __cf_bm=z6S3dL7_bo6RG8BfqnlNMpNLzmXK_8buvdq6hEkz6g0-1699998525-0-ATXzdRjO1ojWRBy7maVMTNUyxvdSF1K8tr3uW1M1IqAEnt1phj8cwx2ePaOvf7G7tjxL7b2HGjPQ4vNth14VI70=; 56 | path=/; expires=Tue, 14-Nov-23 22:18:45 GMT; domain=.api.openai.com; HttpOnly; 57 | Secure; SameSite=None 58 | - _cfuvid=5ll5xaOaLmjBCK3CIVpeVaQZvpG6JVNmN3aNme9jpP8-1699998525776-0-604800000; 59 | path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None 60 | Server: 61 | - cloudflare 62 | Cf-Ray: 63 | - 826275de7ec4770d-LHR 64 | Alt-Svc: 65 | - h3=":443"; ma=86400 66 | body: 67 | encoding: ASCII-8BIT 68 | string: | 69 | { 70 | "object": "file", 71 | "id": "file-ykJ7hEWXWoZm3NRuPrFqS3j1", 72 | "purpose": "fine-tune", 73 | "filename": "sentiment.jsonl", 74 | "bytes": 159, 75 | "created_at": 1699998525, 76 | "status": "uploaded", 77 | "status_details": null 78 | } 79 | recorded_at: Tue, 14 Nov 2023 21:48:45 GMT 80 | recorded_with: VCR 6.1.0 81 | -------------------------------------------------------------------------------- /spec/fixtures/cassettes/files_retrieve.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_interactions: 3 | - request: 4 | method: get 5 | uri: https://api.openai.com/v1/files/file-s2xQXv3BRiB88t19DfkMpF6f 6 | body: 7 | encoding: US-ASCII 8 | string: '' 9 | headers: 10 | Content-Type: 11 | - application/json 12 | Authorization: 13 | - Bearer 14 | Accept-Encoding: 15 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 16 | Accept: 17 | - "*/*" 18 | User-Agent: 19 | - Ruby 20 | response: 21 | status: 22 | code: 200 23 | message: OK 24 | headers: 25 | Date: 26 | - Tue, 14 Nov 2023 21:48:48 GMT 27 | Content-Type: 28 | - application/json 29 | Transfer-Encoding: 30 | - chunked 31 | Connection: 32 | - keep-alive 33 | Openai-Version: 34 | - '2020-10-01' 35 | Openai-Organization: 36 | - user-jxm65ijkzc1qrfhc0ij8moic 37 | X-Request-Id: 38 | - fa20e45ea8a965b7d88d099954d962e4 39 | Openai-Processing-Ms: 40 | - '76' 41 | Access-Control-Allow-Origin: 42 | - "*" 43 | Strict-Transport-Security: 44 | - max-age=15724800; includeSubDomains 45 | Cf-Cache-Status: 46 | - DYNAMIC 47 | Set-Cookie: 48 | - __cf_bm=D99.M34EQbEDP9T8.X5oxtjiv18x1mEX4WV_.9I5wwU-1699998528-0-AUn98TFcB6+4HzJgGyY2f5rUQxgqKothApCaooAUmAaBFXP8XMKF1fjWVxfdoGzgEuaEutlavhQRu4tOqEsS/Mw=; 49 | path=/; expires=Tue, 14-Nov-23 22:18:48 GMT; domain=.api.openai.com; HttpOnly; 50 | Secure; SameSite=None 51 | - _cfuvid=24QuXnJgnaYFVMihszLmi4_mzNn1L3Mj6L06LMwxVe0-1699998528684-0-604800000; 52 | path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None 53 | Server: 54 | - cloudflare 55 | Cf-Ray: 56 | - 826275f2e955dd79-LHR 57 | Alt-Svc: 58 | - h3=":443"; ma=86400 59 | body: 60 | encoding: ASCII-8BIT 61 | string: | 62 | { 63 | "object": "file", 64 | "id": "file-s2xQXv3BRiB88t19DfkMpF6f", 65 | "purpose": "fine-tune", 66 | "filename": "sentiment.jsonl", 67 | "bytes": 159, 68 | "created_at": 1699998528, 69 | "status": "uploaded", 70 | "status_details": null 71 | } 72 | recorded_at: Tue, 14 Nov 2023 21:48:48 GMT 73 | recorded_with: VCR 6.1.0 74 | -------------------------------------------------------------------------------- /spec/fixtures/cassettes/files_retrieve_upload.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_interactions: 3 | - request: 4 | method: post 5 | uri: https://api.openai.com/v1/files 6 | body: 7 | encoding: UTF-8 8 | string: "-------------RubyMultipartPost-c55bd251585ba8dc6b96920a035a247f\r\nContent-Disposition: 9 | form-data; name=\"file\"; filename=\"sentiment.jsonl\"\r\nContent-Length: 10 | 159\r\nContent-Type: \r\nContent-Transfer-Encoding: binary\r\n\r\n{\"prompt\":\"Overjoyed 11 | with my new phone! ->\", \"completion\":\" positive\"}\n{\"prompt\":\"@lakers 12 | disappoint for a third straight night ->\", \"completion\":\" negative\"}\n\r\n-------------RubyMultipartPost-c55bd251585ba8dc6b96920a035a247f\r\nContent-Disposition: 13 | form-data; name=\"purpose\"\r\n\r\nfine-tune\r\n-------------RubyMultipartPost-c55bd251585ba8dc6b96920a035a247f--\r\n" 14 | headers: 15 | Content-Type: 16 | - multipart/form-data; boundary=-----------RubyMultipartPost-c55bd251585ba8dc6b96920a035a247f 17 | Authorization: 18 | - Bearer 19 | Content-Length: 20 | - '566' 21 | Accept-Encoding: 22 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 23 | Accept: 24 | - "*/*" 25 | User-Agent: 26 | - Ruby 27 | response: 28 | status: 29 | code: 200 30 | message: OK 31 | headers: 32 | Date: 33 | - Tue, 14 Nov 2023 21:48:48 GMT 34 | Content-Type: 35 | - application/json 36 | Transfer-Encoding: 37 | - chunked 38 | Connection: 39 | - keep-alive 40 | Openai-Version: 41 | - '2020-10-01' 42 | Openai-Organization: 43 | - user-jxm65ijkzc1qrfhc0ij8moic 44 | X-Request-Id: 45 | - 1a9716efcfa84eee2b1b21f169b15b6e 46 | Openai-Processing-Ms: 47 | - '429' 48 | Access-Control-Allow-Origin: 49 | - "*" 50 | Strict-Transport-Security: 51 | - max-age=15724800; includeSubDomains 52 | Cf-Cache-Status: 53 | - DYNAMIC 54 | Set-Cookie: 55 | - __cf_bm=QOe7wOfklOCeHqd.g68PCXvNRrwo2g2G4QTc15ERYOs-1699998528-0-AY8oVfTmDGUp/BbMKvdtAbMDiYr3j1JDLtuK1p3OtcQF9+kV6LWz4JuqnSnJSdp0CLefqsyQabpdPU7VCUfDkLE=; 56 | path=/; expires=Tue, 14-Nov-23 22:18:48 GMT; domain=.api.openai.com; HttpOnly; 57 | Secure; SameSite=None 58 | - _cfuvid=AENpo.RjsgrDpNTFtImI50KsTEIsAmrcb4g74IinR64-1699998528311-0-604800000; 59 | path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None 60 | Server: 61 | - cloudflare 62 | Cf-Ray: 63 | - 826275ee6cdc63f1-LHR 64 | Alt-Svc: 65 | - h3=":443"; ma=86400 66 | body: 67 | encoding: ASCII-8BIT 68 | string: | 69 | { 70 | "object": "file", 71 | "id": "file-s2xQXv3BRiB88t19DfkMpF6f", 72 | "purpose": "fine-tune", 73 | "filename": "sentiment.jsonl", 74 | "bytes": 159, 75 | "created_at": 1699998528, 76 | "status": "uploaded", 77 | "status_details": null 78 | } 79 | recorded_at: Tue, 14 Nov 2023 21:48:48 GMT 80 | recorded_with: VCR 6.1.0 81 | -------------------------------------------------------------------------------- /spec/fixtures/cassettes/files_upload_stringio.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_interactions: 3 | - request: 4 | method: post 5 | uri: https://api.openai.com/v1/files 6 | body: 7 | encoding: UTF-8 8 | string: "-------------RubyMultipartPost-d378277b5916682b36eb1b4be9f59e6c\r\nContent-Disposition: 9 | form-data; name=\"file\"; filename=\"local.path\"\r\nContent-Length: 159\r\nContent-Type: 10 | \r\nContent-Transfer-Encoding: binary\r\n\r\n{\"prompt\":\"Overjoyed with 11 | my new phone! ->\", \"completion\":\" positive\"}\n{\"prompt\":\"@lakers disappoint 12 | for a third straight night ->\", \"completion\":\" negative\"}\n\r\n-------------RubyMultipartPost-d378277b5916682b36eb1b4be9f59e6c\r\nContent-Disposition: 13 | form-data; name=\"purpose\"\r\n\r\nfine-tune\r\n-------------RubyMultipartPost-d378277b5916682b36eb1b4be9f59e6c--\r\n" 14 | headers: 15 | Content-Type: 16 | - multipart/form-data; boundary=-----------RubyMultipartPost-d378277b5916682b36eb1b4be9f59e6c 17 | Authorization: 18 | - Bearer 19 | Content-Length: 20 | - '561' 21 | Accept-Encoding: 22 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 23 | Accept: 24 | - "*/*" 25 | User-Agent: 26 | - Ruby 27 | response: 28 | status: 29 | code: 200 30 | message: OK 31 | headers: 32 | Date: 33 | - Sat, 27 Apr 2024 19:39:22 GMT 34 | Content-Type: 35 | - application/json 36 | Transfer-Encoding: 37 | - chunked 38 | Connection: 39 | - keep-alive 40 | Openai-Version: 41 | - '2020-10-01' 42 | Openai-Organization: 43 | - user-jxm65ijkzc1qrfhc0ij8moic 44 | X-Request-Id: 45 | - req_328560cbd9986e316ea469c31d62bba2 46 | Openai-Processing-Ms: 47 | - '2467' 48 | Access-Control-Allow-Origin: 49 | - "*" 50 | Strict-Transport-Security: 51 | - max-age=15724800; includeSubDomains 52 | Cf-Cache-Status: 53 | - DYNAMIC 54 | Set-Cookie: 55 | - __cf_bm=MAMznYNNTvYhTSqABSqAeYt3PMejImKQrzNM15hxjLM-1714246762-1.0.1.1-q_7FJuNCbh8dL_oTl.bdY_0JBKZTBKRPaoT.60aarHGnjFKLvN_IM8IZDkiKPsm7Mv9AFDvSEYbIwd8EJVsghw; 56 | path=/; expires=Sat, 27-Apr-24 20:09:22 GMT; domain=.api.openai.com; HttpOnly; 57 | Secure; SameSite=None 58 | - _cfuvid=nxM.eaGMc59pz1xiuz4MTF.IFWIbSfb5TF.xoVwQqR4-1714246762287-0.0.1.1-604800000; 59 | path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None 60 | Server: 61 | - cloudflare 62 | Cf-Ray: 63 | - 87b14727bc816e9f-SOF 64 | Alt-Svc: 65 | - h3=":443"; ma=86400 66 | body: 67 | encoding: ASCII-8BIT 68 | string: | 69 | { 70 | "object": "file", 71 | "id": "file-moVAfw5Z9umta9U8jAcl6kcs", 72 | "purpose": "fine-tune", 73 | "filename": "local.path", 74 | "bytes": 159, 75 | "created_at": 1714246759, 76 | "status": "processed", 77 | "status_details": null 78 | } 79 | recorded_at: Sat, 27 Apr 2024 19:39:22 GMT 80 | recorded_with: VCR 6.1.0 81 | -------------------------------------------------------------------------------- /spec/fixtures/cassettes/finetunes_cancel.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_interactions: 3 | - request: 4 | method: post 5 | uri: https://api.openai.com/v1/fine_tuning/jobs/123/cancel 6 | body: 7 | encoding: UTF-8 8 | string: "{}" 9 | headers: 10 | Content-Type: 11 | - application/json 12 | Authorization: 13 | - Bearer 14 | Accept-Encoding: 15 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 16 | Accept: 17 | - "*/*" 18 | User-Agent: 19 | - Ruby 20 | response: 21 | status: 22 | code: 404 23 | message: Not Found 24 | headers: 25 | Date: 26 | - Tue, 14 Nov 2023 21:48:57 GMT 27 | Content-Type: 28 | - application/json 29 | Transfer-Encoding: 30 | - chunked 31 | Connection: 32 | - keep-alive 33 | Openai-Version: 34 | - '2020-10-01' 35 | Openai-Organization: 36 | - user-jxm65ijkzc1qrfhc0ij8moic 37 | X-Request-Id: 38 | - 3d789b25cea3eab9c40614b357c4eddb 39 | Openai-Processing-Ms: 40 | - '72' 41 | Strict-Transport-Security: 42 | - max-age=15724800; includeSubDomains 43 | Cf-Cache-Status: 44 | - DYNAMIC 45 | Set-Cookie: 46 | - __cf_bm=ApG7ZXI4CPFkrB2j1s.UUro1izhAH0gnB7u4NOVgVhg-1699998537-0-AUby5N6SqX/GfzT18HtFsIjWzIzjj6gQuOdx+utecnpv/SKPMpV6BHq7AAwH+00P53xC8UtaLyeQANpIl0tdQlc=; 47 | path=/; expires=Tue, 14-Nov-23 22:18:57 GMT; domain=.api.openai.com; HttpOnly; 48 | Secure; SameSite=None 49 | - _cfuvid=sgtbVUZgnPZTPyX0GVQXCPuzepVhkQsw2TaxRvXVBfg-1699998537515-0-604800000; 50 | path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None 51 | Server: 52 | - cloudflare 53 | Cf-Ray: 54 | - 8262762a0b5f60ed-LHR 55 | Alt-Svc: 56 | - h3=":443"; ma=86400 57 | body: 58 | encoding: ASCII-8BIT 59 | string: |- 60 | { 61 | "error": { 62 | "message": "Could not find fine tune: 123", 63 | "type": "invalid_request_error", 64 | "param": "fine_tune_id", 65 | "code": "fine_tune_not_found" 66 | } 67 | } 68 | recorded_at: Tue, 14 Nov 2023 21:48:57 GMT 69 | recorded_with: VCR 6.1.0 70 | -------------------------------------------------------------------------------- /spec/fixtures/cassettes/finetunes_create.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_interactions: 3 | - request: 4 | method: post 5 | uri: https://api.openai.com/v1/fine_tuning/jobs 6 | body: 7 | encoding: UTF-8 8 | string: '{"training_file":"file-ciQ5Wxyk73nzPmsypiLfLMtG","model":"gpt-3.5-turbo-0613"}' 9 | headers: 10 | Content-Type: 11 | - application/json 12 | Authorization: 13 | - Bearer 14 | Accept-Encoding: 15 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 16 | Accept: 17 | - "*/*" 18 | User-Agent: 19 | - Ruby 20 | response: 21 | status: 22 | code: 200 23 | message: OK 24 | headers: 25 | Date: 26 | - Tue, 14 Nov 2023 21:48:56 GMT 27 | Content-Type: 28 | - application/json 29 | Transfer-Encoding: 30 | - chunked 31 | Connection: 32 | - keep-alive 33 | Openai-Version: 34 | - '2020-10-01' 35 | Openai-Organization: 36 | - user-jxm65ijkzc1qrfhc0ij8moic 37 | X-Request-Id: 38 | - b3a11779dce7e5ce1fdae596ac14baca 39 | Openai-Processing-Ms: 40 | - '774' 41 | Strict-Transport-Security: 42 | - max-age=15724800; includeSubDomains 43 | Cf-Cache-Status: 44 | - DYNAMIC 45 | Set-Cookie: 46 | - __cf_bm=jTwwkePz7sJ4JnXFDMIr0OmYRMm07FXAEND9UCfvUbw-1699998536-0-Ac288qtFI51/byOhWxKVB0d8a2pqz4KO3gvuRY+klYqFUaBHVLIlzcUkQAP9d80Un0Pc9cYskeoStMsEFF5NzaA=; 47 | path=/; expires=Tue, 14-Nov-23 22:18:56 GMT; domain=.api.openai.com; HttpOnly; 48 | Secure; SameSite=None 49 | - _cfuvid=TEwR3EzX34B9eKCVZzjEnfmJSbduHZO0R4HlvsAWLXc-1699998536869-0-604800000; 50 | path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None 51 | Server: 52 | - cloudflare 53 | Cf-Ray: 54 | - 82627621c9df24b7-LHR 55 | Alt-Svc: 56 | - h3=":443"; ma=86400 57 | body: 58 | encoding: ASCII-8BIT 59 | string: |- 60 | { 61 | "object": "fine_tuning.job", 62 | "id": "ftjob-rT0CMczT7AVa1A1PSbPj5rOk", 63 | "model": "gpt-3.5-turbo-0613", 64 | "created_at": 1699998536, 65 | "finished_at": null, 66 | "fine_tuned_model": null, 67 | "organization_id": "org-Rf437IxKhhQPMiIQ0Es8OwrH", 68 | "result_files": [], 69 | "status": "validating_files", 70 | "validation_file": null, 71 | "training_file": "file-ciQ5Wxyk73nzPmsypiLfLMtG", 72 | "hyperparameters": { 73 | "n_epochs": "auto", 74 | "batch_size": "auto", 75 | "learning_rate_multiplier": "auto" 76 | }, 77 | "trained_tokens": null, 78 | "error": null 79 | } 80 | recorded_at: Tue, 14 Nov 2023 21:48:56 GMT 81 | recorded_with: VCR 6.1.0 82 | -------------------------------------------------------------------------------- /spec/fixtures/cassettes/finetunes_event_list.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_interactions: 3 | - request: 4 | method: get 5 | uri: https://api.openai.com/v1/fine_tuning/jobs/123/events 6 | body: 7 | encoding: US-ASCII 8 | string: '' 9 | headers: 10 | Content-Type: 11 | - application/json 12 | Authorization: 13 | - Bearer 14 | Accept-Encoding: 15 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 16 | Accept: 17 | - "*/*" 18 | User-Agent: 19 | - Ruby 20 | response: 21 | status: 22 | code: 404 23 | message: Not Found 24 | headers: 25 | Date: 26 | - Tue, 14 Nov 2023 21:48:57 GMT 27 | Content-Type: 28 | - application/json 29 | Transfer-Encoding: 30 | - chunked 31 | Connection: 32 | - keep-alive 33 | Openai-Version: 34 | - '2020-10-01' 35 | Openai-Organization: 36 | - user-jxm65ijkzc1qrfhc0ij8moic 37 | X-Request-Id: 38 | - acee5390e7c6598ae20d10f8efef679f 39 | Openai-Processing-Ms: 40 | - '63' 41 | Strict-Transport-Security: 42 | - max-age=15724800; includeSubDomains 43 | Cf-Cache-Status: 44 | - DYNAMIC 45 | Set-Cookie: 46 | - __cf_bm=XOoyLpJN2wpWJwzIuvVuZRZi_2SYhhTDxw8f8WroxHo-1699998537-0-AR/AYW0F4YK/ut236CIsq7hgUR7/NCRabpknFQxasdcjx7u/pfBfziVrjRpsgW9Gy8F3yGeYA3rMAWZiO5eRc9E=; 47 | path=/; expires=Tue, 14-Nov-23 22:18:57 GMT; domain=.api.openai.com; HttpOnly; 48 | Secure; SameSite=None 49 | - _cfuvid=TNlk3rpEeFUa6Zhlw3UyjbWrh0DoHm9wQsmSKWxw7wA-1699998537888-0-604800000; 50 | path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None 51 | Server: 52 | - cloudflare 53 | Cf-Ray: 54 | - 8262762c893f6401-LHR 55 | Alt-Svc: 56 | - h3=":443"; ma=86400 57 | body: 58 | encoding: ASCII-8BIT 59 | string: |- 60 | { 61 | "error": { 62 | "message": "Could not find fine tune: 123", 63 | "type": "invalid_request_error", 64 | "param": "fine_tune_id", 65 | "code": "fine_tune_not_found" 66 | } 67 | } 68 | recorded_at: Tue, 14 Nov 2023 21:48:57 GMT 69 | recorded_with: VCR 6.1.0 70 | -------------------------------------------------------------------------------- /spec/fixtures/cassettes/finetunes_retrieve.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_interactions: 3 | - request: 4 | method: get 5 | uri: https://api.openai.com/v1/fine_tuning/jobs/123 6 | body: 7 | encoding: US-ASCII 8 | string: '' 9 | headers: 10 | Content-Type: 11 | - application/json 12 | Authorization: 13 | - Bearer 14 | Accept-Encoding: 15 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 16 | Accept: 17 | - "*/*" 18 | User-Agent: 19 | - Ruby 20 | response: 21 | status: 22 | code: 404 23 | message: Not Found 24 | headers: 25 | Date: 26 | - Tue, 14 Nov 2023 21:48:57 GMT 27 | Content-Type: 28 | - application/json 29 | Transfer-Encoding: 30 | - chunked 31 | Connection: 32 | - keep-alive 33 | Openai-Version: 34 | - '2020-10-01' 35 | Openai-Organization: 36 | - user-jxm65ijkzc1qrfhc0ij8moic 37 | X-Request-Id: 38 | - 4df7f8b0ba83e6a8aa9b8fa976bef023 39 | Openai-Processing-Ms: 40 | - '78' 41 | Strict-Transport-Security: 42 | - max-age=15724800; includeSubDomains 43 | Cf-Cache-Status: 44 | - DYNAMIC 45 | Set-Cookie: 46 | - __cf_bm=59RifJfbvlHN9Qu4rSBxZ96qCKQcQU1R6KLVuIWvywU-1699998537-0-AYf+z4TCJF0x9+7F5VOSMB//zVOjJ+XqXcWMsow4UBoahmPqOmB9pForlcSvg1vSX8PUXeq8iie+W3qqKci1gbw=; 47 | path=/; expires=Tue, 14-Nov-23 22:18:57 GMT; domain=.api.openai.com; HttpOnly; 48 | Secure; SameSite=None 49 | - _cfuvid=345CorXhyQakR7D.2YoEdUPTYOgeMBgxjuBKWdJTOsE-1699998537187-0-604800000; 50 | path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None 51 | Server: 52 | - cloudflare 53 | Cf-Ray: 54 | - 826276280831777d-LHR 55 | Alt-Svc: 56 | - h3=":443"; ma=86400 57 | body: 58 | encoding: ASCII-8BIT 59 | string: |- 60 | { 61 | "error": { 62 | "message": "Could not find fine tune: 123", 63 | "type": "invalid_request_error", 64 | "param": "fine_tune_id", 65 | "code": "fine_tune_not_found" 66 | } 67 | } 68 | recorded_at: Tue, 14 Nov 2023 21:48:57 GMT 69 | recorded_with: VCR 6.1.0 70 | -------------------------------------------------------------------------------- /spec/fixtures/cassettes/finetunes_retrieve_for_create.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_interactions: 3 | - request: 4 | method: get 5 | uri: https://api.openai.com/v1/files/file-ciQ5Wxyk73nzPmsypiLfLMtG 6 | body: 7 | encoding: US-ASCII 8 | string: '' 9 | headers: 10 | Content-Type: 11 | - application/json 12 | Authorization: 13 | - Bearer 14 | Accept-Encoding: 15 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 16 | Accept: 17 | - "*/*" 18 | User-Agent: 19 | - Ruby 20 | response: 21 | status: 22 | code: 200 23 | message: OK 24 | headers: 25 | Date: 26 | - Tue, 14 Nov 2023 21:48:55 GMT 27 | Content-Type: 28 | - application/json 29 | Transfer-Encoding: 30 | - chunked 31 | Connection: 32 | - keep-alive 33 | Openai-Version: 34 | - '2020-10-01' 35 | Openai-Organization: 36 | - user-jxm65ijkzc1qrfhc0ij8moic 37 | X-Request-Id: 38 | - fdb3f16a3b42f04027f028e9e0b33e0f 39 | Openai-Processing-Ms: 40 | - '13' 41 | Access-Control-Allow-Origin: 42 | - "*" 43 | Strict-Transport-Security: 44 | - max-age=15724800; includeSubDomains 45 | Cf-Cache-Status: 46 | - DYNAMIC 47 | Set-Cookie: 48 | - __cf_bm=YXJboZ65nSgFYYm1EZoFE4aoRPbJJKRkDMmoGR3s80g-1699998535-0-AUAfXWWIDIxsAArqQYwJKdJPxkRH5wgzKLNael6hjonjtUpGSbahOFjH7sr+2N9iES+o41Q7INYu4/wE+u/WWmw=; 49 | path=/; expires=Tue, 14-Nov-23 22:18:55 GMT; domain=.api.openai.com; HttpOnly; 50 | Secure; SameSite=None 51 | - _cfuvid=gSE6tcehzhXkZhwECpaS0V57U4vxYJI9e0hsL77HeCU-1699998535897-0-604800000; 52 | path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None 53 | Server: 54 | - cloudflare 55 | Cf-Ray: 56 | - 826276203c1276c3-LHR 57 | Alt-Svc: 58 | - h3=":443"; ma=86400 59 | body: 60 | encoding: ASCII-8BIT 61 | string: | 62 | { 63 | "object": "file", 64 | "id": "file-ciQ5Wxyk73nzPmsypiLfLMtG", 65 | "purpose": "fine-tune", 66 | "filename": "sarcastic.jsonl", 67 | "bytes": 2676, 68 | "created_at": 1699998535, 69 | "status": "processed", 70 | "status_details": null 71 | } 72 | recorded_at: Tue, 14 Nov 2023 21:48:55 GMT 73 | recorded_with: VCR 6.1.0 74 | -------------------------------------------------------------------------------- /spec/fixtures/cassettes/gpt-3_5-turbo_streamed_chat_with_error_response.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_interactions: 3 | - request: 4 | method: post 5 | uri: https://api.openai.com/v1/chat/completions 6 | body: 7 | encoding: UTF-8 8 | string: '{"model":"gpt-3.5-turbo","messages":[{"role":"user","content":"Hello!"}],"stream":true}' 9 | headers: 10 | Content-Type: 11 | - application/json 12 | Authorization: 13 | - Bearer 14 | Accept-Encoding: 15 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 16 | Accept: 17 | - "*/*" 18 | User-Agent: 19 | - Ruby 20 | response: 21 | status: 22 | code: 500 23 | message: Internal Server Error 24 | headers: 25 | Date: 26 | - Mon, 14 Aug 2023 15:02:13 GMT 27 | recorded_at: Mon, 14 Aug 2023 15:02:13 GMT 28 | 29 | recorded_with: VCR 6.1.0 30 | -------------------------------------------------------------------------------- /spec/fixtures/cassettes/gpt-3_5-turbo_streamed_chat_with_json_error_response.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_interactions: 3 | - request: 4 | method: post 5 | uri: https://api.openai.com/v1/chat/completions 6 | body: 7 | encoding: UTF-8 8 | string: '{"model":"gpt-3.5-turbo","messages":[{"role":"user","content":"Hello!"}],"stream":true}' 9 | headers: 10 | Content-Type: 11 | - application/json 12 | Authorization: 13 | - Bearer 14 | Accept-Encoding: 15 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 16 | Accept: 17 | - "*/*" 18 | User-Agent: 19 | - Ruby 20 | response: 21 | status: 22 | code: 400 23 | message: Bad Request 24 | headers: 25 | Date: 26 | - Mon, 14 Aug 2023 15:02:13 GMT 27 | Content-Type: 28 | - application/json 29 | body: 30 | encoding: UTF-8 31 | string: |+ 32 | { 33 | "error": { 34 | "message": "Test error", 35 | "type": "test_error", 36 | "param": null, 37 | "code": "test" 38 | } 39 | } 40 | recorded_at: Mon, 14 Aug 2023 15:02:13 GMT 41 | 42 | recorded_with: VCR 6.1.0 43 | -------------------------------------------------------------------------------- /spec/fixtures/cassettes/http_get_with_error_response.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_interactions: 3 | - request: 4 | method: get 5 | uri: https://api.openai.com/v1/models/text-ada-001 6 | body: 7 | encoding: US-ASCII 8 | string: '' 9 | headers: 10 | Content-Type: 11 | - application/json 12 | Authorization: 13 | - Bearer 14 | Accept-Encoding: 15 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 16 | Accept: 17 | - "*/*" 18 | User-Agent: 19 | - Ruby 20 | response: 21 | status: 22 | code: 400 23 | message: Bad Request 24 | headers: 25 | Date: 26 | - Mon, 14 Aug 2023 15:02:13 GMT 27 | Content-Type: 28 | - application/json 29 | body: 30 | encoding: UTF-8 31 | string: |+ 32 | { 33 | "error": { 34 | "message": "Test error", 35 | "type": "test_error", 36 | "param": null, 37 | "code": "test" 38 | } 39 | } 40 | recorded_at: Mon, 14 Aug 2023 15:02:13 GMT 41 | recorded_with: VCR 6.1.0 42 | -------------------------------------------------------------------------------- /spec/fixtures/cassettes/images_generate_A_baby_sea_otter_cooking_pasta_wearing_a_hat_of_some_sort.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_interactions: 3 | - request: 4 | method: post 5 | uri: https://api.openai.com/v1/images/generations 6 | body: 7 | encoding: UTF-8 8 | string: '{"prompt":"A baby sea otter cooking pasta wearing a hat of some sort","size":"256x256","model":"dall-e-2"}' 9 | headers: 10 | Content-Type: 11 | - application/json 12 | Authorization: 13 | - Bearer 14 | Accept-Encoding: 15 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 16 | Accept: 17 | - "*/*" 18 | User-Agent: 19 | - Ruby 20 | response: 21 | status: 22 | code: 200 23 | message: OK 24 | headers: 25 | Date: 26 | - Fri, 19 Jan 2024 11:40:53 GMT 27 | Content-Type: 28 | - application/json 29 | Transfer-Encoding: 30 | - chunked 31 | Connection: 32 | - keep-alive 33 | Openai-Version: 34 | - '2020-10-01' 35 | Openai-Organization: 36 | - user-3clrjdlztmfzmksxfsyoiaou 37 | X-Request-Id: 38 | - 0137f54d99d1362b1e623d676116a4c9 39 | Openai-Processing-Ms: 40 | - '6822' 41 | Access-Control-Allow-Origin: 42 | - "*" 43 | Strict-Transport-Security: 44 | - max-age=15724800; includeSubDomains 45 | Cf-Cache-Status: 46 | - DYNAMIC 47 | Set-Cookie: 48 | - __cf_bm=P36Wd_cn8juahMszhsJOx5kkOYVokwSxjGZmiTuOep8-1705664453-1-AWK8XEV35FFAXSMl+MBEJ2XPKC3KQc4hWuMvbTkdXErcByHJJo77vuiKXigfEXUDZKpOT8VxsAaRxiyE/ZV9wbE=; 49 | path=/; expires=Fri, 19-Jan-24 12:10:53 GMT; domain=.api.openai.com; HttpOnly; 50 | Secure; SameSite=None 51 | - _cfuvid=BoKuzauoIz4K9oDwnJtEGtFjVAkD0lnYqLBXdB4lehc-1705664453478-0-604800000; 52 | path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None 53 | Server: 54 | - cloudflare 55 | Cf-Ray: 56 | - 847ece06be0a0755-MAN 57 | Alt-Svc: 58 | - h3=":443"; ma=86400 59 | body: 60 | encoding: ASCII-8BIT 61 | string: | 62 | { 63 | "created": 1705664453, 64 | "data": [ 65 | { 66 | "url": "https://oaidalleapiprodscus.blob.core.windows.net/private/org-yUfNie34j2cA3IrAwdyJpfdb/user-3ClrjdlztmfzMKsxFSYOIAOu/img-TXGcLfiIhAqPEEED1eQ4SyMg.png?st=2024-01-19T10%3A40%3A53Z&se=2024-01-19T12%3A40%3A53Z&sp=r&sv=2021-08-06&sr=b&rscd=inline&rsct=image/png&skoid=6aaadede-4fb3-4698-a8f6-684d7786b067&sktid=a48cca56-e6da-484e-a814-9c849652bcb3&skt=2024-01-18T22%3A51%3A44Z&ske=2024-01-19T22%3A51%3A44Z&sks=b&skv=2021-08-06&sig=AFx2RqTU0Zb2Klk3QPFO06JtipjPmGadWbVVOVQkVeU%3D" 67 | } 68 | ] 69 | } 70 | recorded_at: Fri, 19 Jan 2024 11:40:53 GMT 71 | recorded_with: VCR 6.1.0 72 | -------------------------------------------------------------------------------- /spec/fixtures/cassettes/models_retrieve.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_interactions: 3 | - request: 4 | method: get 5 | uri: https://api.openai.com/v1/models/gpt-3.5-turbo-instruct 6 | body: 7 | encoding: US-ASCII 8 | string: '' 9 | headers: 10 | Content-Type: 11 | - application/json 12 | Authorization: 13 | - Bearer 14 | Accept-Encoding: 15 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 16 | Accept: 17 | - "*/*" 18 | User-Agent: 19 | - Ruby 20 | response: 21 | status: 22 | code: 200 23 | message: OK 24 | headers: 25 | Date: 26 | - Sat, 27 Apr 2024 11:46:19 GMT 27 | Content-Type: 28 | - application/json 29 | Transfer-Encoding: 30 | - chunked 31 | Connection: 32 | - keep-alive 33 | Openai-Version: 34 | - '2020-10-01' 35 | X-Request-Id: 36 | - req_cf835448d20433cce7b43909bd0c7ea8 37 | Openai-Processing-Ms: 38 | - '40' 39 | Access-Control-Allow-Origin: 40 | - "*" 41 | Strict-Transport-Security: 42 | - max-age=15724800; includeSubDomains 43 | Cf-Cache-Status: 44 | - DYNAMIC 45 | Set-Cookie: 46 | - __cf_bm=_eXpJA5dZ3Iz9_qoQNymKpqKLHLsZEdKqxGTCyOGtHQ-1714218379-1.0.1.1-LVHAwy3.gnF2dY_sbdaJGIq8NyFH4hqK9sdggW1vN1SW4oFDUyodj.uP584Q_lj9DkcUl3L6IsMqiWdqoFRqxg; 47 | path=/; expires=Sat, 27-Apr-24 12:16:19 GMT; domain=.api.openai.com; HttpOnly; 48 | Secure; SameSite=None 49 | - _cfuvid=Gm6N._3EC58LRuLAqngsZG7PkgcZmFEjJCaqg2FodXU-1714218379420-0.0.1.1-604800000; 50 | path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None 51 | Server: 52 | - cloudflare 53 | Cf-Ray: 54 | - 87ae924608e47141-SOF 55 | Alt-Svc: 56 | - h3=":443"; ma=86400 57 | body: 58 | encoding: ASCII-8BIT 59 | string: | 60 | { 61 | "id": "gpt-3.5-turbo-instruct", 62 | "object": "model", 63 | "created": 1692901427, 64 | "owned_by": "system" 65 | } 66 | recorded_at: Sat, 27 Apr 2024 11:46:19 GMT 67 | recorded_with: VCR 6.1.0 68 | -------------------------------------------------------------------------------- /spec/fixtures/cassettes/ollama_llama3_chat.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_interactions: 3 | - request: 4 | method: get 5 | uri: http://localhost:11434/ 6 | body: 7 | encoding: US-ASCII 8 | string: '' 9 | headers: 10 | User-Agent: 11 | - Faraday v2.8.1 12 | Accept-Encoding: 13 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 14 | Accept: 15 | - "*/*" 16 | response: 17 | status: 18 | code: 200 19 | message: OK 20 | headers: 21 | Content-Type: 22 | - text/plain; charset=utf-8 23 | Date: 24 | - Sun, 28 Apr 2024 12:58:36 GMT 25 | Content-Length: 26 | - '17' 27 | body: 28 | encoding: UTF-8 29 | string: Ollama is running 30 | recorded_at: Sun, 28 Apr 2024 12:58:36 GMT 31 | - request: 32 | method: post 33 | uri: http://localhost:11434/v1/chat/completions 34 | body: 35 | encoding: UTF-8 36 | string: '{"model":"llama3","messages":[{"role":"user","content":"Hello!"}],"stream":false}' 37 | headers: 38 | Content-Type: 39 | - application/json 40 | Authorization: 41 | - Bearer 42 | Accept-Encoding: 43 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 44 | Accept: 45 | - "*/*" 46 | User-Agent: 47 | - Ruby 48 | response: 49 | status: 50 | code: 200 51 | message: OK 52 | headers: 53 | Content-Type: 54 | - application/json 55 | Date: 56 | - Sun, 28 Apr 2024 12:58:37 GMT 57 | Content-Length: 58 | - '376' 59 | body: 60 | encoding: UTF-8 61 | string: '{"id":"chatcmpl-106","object":"chat.completion","created":1714309117,"model":"llama3","system_fingerprint":"fp_ollama","choices":[{"index":0,"message":{"role":"assistant","content":"Hello! 62 | It''s nice to meet you. Is there something I can help you with, or would you 63 | like to chat?"},"finish_reason":"stop"}],"usage":{"prompt_tokens":0,"completion_tokens":26,"total_tokens":26}} 64 | 65 | ' 66 | recorded_at: Sun, 28 Apr 2024 12:58:37 GMT 67 | recorded_with: VCR 6.1.0 68 | -------------------------------------------------------------------------------- /spec/fixtures/cassettes/runs_create_thread_and_run_assistant_setup.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_interactions: 3 | - request: 4 | method: post 5 | uri: https://api.openai.com/v1/assistants 6 | body: 7 | encoding: UTF-8 8 | string: '{"model":"gpt-4","name":"OpenAI-Ruby test assistant","instructions":"You 9 | are a Ruby dev bot. When asked a question, write and run Ruby code to answer 10 | the question"}' 11 | headers: 12 | Content-Type: 13 | - application/json 14 | Authorization: 15 | - Bearer 16 | Openai-Beta: 17 | - assistants=v2 18 | Accept-Encoding: 19 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 20 | Accept: 21 | - "*/*" 22 | User-Agent: 23 | - Ruby 24 | response: 25 | status: 26 | code: 200 27 | message: OK 28 | headers: 29 | Date: 30 | - Mon, 29 Apr 2024 23:35:35 GMT 31 | Content-Type: 32 | - application/json 33 | Transfer-Encoding: 34 | - chunked 35 | Connection: 36 | - keep-alive 37 | Openai-Version: 38 | - '2020-10-01' 39 | Openai-Organization: 40 | - user-jxm65ijkzc1qrfhc0ij8moic 41 | X-Request-Id: 42 | - req_65303f4ab0dc9ca53a54209978450a38 43 | Openai-Processing-Ms: 44 | - '82' 45 | Strict-Transport-Security: 46 | - max-age=15724800; includeSubDomains 47 | Cf-Cache-Status: 48 | - DYNAMIC 49 | Set-Cookie: 50 | - __cf_bm=hclv1xs61T2Au_wvXBWBBG8_cQ_KfaUSkhtrD7Il504-1714433735-1.0.1.1-2J3bLZqtXGvvBFZcNclT6xbxDIwenxw4aJ2scVfRwN3T0ETPKBj1wi0MX63M2_cOJnGeeZp9xH66AJNiek20iA; 51 | path=/; expires=Tue, 30-Apr-24 00:05:35 GMT; domain=.api.openai.com; HttpOnly; 52 | Secure; SameSite=None 53 | - _cfuvid=IfX9jEvrhi8qxEhEvHWSd58dFaxpIHQ7x0GWpM7IwuY-1714433735724-0.0.1.1-604800000; 54 | path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None 55 | Server: 56 | - cloudflare 57 | Cf-Ray: 58 | - 87c31bfefd6135dd-LHR 59 | Alt-Svc: 60 | - h3=":443"; ma=86400 61 | body: 62 | encoding: ASCII-8BIT 63 | string: |- 64 | { 65 | "id": "asst_VcuNVLAXPQLIZhuKZwFsYN8n", 66 | "object": "assistant", 67 | "created_at": 1714433735, 68 | "name": "OpenAI-Ruby test assistant", 69 | "description": null, 70 | "model": "gpt-4", 71 | "instructions": "You are a Ruby dev bot. When asked a question, write and run Ruby code to answer the question", 72 | "tools": [], 73 | "top_p": 1.0, 74 | "temperature": 1.0, 75 | "tool_resources": {}, 76 | "metadata": {}, 77 | "response_format": "auto" 78 | } 79 | recorded_at: Mon, 29 Apr 2024 23:35:35 GMT 80 | recorded_with: VCR 6.1.0 81 | -------------------------------------------------------------------------------- /spec/fixtures/cassettes/runs_streamed_create_assistant_setup.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_interactions: 3 | - request: 4 | method: post 5 | uri: https://api.openai.com/v1/assistants 6 | body: 7 | encoding: UTF-8 8 | string: '{"model":"gpt-4","name":"OpenAI-Ruby test assistant","instructions":"You 9 | are a Ruby dev bot. When asked a question, write and run Ruby code to answer 10 | the question"}' 11 | headers: 12 | Content-Type: 13 | - application/json 14 | Authorization: 15 | - Bearer 16 | Openai-Beta: 17 | - assistants=v2 18 | Accept-Encoding: 19 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 20 | Accept: 21 | - "*/*" 22 | User-Agent: 23 | - Ruby 24 | response: 25 | status: 26 | code: 200 27 | message: OK 28 | headers: 29 | Date: 30 | - Mon, 29 Apr 2024 23:35:28 GMT 31 | Content-Type: 32 | - application/json 33 | Transfer-Encoding: 34 | - chunked 35 | Connection: 36 | - keep-alive 37 | Openai-Version: 38 | - '2020-10-01' 39 | Openai-Organization: 40 | - user-jxm65ijkzc1qrfhc0ij8moic 41 | X-Request-Id: 42 | - req_28099de6f0242c80a7d8eddadcf9e9a1 43 | Openai-Processing-Ms: 44 | - '86' 45 | Strict-Transport-Security: 46 | - max-age=15724800; includeSubDomains 47 | Cf-Cache-Status: 48 | - DYNAMIC 49 | Set-Cookie: 50 | - __cf_bm=SFcsxSe8Zq3hPT4O7oghitN1wJ9mq_2_F6Do7fBcKXc-1714433728-1.0.1.1-FGOWJ2O4MO_mEf04sK0U7JQjUx3CZbqVTq3CneQBFiDqrvaEDYyFQoZHiXYb9US16giHQXYgYz1fenq7W6bvCw; 51 | path=/; expires=Tue, 30-Apr-24 00:05:28 GMT; domain=.api.openai.com; HttpOnly; 52 | Secure; SameSite=None 53 | - _cfuvid=7EUpdgDyQiDf3aHjm43JNJWgWT9qF.wpx9Irw8iKSC0-1714433728686-0.0.1.1-604800000; 54 | path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None 55 | Server: 56 | - cloudflare 57 | Cf-Ray: 58 | - 87c31bd2ffb4654d-LHR 59 | Alt-Svc: 60 | - h3=":443"; ma=86400 61 | body: 62 | encoding: ASCII-8BIT 63 | string: |- 64 | { 65 | "id": "asst_bZxEGReqm63trZ2h4pEDxSGU", 66 | "object": "assistant", 67 | "created_at": 1714433728, 68 | "name": "OpenAI-Ruby test assistant", 69 | "description": null, 70 | "model": "gpt-4", 71 | "instructions": "You are a Ruby dev bot. When asked a question, write and run Ruby code to answer the question", 72 | "tools": [], 73 | "top_p": 1.0, 74 | "temperature": 1.0, 75 | "tool_resources": {}, 76 | "metadata": {}, 77 | "response_format": "auto" 78 | } 79 | recorded_at: Mon, 29 Apr 2024 23:35:28 GMT 80 | recorded_with: VCR 6.1.0 81 | -------------------------------------------------------------------------------- /spec/fixtures/cassettes/vector_store_file_batches_cancel.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_interactions: 3 | - request: 4 | method: post 5 | uri: https://api.openai.com/v1/vector_stores/vs_QcdNZBbMIbTve3S9eR3n6E17/file_batches/vsfb_ddc37037b1d24838bcd3d3e4048aed78/cancel 6 | body: 7 | encoding: UTF-8 8 | string: '' 9 | headers: 10 | Content-Type: 11 | - application/json 12 | Authorization: 13 | - Bearer 14 | Openai-Beta: 15 | - assistants=v2 16 | Content-Length: 17 | - '0' 18 | Accept-Encoding: 19 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 20 | Accept: 21 | - "*/*" 22 | User-Agent: 23 | - Ruby 24 | response: 25 | status: 26 | code: 200 27 | message: OK 28 | headers: 29 | Date: 30 | - Tue, 30 Apr 2024 20:57:07 GMT 31 | Content-Type: 32 | - application/json 33 | Transfer-Encoding: 34 | - chunked 35 | Connection: 36 | - keep-alive 37 | Openai-Version: 38 | - '2020-10-01' 39 | Openai-Organization: 40 | - gojom-1 41 | X-Request-Id: 42 | - req_01318927b71a7d2e76268caf49b6bea6 43 | Openai-Processing-Ms: 44 | - '160' 45 | Strict-Transport-Security: 46 | - max-age=15724800; includeSubDomains 47 | Cf-Cache-Status: 48 | - DYNAMIC 49 | Set-Cookie: 50 | - __cf_bm=CW4.gWsOsjbXJymO5ablC3qenCCtJGSr5q_NAfl2MkI-1714510627-1.0.1.1-nOAqJv7NOFnDyBT7xtldezSDGwj9rqUGKjXeGPyrl9tzGWeqwOiRr5yvOSWe140snf1oCW1gXQNAoEUD4FNzVw; 51 | path=/; expires=Tue, 30-Apr-24 21:27:07 GMT; domain=.api.openai.com; HttpOnly; 52 | Secure; SameSite=None 53 | - _cfuvid=V.1YuucVb9ymbBXaDtPauuKH6mG7wQJLx_h7NMsuI9Y-1714510627214-0.0.1.1-604800000; 54 | path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None 55 | Server: 56 | - cloudflare 57 | Cf-Ray: 58 | - 87ca7139e8681d05-GRU 59 | Alt-Svc: 60 | - h3=":443"; ma=86400 61 | body: 62 | encoding: ASCII-8BIT 63 | string: |- 64 | { 65 | "id": "vsfb_ddc37037b1d24838bcd3d3e4048aed78", 66 | "object": "vector_store.file_batch", 67 | "created_at": 1714510627, 68 | "status": "completed", 69 | "vector_store_id": "vs_QcdNZBbMIbTve3S9eR3n6E17", 70 | "file_counts": { 71 | "in_progress": 0, 72 | "completed": 1, 73 | "failed": 0, 74 | "cancelled": 0, 75 | "total": 1 76 | } 77 | } 78 | recorded_at: Tue, 30 Apr 2024 20:57:07 GMT 79 | recorded_with: VCR 6.1.0 80 | -------------------------------------------------------------------------------- /spec/fixtures/cassettes/vector_store_file_batches_cancel_file_setup.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_interactions: 3 | - request: 4 | method: post 5 | uri: https://api.openai.com/v1/files 6 | body: 7 | encoding: UTF-8 8 | string: "-------------RubyMultipartPost-9d4b08578a07a38d43f31b7d4ec179d6\r\nContent-Disposition: 9 | form-data; name=\"file\"; filename=\"text.txt\"\r\nContent-Length: 12\r\nContent-Type: 10 | \r\nContent-Transfer-Encoding: binary\r\n\r\nHello world!\r\n-------------RubyMultipartPost-9d4b08578a07a38d43f31b7d4ec179d6\r\nContent-Disposition: 11 | form-data; name=\"purpose\"\r\n\r\nassistants\r\n-------------RubyMultipartPost-9d4b08578a07a38d43f31b7d4ec179d6--\r\n" 12 | headers: 13 | Content-Type: 14 | - multipart/form-data; boundary=-----------RubyMultipartPost-9d4b08578a07a38d43f31b7d4ec179d6 15 | Authorization: 16 | - Bearer 17 | Content-Length: 18 | - '412' 19 | Accept-Encoding: 20 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 21 | Accept: 22 | - "*/*" 23 | User-Agent: 24 | - Ruby 25 | response: 26 | status: 27 | code: 200 28 | message: OK 29 | headers: 30 | Date: 31 | - Tue, 30 Apr 2024 20:57:04 GMT 32 | Content-Type: 33 | - application/json 34 | Transfer-Encoding: 35 | - chunked 36 | Connection: 37 | - keep-alive 38 | Openai-Version: 39 | - '2020-10-01' 40 | Openai-Organization: 41 | - gojom-1 42 | X-Request-Id: 43 | - req_21964119e56a018b8b00698597f42cb6 44 | Openai-Processing-Ms: 45 | - '317' 46 | Access-Control-Allow-Origin: 47 | - "*" 48 | Strict-Transport-Security: 49 | - max-age=15724800; includeSubDomains 50 | Cf-Cache-Status: 51 | - DYNAMIC 52 | Set-Cookie: 53 | - __cf_bm=bviGzlDF..DQ0KO8MBAHUaTjtTIaRbZnq0odSanfOjc-1714510624-1.0.1.1-C4XW4a96lnVPkqWk5I6qwBxLrbSqFVInETD2q9g9dkO_louIzzDhzAkIpreojkPmEgOVrnJGHnb0PTt0ty9ucw; 54 | path=/; expires=Tue, 30-Apr-24 21:27:04 GMT; domain=.api.openai.com; HttpOnly; 55 | Secure; SameSite=None 56 | - _cfuvid=9R1vgPCl56KEwKDhhY4DCWkPS0lP8vWeRP6xvEc7OCY-1714510624660-0.0.1.1-604800000; 57 | path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None 58 | Server: 59 | - cloudflare 60 | Cf-Ray: 61 | - 87ca71291e5d6042-GRU 62 | Alt-Svc: 63 | - h3=":443"; ma=86400 64 | body: 65 | encoding: ASCII-8BIT 66 | string: | 67 | { 68 | "object": "file", 69 | "id": "file-FCgJPLryUiHJru6yPtHzjjh3", 70 | "purpose": "assistants", 71 | "filename": "text.txt", 72 | "bytes": 12, 73 | "created_at": 1714510624, 74 | "status": "processed", 75 | "status_details": null 76 | } 77 | recorded_at: Tue, 30 Apr 2024 20:57:04 GMT 78 | recorded_with: VCR 6.1.0 79 | -------------------------------------------------------------------------------- /spec/fixtures/cassettes/vector_store_file_batches_cancel_vector_store_file_batch_setup.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_interactions: 3 | - request: 4 | method: post 5 | uri: https://api.openai.com/v1/vector_stores/vs_QcdNZBbMIbTve3S9eR3n6E17/file_batches 6 | body: 7 | encoding: UTF-8 8 | string: '{"file_ids":["file-FCgJPLryUiHJru6yPtHzjjh3"]}' 9 | headers: 10 | Content-Type: 11 | - application/json 12 | Authorization: 13 | - Bearer 14 | Openai-Beta: 15 | - assistants=v2 16 | Accept-Encoding: 17 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 18 | Accept: 19 | - "*/*" 20 | User-Agent: 21 | - Ruby 22 | response: 23 | status: 24 | code: 200 25 | message: OK 26 | headers: 27 | Date: 28 | - Tue, 30 Apr 2024 20:57:06 GMT 29 | Content-Type: 30 | - application/json 31 | Transfer-Encoding: 32 | - chunked 33 | Connection: 34 | - keep-alive 35 | Openai-Version: 36 | - '2020-10-01' 37 | Openai-Organization: 38 | - gojom-1 39 | X-Request-Id: 40 | - req_392363d64cd7f8743b898817cb458029 41 | Openai-Processing-Ms: 42 | - '1304' 43 | Strict-Transport-Security: 44 | - max-age=15724800; includeSubDomains 45 | Cf-Cache-Status: 46 | - DYNAMIC 47 | Set-Cookie: 48 | - __cf_bm=47PRLUlyuH4HKYKMQ901.i_TVUaqOgJrLkG1jbf0.H4-1714510626-1.0.1.1-SYvxVeunnNO6OXjue3auNoVmsM5WOo_cDiTy5tSVkLrmeAEuxhjK9M9SmNchfm1jBE4yGPYoCRtNHGcjauG_jQ; 49 | path=/; expires=Tue, 30-Apr-24 21:27:06 GMT; domain=.api.openai.com; HttpOnly; 50 | Secure; SameSite=None 51 | - _cfuvid=sBcSLxgNVuwOEHPZC.tHuF_CNjsd71bN34tPquUs9J8-1714510626496-0.0.1.1-604800000; 52 | path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None 53 | Server: 54 | - cloudflare 55 | Cf-Ray: 56 | - 87ca712e1a021d23-GRU 57 | Alt-Svc: 58 | - h3=":443"; ma=86400 59 | body: 60 | encoding: ASCII-8BIT 61 | string: |- 62 | { 63 | "id": "vsfb_ddc37037b1d24838bcd3d3e4048aed78", 64 | "object": "vector_store.file_batch", 65 | "created_at": 1714510626, 66 | "status": "in_progress", 67 | "vector_store_id": "vs_QcdNZBbMIbTve3S9eR3n6E17", 68 | "file_counts": { 69 | "in_progress": 1, 70 | "completed": 0, 71 | "failed": 0, 72 | "cancelled": 0, 73 | "total": 1 74 | } 75 | } 76 | recorded_at: Tue, 30 Apr 2024 20:57:06 GMT 77 | recorded_with: VCR 6.1.0 78 | -------------------------------------------------------------------------------- /spec/fixtures/cassettes/vector_store_file_batches_cancel_vector_store_setup.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_interactions: 3 | - request: 4 | method: post 5 | uri: https://api.openai.com/v1/vector_stores 6 | body: 7 | encoding: UTF-8 8 | string: "{}" 9 | headers: 10 | Content-Type: 11 | - application/json 12 | Authorization: 13 | - Bearer 14 | Openai-Beta: 15 | - assistants=v2 16 | Accept-Encoding: 17 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 18 | Accept: 19 | - "*/*" 20 | User-Agent: 21 | - Ruby 22 | response: 23 | status: 24 | code: 200 25 | message: OK 26 | headers: 27 | Date: 28 | - Tue, 30 Apr 2024 20:57:03 GMT 29 | Content-Type: 30 | - application/json 31 | Transfer-Encoding: 32 | - chunked 33 | Connection: 34 | - keep-alive 35 | Openai-Version: 36 | - '2020-10-01' 37 | Openai-Organization: 38 | - gojom-1 39 | X-Request-Id: 40 | - req_b83730544ba66caa0a55fe6a86ddd3a3 41 | Openai-Processing-Ms: 42 | - '90' 43 | Strict-Transport-Security: 44 | - max-age=15724800; includeSubDomains 45 | Cf-Cache-Status: 46 | - DYNAMIC 47 | Set-Cookie: 48 | - __cf_bm=xaro7eJPFfRfyJZi3cdgVlf3KWcl5pxwHhtoRIFc3Fk-1714510623-1.0.1.1-mseJiuH9gW9tOaeBs4xt5Snjj3Pp.w1lePVrfMd_mVyduaPZT7CLgTo2U_uA3BKMnQMcf0ffF.oK1bC0T3u.dA; 49 | path=/; expires=Tue, 30-Apr-24 21:27:03 GMT; domain=.api.openai.com; HttpOnly; 50 | Secure; SameSite=None 51 | - _cfuvid=aA_3agUxvEM6rdu8vD5kzVC1FyTjE5qYigeF6FGAQRw-1714510623770-0.0.1.1-604800000; 52 | path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None 53 | Server: 54 | - cloudflare 55 | Cf-Ray: 56 | - 87ca7124c9331cd9-GRU 57 | Alt-Svc: 58 | - h3=":443"; ma=86400 59 | body: 60 | encoding: ASCII-8BIT 61 | string: |- 62 | { 63 | "id": "vs_QcdNZBbMIbTve3S9eR3n6E17", 64 | "object": "vector_store", 65 | "name": null, 66 | "status": "completed", 67 | "usage_bytes": 0, 68 | "created_at": 1714510623, 69 | "file_counts": { 70 | "in_progress": 0, 71 | "completed": 0, 72 | "failed": 0, 73 | "cancelled": 0, 74 | "total": 0 75 | }, 76 | "metadata": {}, 77 | "expires_after": null, 78 | "expires_at": null, 79 | "last_active_at": 1714510623 80 | } 81 | recorded_at: Tue, 30 Apr 2024 20:57:03 GMT 82 | recorded_with: VCR 6.1.0 83 | -------------------------------------------------------------------------------- /spec/fixtures/cassettes/vector_store_file_batches_create.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_interactions: 3 | - request: 4 | method: post 5 | uri: https://api.openai.com/v1/vector_stores/vs_yrC4Y143ue4kRkSxu1VW8ece/file_batches 6 | body: 7 | encoding: UTF-8 8 | string: '{"file_ids":["file-0cXHcvZknvN0EVU5JpYm5S0U"]}' 9 | headers: 10 | Content-Type: 11 | - application/json 12 | Authorization: 13 | - Bearer 14 | Openai-Beta: 15 | - assistants=v2 16 | Accept-Encoding: 17 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 18 | Accept: 19 | - "*/*" 20 | User-Agent: 21 | - Ruby 22 | response: 23 | status: 24 | code: 200 25 | message: OK 26 | headers: 27 | Date: 28 | - Tue, 30 Apr 2024 20:57:03 GMT 29 | Content-Type: 30 | - application/json 31 | Transfer-Encoding: 32 | - chunked 33 | Connection: 34 | - keep-alive 35 | Openai-Version: 36 | - '2020-10-01' 37 | Openai-Organization: 38 | - gojom-1 39 | X-Request-Id: 40 | - req_8638f3897e8c10d74d1190da9f93d209 41 | Openai-Processing-Ms: 42 | - '1320' 43 | Strict-Transport-Security: 44 | - max-age=15724800; includeSubDomains 45 | Cf-Cache-Status: 46 | - DYNAMIC 47 | Set-Cookie: 48 | - __cf_bm=_9xWEs0qkyyHhWE4G.xiCuJ7sWhzQDslhHKnn52wtn4-1714510623-1.0.1.1-beVdeaEW61ignNBFm9iLhg7PLkWIloagNkeksWrIVDIlrGvw33cRJARNQ9qXTzzkum8eIwTQX_0.1pIodbMXZQ; 49 | path=/; expires=Tue, 30-Apr-24 21:27:03 GMT; domain=.api.openai.com; HttpOnly; 50 | Secure; SameSite=None 51 | - _cfuvid=b09APS.Dvj7RBLVOouT5TcjuifdpbuQvMsKIeJ3HNEM-1714510623065-0.0.1.1-604800000; 52 | path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None 53 | Server: 54 | - cloudflare 55 | Cf-Ray: 56 | - 87ca71188de61d38-GRU 57 | Alt-Svc: 58 | - h3=":443"; ma=86400 59 | body: 60 | encoding: ASCII-8BIT 61 | string: |- 62 | { 63 | "id": "vsfb_2ff3927d8fd542d59610690b460d5d62", 64 | "object": "vector_store.file_batch", 65 | "created_at": 1714510622, 66 | "status": "in_progress", 67 | "vector_store_id": "vs_yrC4Y143ue4kRkSxu1VW8ece", 68 | "file_counts": { 69 | "in_progress": 1, 70 | "completed": 0, 71 | "failed": 0, 72 | "cancelled": 0, 73 | "total": 1 74 | } 75 | } 76 | recorded_at: Tue, 30 Apr 2024 20:57:03 GMT 77 | recorded_with: VCR 6.1.0 78 | -------------------------------------------------------------------------------- /spec/fixtures/cassettes/vector_store_file_batches_create_file_setup.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_interactions: 3 | - request: 4 | method: post 5 | uri: https://api.openai.com/v1/files 6 | body: 7 | encoding: UTF-8 8 | string: "-------------RubyMultipartPost-c06c63cdf2979ada70d6aef04da40621\r\nContent-Disposition: 9 | form-data; name=\"file\"; filename=\"text.txt\"\r\nContent-Length: 12\r\nContent-Type: 10 | \r\nContent-Transfer-Encoding: binary\r\n\r\nHello world!\r\n-------------RubyMultipartPost-c06c63cdf2979ada70d6aef04da40621\r\nContent-Disposition: 11 | form-data; name=\"purpose\"\r\n\r\nassistants\r\n-------------RubyMultipartPost-c06c63cdf2979ada70d6aef04da40621--\r\n" 12 | headers: 13 | Content-Type: 14 | - multipart/form-data; boundary=-----------RubyMultipartPost-c06c63cdf2979ada70d6aef04da40621 15 | Authorization: 16 | - Bearer 17 | Content-Length: 18 | - '412' 19 | Accept-Encoding: 20 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 21 | Accept: 22 | - "*/*" 23 | User-Agent: 24 | - Ruby 25 | response: 26 | status: 27 | code: 200 28 | message: OK 29 | headers: 30 | Date: 31 | - Tue, 30 Apr 2024 20:57:01 GMT 32 | Content-Type: 33 | - application/json 34 | Transfer-Encoding: 35 | - chunked 36 | Connection: 37 | - keep-alive 38 | Openai-Version: 39 | - '2020-10-01' 40 | Openai-Organization: 41 | - gojom-1 42 | X-Request-Id: 43 | - req_8ebbd1ab1c6fff2cd3492f99017ed3a7 44 | Openai-Processing-Ms: 45 | - '267' 46 | Access-Control-Allow-Origin: 47 | - "*" 48 | Strict-Transport-Security: 49 | - max-age=15724800; includeSubDomains 50 | Cf-Cache-Status: 51 | - DYNAMIC 52 | Set-Cookie: 53 | - __cf_bm=1QehjW4quOgi3LwKuz6Dhg16b_rTcE62Tp92ix686wA-1714510621-1.0.1.1-5p_R41aVgF5dYR1E5mHIRPHUNWlMpvLo9nTl1qrZUL3IZB8HvjIw0G_R6X645oj8LgOhEpFUMaA2wW3K0HNSAg; 54 | path=/; expires=Tue, 30-Apr-24 21:27:01 GMT; domain=.api.openai.com; HttpOnly; 55 | Secure; SameSite=None 56 | - _cfuvid=sXpohW253cZajxPzfWAM5er.dkbSLezjAiQMSW0jCzM-1714510621096-0.0.1.1-604800000; 57 | path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None 58 | Server: 59 | - cloudflare 60 | Cf-Ray: 61 | - 87ca7112fbf5017c-GRU 62 | Alt-Svc: 63 | - h3=":443"; ma=86400 64 | body: 65 | encoding: ASCII-8BIT 66 | string: | 67 | { 68 | "object": "file", 69 | "id": "file-0cXHcvZknvN0EVU5JpYm5S0U", 70 | "purpose": "assistants", 71 | "filename": "text.txt", 72 | "bytes": 12, 73 | "created_at": 1714510620, 74 | "status": "processed", 75 | "status_details": null 76 | } 77 | recorded_at: Tue, 30 Apr 2024 20:57:01 GMT 78 | recorded_with: VCR 6.1.0 79 | -------------------------------------------------------------------------------- /spec/fixtures/cassettes/vector_store_file_batches_create_vector_store_setup.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_interactions: 3 | - request: 4 | method: post 5 | uri: https://api.openai.com/v1/vector_stores 6 | body: 7 | encoding: UTF-8 8 | string: "{}" 9 | headers: 10 | Content-Type: 11 | - application/json 12 | Authorization: 13 | - Bearer 14 | Openai-Beta: 15 | - assistants=v2 16 | Accept-Encoding: 17 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 18 | Accept: 19 | - "*/*" 20 | User-Agent: 21 | - Ruby 22 | response: 23 | status: 24 | code: 200 25 | message: OK 26 | headers: 27 | Date: 28 | - Tue, 30 Apr 2024 20:57:00 GMT 29 | Content-Type: 30 | - application/json 31 | Transfer-Encoding: 32 | - chunked 33 | Connection: 34 | - keep-alive 35 | Openai-Version: 36 | - '2020-10-01' 37 | Openai-Organization: 38 | - gojom-1 39 | X-Request-Id: 40 | - req_955b147716739c3503980367c407ba58 41 | Openai-Processing-Ms: 42 | - '97' 43 | Strict-Transport-Security: 44 | - max-age=15724800; includeSubDomains 45 | Cf-Cache-Status: 46 | - DYNAMIC 47 | Set-Cookie: 48 | - __cf_bm=vvuy0cSxYfodWo38srzu_A4cvptGKewqZJ5xLDEnpyQ-1714510620-1.0.1.1-SQbvfETsOJVM9GzWoLBdKkv.BwOMdSVkPbQ9WkAkPBm3Ww0sKau4b_yjUVGyOf.2oZDXFv.rDPvOLpyhXvxhFQ; 49 | path=/; expires=Tue, 30-Apr-24 21:27:00 GMT; domain=.api.openai.com; HttpOnly; 50 | Secure; SameSite=None 51 | - _cfuvid=9Qv_OTKYlWuDHULv1b5MmFCbqRdgZOqHMZ8mOmygvdg-1714510620323-0.0.1.1-604800000; 52 | path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None 53 | Server: 54 | - cloudflare 55 | Cf-Ray: 56 | - 87ca710f3bfb77ca-GRU 57 | Alt-Svc: 58 | - h3=":443"; ma=86400 59 | body: 60 | encoding: ASCII-8BIT 61 | string: |- 62 | { 63 | "id": "vs_yrC4Y143ue4kRkSxu1VW8ece", 64 | "object": "vector_store", 65 | "name": null, 66 | "status": "completed", 67 | "usage_bytes": 0, 68 | "created_at": 1714510620, 69 | "file_counts": { 70 | "in_progress": 0, 71 | "completed": 0, 72 | "failed": 0, 73 | "cancelled": 0, 74 | "total": 0 75 | }, 76 | "metadata": {}, 77 | "expires_after": null, 78 | "expires_at": null, 79 | "last_active_at": 1714510620 80 | } 81 | recorded_at: Tue, 30 Apr 2024 20:57:00 GMT 82 | recorded_with: VCR 6.1.0 83 | -------------------------------------------------------------------------------- /spec/fixtures/cassettes/vector_store_file_batches_list.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_interactions: 3 | - request: 4 | method: get 5 | uri: https://api.openai.com/v1/vector_stores/vs_ePcVDZvWrtnriEvWr8nNZMRH/file_batches/vsfb_21d3cfd33a4d412a87c49d6eec59c717/files 6 | body: 7 | encoding: US-ASCII 8 | string: '' 9 | headers: 10 | Content-Type: 11 | - application/json 12 | Authorization: 13 | - Bearer 14 | Openai-Beta: 15 | - assistants=v2 16 | Accept-Encoding: 17 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 18 | Accept: 19 | - "*/*" 20 | User-Agent: 21 | - Ruby 22 | response: 23 | status: 24 | code: 200 25 | message: OK 26 | headers: 27 | Date: 28 | - Tue, 30 Apr 2024 20:56:55 GMT 29 | Content-Type: 30 | - application/json 31 | Transfer-Encoding: 32 | - chunked 33 | Connection: 34 | - keep-alive 35 | Openai-Version: 36 | - '2020-10-01' 37 | Openai-Organization: 38 | - gojom-1 39 | X-Request-Id: 40 | - req_5d93157b96f17bc5b174d51922d8adde 41 | Openai-Processing-Ms: 42 | - '130' 43 | Strict-Transport-Security: 44 | - max-age=15724800; includeSubDomains 45 | Cf-Cache-Status: 46 | - DYNAMIC 47 | Set-Cookie: 48 | - __cf_bm=Mf2Gs1GaGiP2oSbvrA2iPxZbPp3LFwI3LsmzzhQGM6s-1714510615-1.0.1.1-aY5pEt1sqvtL2TupaGPgcdQIOLyRMbDguidiGHaJp9I2t4vL_Fn54DbckkMOfPWldb4RdbpFeZ5VbDIFnCbEoQ; 49 | path=/; expires=Tue, 30-Apr-24 21:26:55 GMT; domain=.api.openai.com; HttpOnly; 50 | Secure; SameSite=None 51 | - _cfuvid=yqek7SB410BpvVOCJENCg.CmMivh63aR6SafB31dpBY-1714510615078-0.0.1.1-604800000; 52 | path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None 53 | Server: 54 | - cloudflare 55 | Cf-Ray: 56 | - 87ca70ee2d964d41-GRU 57 | Alt-Svc: 58 | - h3=":443"; ma=86400 59 | body: 60 | encoding: ASCII-8BIT 61 | string: |- 62 | { 63 | "object": "list", 64 | "data": [ 65 | { 66 | "id": "file-cEwnAjZSvtO66i8Qnj0R9d0M", 67 | "object": "vector_store.file", 68 | "created_at": 1714510613, 69 | "vector_store_id": "vs_ePcVDZvWrtnriEvWr8nNZMRH", 70 | "status": "completed", 71 | "last_error": null 72 | } 73 | ], 74 | "first_id": "file-cEwnAjZSvtO66i8Qnj0R9d0M", 75 | "last_id": "file-cEwnAjZSvtO66i8Qnj0R9d0M", 76 | "has_more": false 77 | } 78 | recorded_at: Tue, 30 Apr 2024 20:56:55 GMT 79 | recorded_with: VCR 6.1.0 80 | -------------------------------------------------------------------------------- /spec/fixtures/cassettes/vector_store_file_batches_list_file_setup.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_interactions: 3 | - request: 4 | method: post 5 | uri: https://api.openai.com/v1/files 6 | body: 7 | encoding: UTF-8 8 | string: "-------------RubyMultipartPost-e7d4131f37ca38d621f8be57de48d6f4\r\nContent-Disposition: 9 | form-data; name=\"file\"; filename=\"text.txt\"\r\nContent-Length: 12\r\nContent-Type: 10 | \r\nContent-Transfer-Encoding: binary\r\n\r\nHello world!\r\n-------------RubyMultipartPost-e7d4131f37ca38d621f8be57de48d6f4\r\nContent-Disposition: 11 | form-data; name=\"purpose\"\r\n\r\nassistants\r\n-------------RubyMultipartPost-e7d4131f37ca38d621f8be57de48d6f4--\r\n" 12 | headers: 13 | Content-Type: 14 | - multipart/form-data; boundary=-----------RubyMultipartPost-e7d4131f37ca38d621f8be57de48d6f4 15 | Authorization: 16 | - Bearer 17 | Content-Length: 18 | - '412' 19 | Accept-Encoding: 20 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 21 | Accept: 22 | - "*/*" 23 | User-Agent: 24 | - Ruby 25 | response: 26 | status: 27 | code: 200 28 | message: OK 29 | headers: 30 | Date: 31 | - Tue, 30 Apr 2024 20:56:52 GMT 32 | Content-Type: 33 | - application/json 34 | Transfer-Encoding: 35 | - chunked 36 | Connection: 37 | - keep-alive 38 | Openai-Version: 39 | - '2020-10-01' 40 | Openai-Organization: 41 | - gojom-1 42 | X-Request-Id: 43 | - req_7c14e341879f3238a0252b081e783304 44 | Openai-Processing-Ms: 45 | - '450' 46 | Access-Control-Allow-Origin: 47 | - "*" 48 | Strict-Transport-Security: 49 | - max-age=15724800; includeSubDomains 50 | Cf-Cache-Status: 51 | - DYNAMIC 52 | Set-Cookie: 53 | - __cf_bm=k.ilft8rzJKNQpfC5XRmcu5Ab4P232DYufCBpj5Z7XE-1714510612-1.0.1.1-MZ4dBI0nXovhrOYiY9dON5s3NVZJgq4Jr3wisr6BvF6BRJ2HcqBUckJkctQZ.dG.W9TIGWZSnW.e1kK0Nct90g; 54 | path=/; expires=Tue, 30-Apr-24 21:26:52 GMT; domain=.api.openai.com; HttpOnly; 55 | Secure; SameSite=None 56 | - _cfuvid=ALwWuwjmiibvuT9KBjPHAPpX59AIZ7CxZ03xn0wz6q8-1714510612520-0.0.1.1-604800000; 57 | path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None 58 | Server: 59 | - cloudflare 60 | Cf-Ray: 61 | - 87ca70dc5b710120-GRU 62 | Alt-Svc: 63 | - h3=":443"; ma=86400 64 | body: 65 | encoding: ASCII-8BIT 66 | string: | 67 | { 68 | "object": "file", 69 | "id": "file-cEwnAjZSvtO66i8Qnj0R9d0M", 70 | "purpose": "assistants", 71 | "filename": "text.txt", 72 | "bytes": 12, 73 | "created_at": 1714510612, 74 | "status": "processed", 75 | "status_details": null 76 | } 77 | recorded_at: Tue, 30 Apr 2024 20:56:52 GMT 78 | recorded_with: VCR 6.1.0 79 | -------------------------------------------------------------------------------- /spec/fixtures/cassettes/vector_store_file_batches_list_vector_store_file_batch_setup.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_interactions: 3 | - request: 4 | method: post 5 | uri: https://api.openai.com/v1/vector_stores/vs_ePcVDZvWrtnriEvWr8nNZMRH/file_batches 6 | body: 7 | encoding: UTF-8 8 | string: '{"file_ids":["file-cEwnAjZSvtO66i8Qnj0R9d0M"]}' 9 | headers: 10 | Content-Type: 11 | - application/json 12 | Authorization: 13 | - Bearer 14 | Openai-Beta: 15 | - assistants=v2 16 | Accept-Encoding: 17 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 18 | Accept: 19 | - "*/*" 20 | User-Agent: 21 | - Ruby 22 | response: 23 | status: 24 | code: 200 25 | message: OK 26 | headers: 27 | Date: 28 | - Tue, 30 Apr 2024 20:56:54 GMT 29 | Content-Type: 30 | - application/json 31 | Transfer-Encoding: 32 | - chunked 33 | Connection: 34 | - keep-alive 35 | Openai-Version: 36 | - '2020-10-01' 37 | Openai-Organization: 38 | - gojom-1 39 | X-Request-Id: 40 | - req_8d320fce7748107730d9d405b28623f5 41 | Openai-Processing-Ms: 42 | - '1345' 43 | Strict-Transport-Security: 44 | - max-age=15724800; includeSubDomains 45 | Cf-Cache-Status: 46 | - DYNAMIC 47 | Set-Cookie: 48 | - __cf_bm=SwPHin4piuDwtklPtj502hRIK9uCEYQTXgh31SyaSKM-1714510614-1.0.1.1-h0Z_K_u70zj2Heisvf_qypRqpLX1gZ7EUBqxOEW9qkJcpokLLnxhsc6nJepW9ZgIR8dPsy7Xt0P3nE0o04d1Kw; 49 | path=/; expires=Tue, 30-Apr-24 21:26:54 GMT; domain=.api.openai.com; HttpOnly; 50 | Secure; SameSite=None 51 | - _cfuvid=w0QMulbhz7kIKKZUTSS54CnF8vaaiRJIHwvnAHgCaMU-1714510614383-0.0.1.1-604800000; 52 | path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None 53 | Server: 54 | - cloudflare 55 | Cf-Ray: 56 | - 87ca70e2490e77c3-GRU 57 | Alt-Svc: 58 | - h3=":443"; ma=86400 59 | body: 60 | encoding: ASCII-8BIT 61 | string: |- 62 | { 63 | "id": "vsfb_21d3cfd33a4d412a87c49d6eec59c717", 64 | "object": "vector_store.file_batch", 65 | "created_at": 1714510614, 66 | "status": "in_progress", 67 | "vector_store_id": "vs_ePcVDZvWrtnriEvWr8nNZMRH", 68 | "file_counts": { 69 | "in_progress": 1, 70 | "completed": 0, 71 | "failed": 0, 72 | "cancelled": 0, 73 | "total": 1 74 | } 75 | } 76 | recorded_at: Tue, 30 Apr 2024 20:56:54 GMT 77 | recorded_with: VCR 6.1.0 78 | -------------------------------------------------------------------------------- /spec/fixtures/cassettes/vector_store_file_batches_list_vector_store_setup.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_interactions: 3 | - request: 4 | method: post 5 | uri: https://api.openai.com/v1/vector_stores 6 | body: 7 | encoding: UTF-8 8 | string: "{}" 9 | headers: 10 | Content-Type: 11 | - application/json 12 | Authorization: 13 | - Bearer 14 | Openai-Beta: 15 | - assistants=v2 16 | Accept-Encoding: 17 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 18 | Accept: 19 | - "*/*" 20 | User-Agent: 21 | - Ruby 22 | response: 23 | status: 24 | code: 200 25 | message: OK 26 | headers: 27 | Date: 28 | - Tue, 30 Apr 2024 20:56:51 GMT 29 | Content-Type: 30 | - application/json 31 | Transfer-Encoding: 32 | - chunked 33 | Connection: 34 | - keep-alive 35 | Openai-Version: 36 | - '2020-10-01' 37 | Openai-Organization: 38 | - gojom-1 39 | X-Request-Id: 40 | - req_8e9e596bbc603f472420726196a08e0a 41 | Openai-Processing-Ms: 42 | - '137' 43 | Strict-Transport-Security: 44 | - max-age=15724800; includeSubDomains 45 | Cf-Cache-Status: 46 | - DYNAMIC 47 | Set-Cookie: 48 | - __cf_bm=QJPVFPWnSn96FYjZkHJjBxfB79bvoE1WUYQeZx.e4cI-1714510611-1.0.1.1-Dhp.gw6KY94CbdsfLnOhRG8.MIjwB7UyrMKvkx6FT4O8hPuajFWkfjnbXej8znctEjDoCyHy3Q2SRTTRQ_49vg; 49 | path=/; expires=Tue, 30-Apr-24 21:26:51 GMT; domain=.api.openai.com; HttpOnly; 50 | Secure; SameSite=None 51 | - _cfuvid=gG3A57J2zzgM6ZWH_0pHRrYf4u1Tna2Q2JElNY_tlTc-1714510611505-0.0.1.1-604800000; 52 | path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None 53 | Server: 54 | - cloudflare 55 | Cf-Ray: 56 | - 87ca70d7c9b66b0f-GRU 57 | Alt-Svc: 58 | - h3=":443"; ma=86400 59 | body: 60 | encoding: ASCII-8BIT 61 | string: |- 62 | { 63 | "id": "vs_ePcVDZvWrtnriEvWr8nNZMRH", 64 | "object": "vector_store", 65 | "name": null, 66 | "status": "completed", 67 | "usage_bytes": 0, 68 | "created_at": 1714510611, 69 | "file_counts": { 70 | "in_progress": 0, 71 | "completed": 0, 72 | "failed": 0, 73 | "cancelled": 0, 74 | "total": 0 75 | }, 76 | "metadata": {}, 77 | "expires_after": null, 78 | "expires_at": null, 79 | "last_active_at": 1714510611 80 | } 81 | recorded_at: Tue, 30 Apr 2024 20:56:51 GMT 82 | recorded_with: VCR 6.1.0 83 | -------------------------------------------------------------------------------- /spec/fixtures/cassettes/vector_store_file_batches_retrieve.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_interactions: 3 | - request: 4 | method: get 5 | uri: https://api.openai.com/v1/vector_stores/vs_qBhwT3kAs6fxYFe9VHcwDwAB/file_batches/vsfb_6fbe4acad12b408191386a762ebbd09a 6 | body: 7 | encoding: US-ASCII 8 | string: '' 9 | headers: 10 | Content-Type: 11 | - application/json 12 | Authorization: 13 | - Bearer 14 | Openai-Beta: 15 | - assistants=v2 16 | Accept-Encoding: 17 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 18 | Accept: 19 | - "*/*" 20 | User-Agent: 21 | - Ruby 22 | response: 23 | status: 24 | code: 200 25 | message: OK 26 | headers: 27 | Date: 28 | - Tue, 30 Apr 2024 20:56:59 GMT 29 | Content-Type: 30 | - application/json 31 | Transfer-Encoding: 32 | - chunked 33 | Connection: 34 | - keep-alive 35 | Openai-Version: 36 | - '2020-10-01' 37 | Openai-Organization: 38 | - gojom-1 39 | X-Request-Id: 40 | - req_4e502a48d951c1b6b3dac1549493117b 41 | Openai-Processing-Ms: 42 | - '105' 43 | Strict-Transport-Security: 44 | - max-age=15724800; includeSubDomains 45 | Cf-Cache-Status: 46 | - DYNAMIC 47 | Set-Cookie: 48 | - __cf_bm=W1XghgolgKcQCFAlR9SJ_KQRc6dgGOXq.6ytEftYzxE-1714510619-1.0.1.1-Uog84zWTKxDR4q210jX8y9WYL96XFpH_1o2ItlT6bRuwt6698RrksX8NGJ1FckCeyfaIiFkHttqgEcTqR8FpmQ; 49 | path=/; expires=Tue, 30-Apr-24 21:26:59 GMT; domain=.api.openai.com; HttpOnly; 50 | Secure; SameSite=None 51 | - _cfuvid=iFpRSxHh0JNtkqQa6aYanuIedEYcri4bCDt2pL8urrE-1714510619582-0.0.1.1-604800000; 52 | path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None 53 | Server: 54 | - cloudflare 55 | Cf-Ray: 56 | - 87ca710a8d0051e0-GRU 57 | Alt-Svc: 58 | - h3=":443"; ma=86400 59 | body: 60 | encoding: ASCII-8BIT 61 | string: |- 62 | { 63 | "id": "vsfb_6fbe4acad12b408191386a762ebbd09a", 64 | "object": "vector_store.file_batch", 65 | "created_at": 1714510619, 66 | "status": "completed", 67 | "vector_store_id": "vs_qBhwT3kAs6fxYFe9VHcwDwAB", 68 | "file_counts": { 69 | "in_progress": 0, 70 | "completed": 1, 71 | "failed": 0, 72 | "cancelled": 0, 73 | "total": 1 74 | } 75 | } 76 | recorded_at: Tue, 30 Apr 2024 20:56:59 GMT 77 | recorded_with: VCR 6.1.0 78 | -------------------------------------------------------------------------------- /spec/fixtures/cassettes/vector_store_file_batches_retrieve_file_setup.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_interactions: 3 | - request: 4 | method: post 5 | uri: https://api.openai.com/v1/files 6 | body: 7 | encoding: UTF-8 8 | string: "-------------RubyMultipartPost-c1df6f9b53e729ec7d2d8bcc32d623e3\r\nContent-Disposition: 9 | form-data; name=\"file\"; filename=\"text.txt\"\r\nContent-Length: 12\r\nContent-Type: 10 | \r\nContent-Transfer-Encoding: binary\r\n\r\nHello world!\r\n-------------RubyMultipartPost-c1df6f9b53e729ec7d2d8bcc32d623e3\r\nContent-Disposition: 11 | form-data; name=\"purpose\"\r\n\r\nassistants\r\n-------------RubyMultipartPost-c1df6f9b53e729ec7d2d8bcc32d623e3--\r\n" 12 | headers: 13 | Content-Type: 14 | - multipart/form-data; boundary=-----------RubyMultipartPost-c1df6f9b53e729ec7d2d8bcc32d623e3 15 | Authorization: 16 | - Bearer 17 | Content-Length: 18 | - '412' 19 | Accept-Encoding: 20 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 21 | Accept: 22 | - "*/*" 23 | User-Agent: 24 | - Ruby 25 | response: 26 | status: 27 | code: 200 28 | message: OK 29 | headers: 30 | Date: 31 | - Tue, 30 Apr 2024 20:56:57 GMT 32 | Content-Type: 33 | - application/json 34 | Transfer-Encoding: 35 | - chunked 36 | Connection: 37 | - keep-alive 38 | Openai-Version: 39 | - '2020-10-01' 40 | Openai-Organization: 41 | - gojom-1 42 | X-Request-Id: 43 | - req_fb4aa737a97203391a2dc39dec7e2840 44 | Openai-Processing-Ms: 45 | - '380' 46 | Access-Control-Allow-Origin: 47 | - "*" 48 | Strict-Transport-Security: 49 | - max-age=15724800; includeSubDomains 50 | Cf-Cache-Status: 51 | - DYNAMIC 52 | Set-Cookie: 53 | - __cf_bm=px1dAsobpO1MbhxZnXEwenhNgfH4tEGQZBbgfoMna1o-1714510617-1.0.1.1-HhZceBpfjnroFBisRk2_D6xJrUFKsoYvt9K7us6QGzLpIRraTdOYryXd7af52FKcht_Wa_Z5w_1GTihLGNhdTw; 54 | path=/; expires=Tue, 30-Apr-24 21:26:57 GMT; domain=.api.openai.com; HttpOnly; 55 | Secure; SameSite=None 56 | - _cfuvid=.9E.dxvI2fIbqN7t8ezZzNt6xtUyBTb6CtlyMoYH9kY-1714510617081-0.0.1.1-604800000; 57 | path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None 58 | Server: 59 | - cloudflare 60 | Cf-Ray: 61 | - 87ca70f93d56a163-GRU 62 | Alt-Svc: 63 | - h3=":443"; ma=86400 64 | body: 65 | encoding: ASCII-8BIT 66 | string: | 67 | { 68 | "object": "file", 69 | "id": "file-CgOz2aPJTpMBLCPfvdGHpSkx", 70 | "purpose": "assistants", 71 | "filename": "text.txt", 72 | "bytes": 12, 73 | "created_at": 1714510616, 74 | "status": "processed", 75 | "status_details": null 76 | } 77 | recorded_at: Tue, 30 Apr 2024 20:56:57 GMT 78 | recorded_with: VCR 6.1.0 79 | -------------------------------------------------------------------------------- /spec/fixtures/cassettes/vector_store_file_batches_retrieve_vector_store_file_batch_setup.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_interactions: 3 | - request: 4 | method: post 5 | uri: https://api.openai.com/v1/vector_stores/vs_qBhwT3kAs6fxYFe9VHcwDwAB/file_batches 6 | body: 7 | encoding: UTF-8 8 | string: '{"file_ids":["file-CgOz2aPJTpMBLCPfvdGHpSkx"]}' 9 | headers: 10 | Content-Type: 11 | - application/json 12 | Authorization: 13 | - Bearer 14 | Openai-Beta: 15 | - assistants=v2 16 | Accept-Encoding: 17 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 18 | Accept: 19 | - "*/*" 20 | User-Agent: 21 | - Ruby 22 | response: 23 | status: 24 | code: 200 25 | message: OK 26 | headers: 27 | Date: 28 | - Tue, 30 Apr 2024 20:56:58 GMT 29 | Content-Type: 30 | - application/json 31 | Transfer-Encoding: 32 | - chunked 33 | Connection: 34 | - keep-alive 35 | Openai-Version: 36 | - '2020-10-01' 37 | Openai-Organization: 38 | - gojom-1 39 | X-Request-Id: 40 | - req_c71f2f212de799ee10c1f74d819a8ae5 41 | Openai-Processing-Ms: 42 | - '1290' 43 | Strict-Transport-Security: 44 | - max-age=15724800; includeSubDomains 45 | Cf-Cache-Status: 46 | - DYNAMIC 47 | Set-Cookie: 48 | - __cf_bm=oJcJmsXeX.ucP8xdV5S7DTKBzXff4MEIcx7PNirf4uU-1714510618-1.0.1.1-4bLUhyeHh.WJFo_Iv4htzZtWvlUXP58bp1ygxBsibDDg_OOqKBsYTe0mhqr7XMUmSbPYcWv0WiX8rc1t4C_oyg; 49 | path=/; expires=Tue, 30-Apr-24 21:26:58 GMT; domain=.api.openai.com; HttpOnly; 50 | Secure; SameSite=None 51 | - _cfuvid=rAoE9AXKR.nubOCsdNZ2gK.MSNoLlaga8xwRqXsy_gE-1714510618932-0.0.1.1-604800000; 52 | path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None 53 | Server: 54 | - cloudflare 55 | Cf-Ray: 56 | - 87ca70fece02a197-GRU 57 | Alt-Svc: 58 | - h3=":443"; ma=86400 59 | body: 60 | encoding: ASCII-8BIT 61 | string: |- 62 | { 63 | "id": "vsfb_6fbe4acad12b408191386a762ebbd09a", 64 | "object": "vector_store.file_batch", 65 | "created_at": 1714510618, 66 | "status": "in_progress", 67 | "vector_store_id": "vs_qBhwT3kAs6fxYFe9VHcwDwAB", 68 | "file_counts": { 69 | "in_progress": 1, 70 | "completed": 0, 71 | "failed": 0, 72 | "cancelled": 0, 73 | "total": 1 74 | } 75 | } 76 | recorded_at: Tue, 30 Apr 2024 20:56:58 GMT 77 | recorded_with: VCR 6.1.0 78 | -------------------------------------------------------------------------------- /spec/fixtures/cassettes/vector_store_file_batches_retrieve_vector_store_setup.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_interactions: 3 | - request: 4 | method: post 5 | uri: https://api.openai.com/v1/vector_stores 6 | body: 7 | encoding: UTF-8 8 | string: "{}" 9 | headers: 10 | Content-Type: 11 | - application/json 12 | Authorization: 13 | - Bearer 14 | Openai-Beta: 15 | - assistants=v2 16 | Accept-Encoding: 17 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 18 | Accept: 19 | - "*/*" 20 | User-Agent: 21 | - Ruby 22 | response: 23 | status: 24 | code: 200 25 | message: OK 26 | headers: 27 | Date: 28 | - Tue, 30 Apr 2024 20:56:56 GMT 29 | Content-Type: 30 | - application/json 31 | Transfer-Encoding: 32 | - chunked 33 | Connection: 34 | - keep-alive 35 | Openai-Version: 36 | - '2020-10-01' 37 | Openai-Organization: 38 | - gojom-1 39 | X-Request-Id: 40 | - req_bb0fda6d35ee5acffa6974fd2ba24ac4 41 | Openai-Processing-Ms: 42 | - '401' 43 | Strict-Transport-Security: 44 | - max-age=15724800; includeSubDomains 45 | Cf-Cache-Status: 46 | - DYNAMIC 47 | Set-Cookie: 48 | - __cf_bm=c0yNMEJvZzE0SAag1MoAYy5MmvnAgzPVZ9cDz5s3cyo-1714510616-1.0.1.1-3lFjOf.O_.6TqDd4b61pfgCCAv3mAoVMRE1CE0mQqPY1ofmVEdJHGWddJPE6N3EJVnIL2tP2M0c.mFATqhZNNA; 49 | path=/; expires=Tue, 30-Apr-24 21:26:56 GMT; domain=.api.openai.com; HttpOnly; 50 | Secure; SameSite=None 51 | - _cfuvid=BAwd4kfdBe.Q4bKmmWRpxq6vDLjEvbmsjN9922Agr5w-1714510616085-0.0.1.1-604800000; 52 | path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None 53 | Server: 54 | - cloudflare 55 | Cf-Ray: 56 | - 87ca70f2b9b31b24-GRU 57 | Alt-Svc: 58 | - h3=":443"; ma=86400 59 | body: 60 | encoding: ASCII-8BIT 61 | string: |- 62 | { 63 | "id": "vs_qBhwT3kAs6fxYFe9VHcwDwAB", 64 | "object": "vector_store", 65 | "name": null, 66 | "status": "completed", 67 | "usage_bytes": 0, 68 | "created_at": 1714510615, 69 | "file_counts": { 70 | "in_progress": 0, 71 | "completed": 0, 72 | "failed": 0, 73 | "cancelled": 0, 74 | "total": 0 75 | }, 76 | "metadata": {}, 77 | "expires_after": null, 78 | "expires_at": null, 79 | "last_active_at": 1714510615 80 | } 81 | recorded_at: Tue, 30 Apr 2024 20:56:56 GMT 82 | recorded_with: VCR 6.1.0 83 | -------------------------------------------------------------------------------- /spec/fixtures/cassettes/vector_store_files_create.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_interactions: 3 | - request: 4 | method: post 5 | uri: https://api.openai.com/v1/vector_stores/vs_jXM8wckBS9gmjt8GlJAqFwwc/files 6 | body: 7 | encoding: UTF-8 8 | string: '{"file_id":"file-cGrNYOaHQOsKvfEDXa3bk6Rg"}' 9 | headers: 10 | Content-Type: 11 | - application/json 12 | Authorization: 13 | - Bearer 14 | Openai-Beta: 15 | - assistants=v2 16 | Accept-Encoding: 17 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 18 | Accept: 19 | - "*/*" 20 | User-Agent: 21 | - Ruby 22 | response: 23 | status: 24 | code: 200 25 | message: OK 26 | headers: 27 | Date: 28 | - Tue, 30 Apr 2024 18:55:09 GMT 29 | Content-Type: 30 | - application/json 31 | Transfer-Encoding: 32 | - chunked 33 | Connection: 34 | - keep-alive 35 | Openai-Version: 36 | - '2020-10-01' 37 | Openai-Organization: 38 | - gojom-1 39 | X-Request-Id: 40 | - req_9916342ad83e66e7095abac0fb79e992 41 | Openai-Processing-Ms: 42 | - '1354' 43 | Strict-Transport-Security: 44 | - max-age=15724800; includeSubDomains 45 | Cf-Cache-Status: 46 | - DYNAMIC 47 | Set-Cookie: 48 | - __cf_bm=nt4xkAXg03V_687Dx8uufZODpKBUIVLQlBTwsmot7TU-1714503308-1.0.1.1-Ydh0WR32g.kMaMYCV9CbQke5Qi.NrxFGikfKrIhU5ckayQmIYcKNTNy.09rY1m40612UpFwCWi7bJsiQgqG.bQ; 49 | path=/; expires=Tue, 30-Apr-24 19:25:08 GMT; domain=.api.openai.com; HttpOnly; 50 | Secure; SameSite=None 51 | - _cfuvid=JyIj02JBLJrLpmIxRTmUjK2dkV4v0Esxc9Ix05kSuWM-1714503309000-0.0.1.1-604800000; 52 | path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None 53 | Server: 54 | - cloudflare 55 | Cf-Ray: 56 | - 87c9be875d311ced-GRU 57 | Alt-Svc: 58 | - h3=":443"; ma=86400 59 | body: 60 | encoding: ASCII-8BIT 61 | string: |- 62 | { 63 | "id": "file-cGrNYOaHQOsKvfEDXa3bk6Rg", 64 | "object": "vector_store.file", 65 | "usage_bytes": 0, 66 | "created_at": 1714503307, 67 | "vector_store_id": "vs_jXM8wckBS9gmjt8GlJAqFwwc", 68 | "status": "in_progress", 69 | "last_error": null 70 | } 71 | recorded_at: Tue, 30 Apr 2024 18:55:08 GMT 72 | recorded_with: VCR 6.1.0 73 | -------------------------------------------------------------------------------- /spec/fixtures/cassettes/vector_store_files_create_file_setup.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_interactions: 3 | - request: 4 | method: post 5 | uri: https://api.openai.com/v1/files 6 | body: 7 | encoding: UTF-8 8 | string: "-------------RubyMultipartPost-a409dd4b7630a5aaad88755b986abd61\r\nContent-Disposition: 9 | form-data; name=\"file\"; filename=\"text.txt\"\r\nContent-Length: 12\r\nContent-Type: 10 | \r\nContent-Transfer-Encoding: binary\r\n\r\nHello world!\r\n-------------RubyMultipartPost-a409dd4b7630a5aaad88755b986abd61\r\nContent-Disposition: 11 | form-data; name=\"purpose\"\r\n\r\nassistants\r\n-------------RubyMultipartPost-a409dd4b7630a5aaad88755b986abd61--\r\n" 12 | headers: 13 | Content-Type: 14 | - multipart/form-data; boundary=-----------RubyMultipartPost-a409dd4b7630a5aaad88755b986abd61 15 | Authorization: 16 | - Bearer 17 | Content-Length: 18 | - '412' 19 | Accept-Encoding: 20 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 21 | Accept: 22 | - "*/*" 23 | User-Agent: 24 | - Ruby 25 | response: 26 | status: 27 | code: 200 28 | message: OK 29 | headers: 30 | Date: 31 | - Tue, 30 Apr 2024 18:55:07 GMT 32 | Content-Type: 33 | - application/json 34 | Transfer-Encoding: 35 | - chunked 36 | Connection: 37 | - keep-alive 38 | Openai-Version: 39 | - '2020-10-01' 40 | Openai-Organization: 41 | - gojom-1 42 | X-Request-Id: 43 | - req_d144c11e2c3cf82ed3f3589a5ae9f26e 44 | Openai-Processing-Ms: 45 | - '575' 46 | Access-Control-Allow-Origin: 47 | - "*" 48 | Strict-Transport-Security: 49 | - max-age=15724800; includeSubDomains 50 | Cf-Cache-Status: 51 | - DYNAMIC 52 | Set-Cookie: 53 | - __cf_bm=EsCBmgpMVg4ZTQNXmnY_9gYXP7wo92wL.i73zt.YO7E-1714503307-1.0.1.1-8qjA_aDu.geX6DOmPSAfpf3e_NLJQu4A7rbVBNSIKa7NGkw9U5VsM0PFxitQVsot2OjRQPSxtvA4MP3vAXJhdA; 54 | path=/; expires=Tue, 30-Apr-24 19:25:07 GMT; domain=.api.openai.com; HttpOnly; 55 | Secure; SameSite=None 56 | - _cfuvid=p3srxf06VBVWq2JHz_1Z_sSbesSu2QXsHXIEFk_3EzU-1714503307063-0.0.1.1-604800000; 57 | path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None 58 | Server: 59 | - cloudflare 60 | Cf-Ray: 61 | - 87c9be807c8f00fa-GRU 62 | Alt-Svc: 63 | - h3=":443"; ma=86400 64 | body: 65 | encoding: ASCII-8BIT 66 | string: | 67 | { 68 | "object": "file", 69 | "id": "file-cGrNYOaHQOsKvfEDXa3bk6Rg", 70 | "purpose": "assistants", 71 | "filename": "text.txt", 72 | "bytes": 12, 73 | "created_at": 1714503306, 74 | "status": "processed", 75 | "status_details": null 76 | } 77 | recorded_at: Tue, 30 Apr 2024 18:55:06 GMT 78 | recorded_with: VCR 6.1.0 79 | -------------------------------------------------------------------------------- /spec/fixtures/cassettes/vector_store_files_create_vector_store_setup.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_interactions: 3 | - request: 4 | method: post 5 | uri: https://api.openai.com/v1/vector_stores 6 | body: 7 | encoding: UTF-8 8 | string: "{}" 9 | headers: 10 | Content-Type: 11 | - application/json 12 | Authorization: 13 | - Bearer 14 | Openai-Beta: 15 | - assistants=v2 16 | Accept-Encoding: 17 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 18 | Accept: 19 | - "*/*" 20 | User-Agent: 21 | - Ruby 22 | response: 23 | status: 24 | code: 200 25 | message: OK 26 | headers: 27 | Date: 28 | - Tue, 30 Apr 2024 18:55:05 GMT 29 | Content-Type: 30 | - application/json 31 | Transfer-Encoding: 32 | - chunked 33 | Connection: 34 | - keep-alive 35 | Openai-Version: 36 | - '2020-10-01' 37 | Openai-Organization: 38 | - gojom-1 39 | X-Request-Id: 40 | - req_7b02fa44d3260f17768f2566482e01a0 41 | Openai-Processing-Ms: 42 | - '73' 43 | Strict-Transport-Security: 44 | - max-age=15724800; includeSubDomains 45 | Cf-Cache-Status: 46 | - DYNAMIC 47 | Set-Cookie: 48 | - __cf_bm=X8Q5Feq8ESL_45Shr90z8pkLBJMStTD6ZsKFiTbTLNc-1714503305-1.0.1.1-1nJwgmyLypZwPtmPpsUPiFCW9MB7PfoYNMCbLdIDw7O8Lk9fHokxZFr4AK4bCt3GolxvdBTos5QJkf.iiMVy2w; 49 | path=/; expires=Tue, 30-Apr-24 19:25:05 GMT; domain=.api.openai.com; HttpOnly; 50 | Secure; SameSite=None 51 | - _cfuvid=FPf3jCHLxTFUJhcN1cDwVo5nXnPuMcfNMp_bSZYichU-1714503305974-0.0.1.1-604800000; 52 | path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None 53 | Server: 54 | - cloudflare 55 | Cf-Ray: 56 | - 87c9be7c8dbf1d1f-GRU 57 | Alt-Svc: 58 | - h3=":443"; ma=86400 59 | body: 60 | encoding: ASCII-8BIT 61 | string: |- 62 | { 63 | "id": "vs_jXM8wckBS9gmjt8GlJAqFwwc", 64 | "object": "vector_store", 65 | "name": null, 66 | "status": "completed", 67 | "usage_bytes": 0, 68 | "created_at": 1714503305, 69 | "file_counts": { 70 | "in_progress": 0, 71 | "completed": 0, 72 | "failed": 0, 73 | "cancelled": 0, 74 | "total": 0 75 | }, 76 | "metadata": {}, 77 | "expires_after": null, 78 | "expires_at": null, 79 | "last_active_at": 1714503305 80 | } 81 | recorded_at: Tue, 30 Apr 2024 18:55:05 GMT 82 | recorded_with: VCR 6.1.0 83 | -------------------------------------------------------------------------------- /spec/fixtures/cassettes/vector_store_files_delete.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_interactions: 3 | - request: 4 | method: delete 5 | uri: https://api.openai.com/v1/vector_stores/vs_8dzN747pTzY2MtyDQoxfwmod/files/file-cQkOwz3aospk6aTNL78LAztA 6 | body: 7 | encoding: US-ASCII 8 | string: '' 9 | headers: 10 | Content-Type: 11 | - application/json 12 | Authorization: 13 | - Bearer 14 | Openai-Beta: 15 | - assistants=v2 16 | Accept-Encoding: 17 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 18 | Accept: 19 | - "*/*" 20 | User-Agent: 21 | - Ruby 22 | response: 23 | status: 24 | code: 200 25 | message: OK 26 | headers: 27 | Date: 28 | - Tue, 30 Apr 2024 18:55:14 GMT 29 | Content-Type: 30 | - application/json 31 | Transfer-Encoding: 32 | - chunked 33 | Connection: 34 | - keep-alive 35 | Openai-Version: 36 | - '2020-10-01' 37 | Openai-Organization: 38 | - gojom-1 39 | X-Request-Id: 40 | - req_84190e2775e6f94c846e728bbecd5ae3 41 | Openai-Processing-Ms: 42 | - '1158' 43 | Strict-Transport-Security: 44 | - max-age=15724800; includeSubDomains 45 | Cf-Cache-Status: 46 | - DYNAMIC 47 | Set-Cookie: 48 | - __cf_bm=ZUBTIh9sZKlJ_ano_7uUS.GrSgC1xDk0nCB1rE39z4c-1714503314-1.0.1.1-yfrsPhstLMgl_FZokZSMHcuRjreQRAPkcj2KB884h1KayOb553i0H07hbyrMgEr3w.TALhtoBkg2SobXpAbk2Q; 49 | path=/; expires=Tue, 30-Apr-24 19:25:14 GMT; domain=.api.openai.com; HttpOnly; 50 | Secure; SameSite=None 51 | - _cfuvid=EbXnnjmqClzdQq8HP0FQb8RWc1N3ad3JLzseQj0m0mk-1714503314239-0.0.1.1-604800000; 52 | path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None 53 | Server: 54 | - cloudflare 55 | Cf-Ray: 56 | - 87c9bea978ea1b31-GRU 57 | Alt-Svc: 58 | - h3=":443"; ma=86400 59 | body: 60 | encoding: ASCII-8BIT 61 | string: |- 62 | { 63 | "id": "file-cQkOwz3aospk6aTNL78LAztA", 64 | "object": "vector_store.file.deleted", 65 | "deleted": true 66 | } 67 | recorded_at: Tue, 30 Apr 2024 18:55:14 GMT 68 | recorded_with: VCR 6.1.0 69 | -------------------------------------------------------------------------------- /spec/fixtures/cassettes/vector_store_files_delete_file_setup.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_interactions: 3 | - request: 4 | method: post 5 | uri: https://api.openai.com/v1/files 6 | body: 7 | encoding: UTF-8 8 | string: "-------------RubyMultipartPost-bfb3a6fb344d762d6d228dbe0cc98f84\r\nContent-Disposition: 9 | form-data; name=\"file\"; filename=\"text.txt\"\r\nContent-Length: 12\r\nContent-Type: 10 | \r\nContent-Transfer-Encoding: binary\r\n\r\nHello world!\r\n-------------RubyMultipartPost-bfb3a6fb344d762d6d228dbe0cc98f84\r\nContent-Disposition: 11 | form-data; name=\"purpose\"\r\n\r\nassistants\r\n-------------RubyMultipartPost-bfb3a6fb344d762d6d228dbe0cc98f84--\r\n" 12 | headers: 13 | Content-Type: 14 | - multipart/form-data; boundary=-----------RubyMultipartPost-bfb3a6fb344d762d6d228dbe0cc98f84 15 | Authorization: 16 | - Bearer 17 | Content-Length: 18 | - '412' 19 | Accept-Encoding: 20 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 21 | Accept: 22 | - "*/*" 23 | User-Agent: 24 | - Ruby 25 | response: 26 | status: 27 | code: 200 28 | message: OK 29 | headers: 30 | Date: 31 | - Tue, 30 Apr 2024 18:55:10 GMT 32 | Content-Type: 33 | - application/json 34 | Transfer-Encoding: 35 | - chunked 36 | Connection: 37 | - keep-alive 38 | Openai-Version: 39 | - '2020-10-01' 40 | Openai-Organization: 41 | - gojom-1 42 | X-Request-Id: 43 | - req_b6075d19b512737e7285b43009a2c25d 44 | Openai-Processing-Ms: 45 | - '324' 46 | Access-Control-Allow-Origin: 47 | - "*" 48 | Strict-Transport-Security: 49 | - max-age=15724800; includeSubDomains 50 | Cf-Cache-Status: 51 | - DYNAMIC 52 | Set-Cookie: 53 | - __cf_bm=iDtKmhFsQOA8xGBJ3HHXlxesbIhF1lu94fwkxjZDIOU-1714503310-1.0.1.1-onLlgdcZc5lPIRGRzI4iSkWYH7EQvOShrS8rEi1HTk.28aCl.g6I07SPmZRVyKmn360DkTMZ6rVlvXPKmqKjPA; 54 | path=/; expires=Tue, 30-Apr-24 19:25:10 GMT; domain=.api.openai.com; HttpOnly; 55 | Secure; SameSite=None 56 | - _cfuvid=uacl6pMfI8TCtH2f2SOvgOXrpfyD.xKEwLfvQAY4Cv8-1714503310684-0.0.1.1-604800000; 57 | path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None 58 | Server: 59 | - cloudflare 60 | Cf-Ray: 61 | - 87c9be96eab74ffa-LIM 62 | Alt-Svc: 63 | - h3=":443"; ma=86400 64 | body: 65 | encoding: ASCII-8BIT 66 | string: | 67 | { 68 | "object": "file", 69 | "id": "file-cQkOwz3aospk6aTNL78LAztA", 70 | "purpose": "assistants", 71 | "filename": "text.txt", 72 | "bytes": 12, 73 | "created_at": 1714503310, 74 | "status": "processed", 75 | "status_details": null 76 | } 77 | recorded_at: Tue, 30 Apr 2024 18:55:10 GMT 78 | recorded_with: VCR 6.1.0 79 | -------------------------------------------------------------------------------- /spec/fixtures/cassettes/vector_store_files_delete_vector_store_file_setup.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_interactions: 3 | - request: 4 | method: post 5 | uri: https://api.openai.com/v1/vector_stores/vs_8dzN747pTzY2MtyDQoxfwmod/files 6 | body: 7 | encoding: UTF-8 8 | string: '{"file_id":"file-cQkOwz3aospk6aTNL78LAztA"}' 9 | headers: 10 | Content-Type: 11 | - application/json 12 | Authorization: 13 | - Bearer 14 | Openai-Beta: 15 | - assistants=v2 16 | Accept-Encoding: 17 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 18 | Accept: 19 | - "*/*" 20 | User-Agent: 21 | - Ruby 22 | response: 23 | status: 24 | code: 200 25 | message: OK 26 | headers: 27 | Date: 28 | - Tue, 30 Apr 2024 18:55:12 GMT 29 | Content-Type: 30 | - application/json 31 | Transfer-Encoding: 32 | - chunked 33 | Connection: 34 | - keep-alive 35 | Openai-Version: 36 | - '2020-10-01' 37 | Openai-Organization: 38 | - gojom-1 39 | X-Request-Id: 40 | - req_5fec774e0ecc487ae2753fb2c85c1873 41 | Openai-Processing-Ms: 42 | - '1364' 43 | Strict-Transport-Security: 44 | - max-age=15724800; includeSubDomains 45 | Cf-Cache-Status: 46 | - DYNAMIC 47 | Set-Cookie: 48 | - __cf_bm=VNgODvRyhg2XY8ZRlTcsXB3QvzoPNOBMlz6_jnDCpUE-1714503312-1.0.1.1-rmUKZPnXKvzKvVZ65GGBWRH5.uN3Uz3yF3KzKw4CKhIYfCPOwAjUS38tEKIFsTuCAs2yLmLtyi3X9uuDLq4Y2w; 49 | path=/; expires=Tue, 30-Apr-24 19:25:12 GMT; domain=.api.openai.com; HttpOnly; 50 | Secure; SameSite=None 51 | - _cfuvid=nNsrz3VGoKM5fH7j8qvBr4Ce.Y3wO6OFWSFZcl__Ieo-1714503312509-0.0.1.1-604800000; 52 | path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None 53 | Server: 54 | - cloudflare 55 | Cf-Ray: 56 | - 87c9be9d9da900ef-GRU 57 | Alt-Svc: 58 | - h3=":443"; ma=86400 59 | body: 60 | encoding: ASCII-8BIT 61 | string: |- 62 | { 63 | "id": "file-cQkOwz3aospk6aTNL78LAztA", 64 | "object": "vector_store.file", 65 | "usage_bytes": 0, 66 | "created_at": 1714503311, 67 | "vector_store_id": "vs_8dzN747pTzY2MtyDQoxfwmod", 68 | "status": "in_progress", 69 | "last_error": null 70 | } 71 | recorded_at: Tue, 30 Apr 2024 18:55:12 GMT 72 | recorded_with: VCR 6.1.0 73 | -------------------------------------------------------------------------------- /spec/fixtures/cassettes/vector_store_files_delete_vector_store_setup.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_interactions: 3 | - request: 4 | method: post 5 | uri: https://api.openai.com/v1/vector_stores 6 | body: 7 | encoding: UTF-8 8 | string: "{}" 9 | headers: 10 | Content-Type: 11 | - application/json 12 | Authorization: 13 | - Bearer 14 | Openai-Beta: 15 | - assistants=v2 16 | Accept-Encoding: 17 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 18 | Accept: 19 | - "*/*" 20 | User-Agent: 21 | - Ruby 22 | response: 23 | status: 24 | code: 200 25 | message: OK 26 | headers: 27 | Date: 28 | - Tue, 30 Apr 2024 18:55:09 GMT 29 | Content-Type: 30 | - application/json 31 | Transfer-Encoding: 32 | - chunked 33 | Connection: 34 | - keep-alive 35 | Openai-Version: 36 | - '2020-10-01' 37 | Openai-Organization: 38 | - gojom-1 39 | X-Request-Id: 40 | - req_d810b8828f70dcb14796f537612c47a3 41 | Openai-Processing-Ms: 42 | - '93' 43 | Strict-Transport-Security: 44 | - max-age=15724800; includeSubDomains 45 | Cf-Cache-Status: 46 | - DYNAMIC 47 | Set-Cookie: 48 | - __cf_bm=pNYoJdZGATE7DjRCNe1FCfsRNlgTjAyo77v6kz3ItMs-1714503309-1.0.1.1-5yuEmw44qHzA4NWZxgGcBZtZ5ZVPuQ7rTfYlFFj0p_4hbd3d6XX4_oyllIc8eNx2m9Nk.BvYCVQXcs02KoIsHw; 49 | path=/; expires=Tue, 30-Apr-24 19:25:09 GMT; domain=.api.openai.com; HttpOnly; 50 | Secure; SameSite=None 51 | - _cfuvid=oxG_D4HPFQTW3Qo1Ft0Qe4qgoJufiYkLzMf9xomATlU-1714503309746-0.0.1.1-604800000; 52 | path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None 53 | Server: 54 | - cloudflare 55 | Cf-Ray: 56 | - 87c9be93bebe1d0f-GRU 57 | Alt-Svc: 58 | - h3=":443"; ma=86400 59 | body: 60 | encoding: ASCII-8BIT 61 | string: |- 62 | { 63 | "id": "vs_8dzN747pTzY2MtyDQoxfwmod", 64 | "object": "vector_store", 65 | "name": null, 66 | "status": "completed", 67 | "usage_bytes": 0, 68 | "created_at": 1714503309, 69 | "file_counts": { 70 | "in_progress": 0, 71 | "completed": 0, 72 | "failed": 0, 73 | "cancelled": 0, 74 | "total": 0 75 | }, 76 | "metadata": {}, 77 | "expires_after": null, 78 | "expires_at": null, 79 | "last_active_at": 1714503309 80 | } 81 | recorded_at: Tue, 30 Apr 2024 18:55:09 GMT 82 | recorded_with: VCR 6.1.0 83 | -------------------------------------------------------------------------------- /spec/fixtures/cassettes/vector_store_files_list.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_interactions: 3 | - request: 4 | method: get 5 | uri: https://api.openai.com/v1/vector_stores/vs_8HxymfYr9b09lsN1tvtMItOe/files 6 | body: 7 | encoding: US-ASCII 8 | string: '' 9 | headers: 10 | Content-Type: 11 | - application/json 12 | Authorization: 13 | - Bearer 14 | Openai-Beta: 15 | - assistants=v2 16 | Accept-Encoding: 17 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 18 | Accept: 19 | - "*/*" 20 | User-Agent: 21 | - Ruby 22 | response: 23 | status: 24 | code: 200 25 | message: OK 26 | headers: 27 | Date: 28 | - Tue, 30 Apr 2024 18:55:00 GMT 29 | Content-Type: 30 | - application/json 31 | Transfer-Encoding: 32 | - chunked 33 | Connection: 34 | - keep-alive 35 | Openai-Version: 36 | - '2020-10-01' 37 | Openai-Organization: 38 | - gojom-1 39 | X-Request-Id: 40 | - req_d90ad49fef2a7a7f08320ec4047383b7 41 | Openai-Processing-Ms: 42 | - '109' 43 | Strict-Transport-Security: 44 | - max-age=15724800; includeSubDomains 45 | Cf-Cache-Status: 46 | - DYNAMIC 47 | Set-Cookie: 48 | - __cf_bm=3d1jYP7kxrAcfhs9shud8gp0l4KafGgIF0LYjgvigys-1714503300-1.0.1.1-UWBu3joNBe0mP6V3eRfC3FNcj7s5hCuN7dOa97IUbWXIqK_w2DzAd.fTzmw0x1kp_NGmNJWm.C1AicWacN.CzA; 49 | path=/; expires=Tue, 30-Apr-24 19:25:00 GMT; domain=.api.openai.com; HttpOnly; 50 | Secure; SameSite=None 51 | - _cfuvid=LiQYGjn_CHYEiAH.7M8bBuPVzH7z.I7HSHBKUI2CPz8-1714503300968-0.0.1.1-604800000; 52 | path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None 53 | Server: 54 | - cloudflare 55 | Cf-Ray: 56 | - 87c9be5d0de16b08-GRU 57 | Alt-Svc: 58 | - h3=":443"; ma=86400 59 | body: 60 | encoding: ASCII-8BIT 61 | string: |- 62 | { 63 | "object": "list", 64 | "data": [ 65 | { 66 | "id": "file-hN8c8cMN7IhVulUyYHN3AKQW", 67 | "object": "vector_store.file", 68 | "usage_bytes": 1036, 69 | "created_at": 1714503299, 70 | "vector_store_id": "vs_8HxymfYr9b09lsN1tvtMItOe", 71 | "status": "completed", 72 | "last_error": null 73 | } 74 | ], 75 | "first_id": "file-hN8c8cMN7IhVulUyYHN3AKQW", 76 | "last_id": "file-hN8c8cMN7IhVulUyYHN3AKQW", 77 | "has_more": false 78 | } 79 | recorded_at: Tue, 30 Apr 2024 18:55:00 GMT 80 | recorded_with: VCR 6.1.0 81 | -------------------------------------------------------------------------------- /spec/fixtures/cassettes/vector_store_files_list_file_setup.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_interactions: 3 | - request: 4 | method: post 5 | uri: https://api.openai.com/v1/files 6 | body: 7 | encoding: UTF-8 8 | string: "-------------RubyMultipartPost-bcb353196fd0e043f3ccd8d5d946b674\r\nContent-Disposition: 9 | form-data; name=\"file\"; filename=\"text.txt\"\r\nContent-Length: 12\r\nContent-Type: 10 | \r\nContent-Transfer-Encoding: binary\r\n\r\nHello world!\r\n-------------RubyMultipartPost-bcb353196fd0e043f3ccd8d5d946b674\r\nContent-Disposition: 11 | form-data; name=\"purpose\"\r\n\r\nassistants\r\n-------------RubyMultipartPost-bcb353196fd0e043f3ccd8d5d946b674--\r\n" 12 | headers: 13 | Content-Type: 14 | - multipart/form-data; boundary=-----------RubyMultipartPost-bcb353196fd0e043f3ccd8d5d946b674 15 | Authorization: 16 | - Bearer 17 | Content-Length: 18 | - '412' 19 | Accept-Encoding: 20 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 21 | Accept: 22 | - "*/*" 23 | User-Agent: 24 | - Ruby 25 | response: 26 | status: 27 | code: 200 28 | message: OK 29 | headers: 30 | Date: 31 | - Tue, 30 Apr 2024 18:54:58 GMT 32 | Content-Type: 33 | - application/json 34 | Transfer-Encoding: 35 | - chunked 36 | Connection: 37 | - keep-alive 38 | Openai-Version: 39 | - '2020-10-01' 40 | Openai-Organization: 41 | - gojom-1 42 | X-Request-Id: 43 | - req_3178a02f264a95ace2c96159d28763d9 44 | Openai-Processing-Ms: 45 | - '571' 46 | Access-Control-Allow-Origin: 47 | - "*" 48 | Strict-Transport-Security: 49 | - max-age=15724800; includeSubDomains 50 | Cf-Cache-Status: 51 | - DYNAMIC 52 | Set-Cookie: 53 | - __cf_bm=raku6LKcjR6QBu1Mc_hCJcVDRspnmyVwJGLap5grVg0-1714503298-1.0.1.1-9xaf4lCbzDUTbiYoVpDVmI7RJ5ScOi_8y3f.TaIa6Aa2IWwskmzRhGikuERTVn5q6QDXNK3DKt18BqqPQBVipQ; 54 | path=/; expires=Tue, 30-Apr-24 19:24:58 GMT; domain=.api.openai.com; HttpOnly; 55 | Secure; SameSite=None 56 | - _cfuvid=yCmSnA8lKuJerSsoDH1K5ShRdohSoPJKYUxWKbLvaww-1714503298385-0.0.1.1-604800000; 57 | path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None 58 | Server: 59 | - cloudflare 60 | Cf-Ray: 61 | - 87c9be4a18a01b11-GRU 62 | Alt-Svc: 63 | - h3=":443"; ma=86400 64 | body: 65 | encoding: ASCII-8BIT 66 | string: | 67 | { 68 | "object": "file", 69 | "id": "file-hN8c8cMN7IhVulUyYHN3AKQW", 70 | "purpose": "assistants", 71 | "filename": "text.txt", 72 | "bytes": 12, 73 | "created_at": 1714503297, 74 | "status": "processed", 75 | "status_details": null 76 | } 77 | recorded_at: Tue, 30 Apr 2024 18:54:58 GMT 78 | recorded_with: VCR 6.1.0 79 | -------------------------------------------------------------------------------- /spec/fixtures/cassettes/vector_store_files_list_vector_store_file_setup.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_interactions: 3 | - request: 4 | method: post 5 | uri: https://api.openai.com/v1/vector_stores/vs_8HxymfYr9b09lsN1tvtMItOe/files 6 | body: 7 | encoding: UTF-8 8 | string: '{"file_id":"file-hN8c8cMN7IhVulUyYHN3AKQW"}' 9 | headers: 10 | Content-Type: 11 | - application/json 12 | Authorization: 13 | - Bearer 14 | Openai-Beta: 15 | - assistants=v2 16 | Accept-Encoding: 17 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 18 | Accept: 19 | - "*/*" 20 | User-Agent: 21 | - Ruby 22 | response: 23 | status: 24 | code: 200 25 | message: OK 26 | headers: 27 | Date: 28 | - Tue, 30 Apr 2024 18:55:00 GMT 29 | Content-Type: 30 | - application/json 31 | Transfer-Encoding: 32 | - chunked 33 | Connection: 34 | - keep-alive 35 | Openai-Version: 36 | - '2020-10-01' 37 | Openai-Organization: 38 | - gojom-1 39 | X-Request-Id: 40 | - req_18bbe9cbb2d3b6c3a650f79e4ffa9cdc 41 | Openai-Processing-Ms: 42 | - '1379' 43 | Strict-Transport-Security: 44 | - max-age=15724800; includeSubDomains 45 | Cf-Cache-Status: 46 | - DYNAMIC 47 | Set-Cookie: 48 | - __cf_bm=O9dhNfXYyveGnWyu2eOSIruNYapl7AKzlHvNP9Ht0qk-1714503300-1.0.1.1-kvRQ6JM4cw7ucCL7VrumMmYpmtFlrEA_ewj1uo23Jb7WdJ34lP6s_RQ0z2unGlPensswZ7I56CNhEODEYAluRg; 49 | path=/; expires=Tue, 30-Apr-24 19:25:00 GMT; domain=.api.openai.com; HttpOnly; 50 | Secure; SameSite=None 51 | - _cfuvid=GLCrdeePDD7qJxuVLwwY_tP2VutmZQLF.LuiN2FjLVs-1714503300306-0.0.1.1-604800000; 52 | path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None 53 | Server: 54 | - cloudflare 55 | Cf-Ray: 56 | - 87c9be511bfc51cc-GRU 57 | Alt-Svc: 58 | - h3=":443"; ma=86400 59 | body: 60 | encoding: ASCII-8BIT 61 | string: |- 62 | { 63 | "id": "file-hN8c8cMN7IhVulUyYHN3AKQW", 64 | "object": "vector_store.file", 65 | "usage_bytes": 0, 66 | "created_at": 1714503299, 67 | "vector_store_id": "vs_8HxymfYr9b09lsN1tvtMItOe", 68 | "status": "in_progress", 69 | "last_error": null 70 | } 71 | recorded_at: Tue, 30 Apr 2024 18:55:00 GMT 72 | recorded_with: VCR 6.1.0 73 | -------------------------------------------------------------------------------- /spec/fixtures/cassettes/vector_store_files_list_vector_store_setup.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_interactions: 3 | - request: 4 | method: post 5 | uri: https://api.openai.com/v1/vector_stores 6 | body: 7 | encoding: UTF-8 8 | string: "{}" 9 | headers: 10 | Content-Type: 11 | - application/json 12 | Authorization: 13 | - Bearer 14 | Openai-Beta: 15 | - assistants=v2 16 | Accept-Encoding: 17 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 18 | Accept: 19 | - "*/*" 20 | User-Agent: 21 | - Ruby 22 | response: 23 | status: 24 | code: 200 25 | message: OK 26 | headers: 27 | Date: 28 | - Tue, 30 Apr 2024 18:54:57 GMT 29 | Content-Type: 30 | - application/json 31 | Transfer-Encoding: 32 | - chunked 33 | Connection: 34 | - keep-alive 35 | Openai-Version: 36 | - '2020-10-01' 37 | Openai-Organization: 38 | - gojom-1 39 | X-Request-Id: 40 | - req_86222f589d21c5d8d0a53d5ae721461d 41 | Openai-Processing-Ms: 42 | - '57' 43 | Strict-Transport-Security: 44 | - max-age=15724800; includeSubDomains 45 | Cf-Cache-Status: 46 | - DYNAMIC 47 | Set-Cookie: 48 | - __cf_bm=28ZbB17mhRFGVcARcAci53wE8EqK7So18q8ZoUG6JJk-1714503297-1.0.1.1-yo4o.UhPgbaz2Y5bdUE0F.o3PNYfjWohRnfx_C8k6kNKutR7LZZDC7XV4QYuCSjY.cI_6hsCnhfMjF1dNQ_D3w; 49 | path=/; expires=Tue, 30-Apr-24 19:24:57 GMT; domain=.api.openai.com; HttpOnly; 50 | Secure; SameSite=None 51 | - _cfuvid=M6mYWcKJmL5tpQpUqEyADABEptcNfqc5BxK1a8KYDKM-1714503297270-0.0.1.1-604800000; 52 | path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None 53 | Server: 54 | - cloudflare 55 | Cf-Ray: 56 | - 87c9be461d4c1b21-GRU 57 | Alt-Svc: 58 | - h3=":443"; ma=86400 59 | body: 60 | encoding: ASCII-8BIT 61 | string: |- 62 | { 63 | "id": "vs_8HxymfYr9b09lsN1tvtMItOe", 64 | "object": "vector_store", 65 | "name": null, 66 | "status": "completed", 67 | "usage_bytes": 0, 68 | "created_at": 1714503297, 69 | "file_counts": { 70 | "in_progress": 0, 71 | "completed": 0, 72 | "failed": 0, 73 | "cancelled": 0, 74 | "total": 0 75 | }, 76 | "metadata": {}, 77 | "expires_after": null, 78 | "expires_at": null, 79 | "last_active_at": 1714503297 80 | } 81 | recorded_at: Tue, 30 Apr 2024 18:54:57 GMT 82 | recorded_with: VCR 6.1.0 83 | -------------------------------------------------------------------------------- /spec/fixtures/cassettes/vector_store_files_retrieve.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_interactions: 3 | - request: 4 | method: get 5 | uri: https://api.openai.com/v1/vector_stores/vs_byyoIIfTk2DjCONUuvGFZwrd/files/file-wVFDYrCLN5iNPWQid43qSLaj 6 | body: 7 | encoding: US-ASCII 8 | string: '' 9 | headers: 10 | Content-Type: 11 | - application/json 12 | Authorization: 13 | - Bearer 14 | Openai-Beta: 15 | - assistants=v2 16 | Accept-Encoding: 17 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 18 | Accept: 19 | - "*/*" 20 | User-Agent: 21 | - Ruby 22 | response: 23 | status: 24 | code: 200 25 | message: OK 26 | headers: 27 | Date: 28 | - Tue, 30 Apr 2024 18:55:05 GMT 29 | Content-Type: 30 | - application/json 31 | Transfer-Encoding: 32 | - chunked 33 | Connection: 34 | - keep-alive 35 | Openai-Version: 36 | - '2020-10-01' 37 | Openai-Organization: 38 | - gojom-1 39 | X-Request-Id: 40 | - req_b2e1ca7e3050e8e167942d210786d09b 41 | Openai-Processing-Ms: 42 | - '114' 43 | Strict-Transport-Security: 44 | - max-age=15724800; includeSubDomains 45 | Cf-Cache-Status: 46 | - DYNAMIC 47 | Set-Cookie: 48 | - __cf_bm=v1cXwQH_H3ti0ihlMyGXU763pVFLLBIXjXZocZF2Lq0-1714503305-1.0.1.1-CBXBPaeHdW3U3WxZY3WQQWHC2bZXSPel28owDZa5nmgGRdZPiy40jAS6aRZN1MFa6OHsNvhldCQkWm_0HDRJAQ; 49 | path=/; expires=Tue, 30-Apr-24 19:25:05 GMT; domain=.api.openai.com; HttpOnly; 50 | Secure; SameSite=None 51 | - _cfuvid=eaxIupAaujae5M022roi_f7tpBETscIChreIkDymmqU-1714503305351-0.0.1.1-604800000; 52 | path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None 53 | Server: 54 | - cloudflare 55 | Cf-Ray: 56 | - 87c9be787e151b0e-GRU 57 | Alt-Svc: 58 | - h3=":443"; ma=86400 59 | body: 60 | encoding: ASCII-8BIT 61 | string: |- 62 | { 63 | "id": "file-wVFDYrCLN5iNPWQid43qSLaj", 64 | "object": "vector_store.file", 65 | "usage_bytes": 1036, 66 | "created_at": 1714503303, 67 | "vector_store_id": "vs_byyoIIfTk2DjCONUuvGFZwrd", 68 | "status": "completed", 69 | "last_error": null 70 | } 71 | recorded_at: Tue, 30 Apr 2024 18:55:05 GMT 72 | recorded_with: VCR 6.1.0 73 | -------------------------------------------------------------------------------- /spec/fixtures/cassettes/vector_store_files_retrieve_file_setup.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_interactions: 3 | - request: 4 | method: post 5 | uri: https://api.openai.com/v1/files 6 | body: 7 | encoding: UTF-8 8 | string: "-------------RubyMultipartPost-6f1d768efdca25b8b047d2d62f5d7f76\r\nContent-Disposition: 9 | form-data; name=\"file\"; filename=\"text.txt\"\r\nContent-Length: 12\r\nContent-Type: 10 | \r\nContent-Transfer-Encoding: binary\r\n\r\nHello world!\r\n-------------RubyMultipartPost-6f1d768efdca25b8b047d2d62f5d7f76\r\nContent-Disposition: 11 | form-data; name=\"purpose\"\r\n\r\nassistants\r\n-------------RubyMultipartPost-6f1d768efdca25b8b047d2d62f5d7f76--\r\n" 12 | headers: 13 | Content-Type: 14 | - multipart/form-data; boundary=-----------RubyMultipartPost-6f1d768efdca25b8b047d2d62f5d7f76 15 | Authorization: 16 | - Bearer 17 | Content-Length: 18 | - '412' 19 | Accept-Encoding: 20 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 21 | Accept: 22 | - "*/*" 23 | User-Agent: 24 | - Ruby 25 | response: 26 | status: 27 | code: 200 28 | message: OK 29 | headers: 30 | Date: 31 | - Tue, 30 Apr 2024 18:55:02 GMT 32 | Content-Type: 33 | - application/json 34 | Transfer-Encoding: 35 | - chunked 36 | Connection: 37 | - keep-alive 38 | Openai-Version: 39 | - '2020-10-01' 40 | Openai-Organization: 41 | - gojom-1 42 | X-Request-Id: 43 | - req_41982bcd672e5f597283a7bfc21f085f 44 | Openai-Processing-Ms: 45 | - '317' 46 | Access-Control-Allow-Origin: 47 | - "*" 48 | Strict-Transport-Security: 49 | - max-age=15724800; includeSubDomains 50 | Cf-Cache-Status: 51 | - DYNAMIC 52 | Set-Cookie: 53 | - __cf_bm=okOoN6KNerOwtUU375J1aFCk8Mxe2jK8h_vwyoWy9po-1714503302-1.0.1.1-N.cxBgr7tz9nS4.VFWkWa0QX8VwpECu1Sl2.iHJmUDz0F1sDjcuc45Hdtl.WQ.9g7ktu5YB3AjafM8L9ioMybQ; 54 | path=/; expires=Tue, 30-Apr-24 19:25:02 GMT; domain=.api.openai.com; HttpOnly; 55 | Secure; SameSite=None 56 | - _cfuvid=6XWZu8z6Hj527iS9VrGNqTVYNBSZGWfZnzfZq.P8b8A-1714503302883-0.0.1.1-604800000; 57 | path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None 58 | Server: 59 | - cloudflare 60 | Cf-Ray: 61 | - 87c9be67b9c71b16-GRU 62 | Alt-Svc: 63 | - h3=":443"; ma=86400 64 | body: 65 | encoding: ASCII-8BIT 66 | string: | 67 | { 68 | "object": "file", 69 | "id": "file-wVFDYrCLN5iNPWQid43qSLaj", 70 | "purpose": "assistants", 71 | "filename": "text.txt", 72 | "bytes": 12, 73 | "created_at": 1714503302, 74 | "status": "processed", 75 | "status_details": null 76 | } 77 | recorded_at: Tue, 30 Apr 2024 18:55:02 GMT 78 | recorded_with: VCR 6.1.0 79 | -------------------------------------------------------------------------------- /spec/fixtures/cassettes/vector_store_files_retrieve_vector_store_file_setup.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_interactions: 3 | - request: 4 | method: post 5 | uri: https://api.openai.com/v1/vector_stores/vs_byyoIIfTk2DjCONUuvGFZwrd/files 6 | body: 7 | encoding: UTF-8 8 | string: '{"file_id":"file-wVFDYrCLN5iNPWQid43qSLaj"}' 9 | headers: 10 | Content-Type: 11 | - application/json 12 | Authorization: 13 | - Bearer 14 | Openai-Beta: 15 | - assistants=v2 16 | Accept-Encoding: 17 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 18 | Accept: 19 | - "*/*" 20 | User-Agent: 21 | - Ruby 22 | response: 23 | status: 24 | code: 200 25 | message: OK 26 | headers: 27 | Date: 28 | - Tue, 30 Apr 2024 18:55:04 GMT 29 | Content-Type: 30 | - application/json 31 | Transfer-Encoding: 32 | - chunked 33 | Connection: 34 | - keep-alive 35 | Openai-Version: 36 | - '2020-10-01' 37 | Openai-Organization: 38 | - gojom-1 39 | X-Request-Id: 40 | - req_e41b6dfef1c318caf00ed5bb6353f259 41 | Openai-Processing-Ms: 42 | - '1263' 43 | Strict-Transport-Security: 44 | - max-age=15724800; includeSubDomains 45 | Cf-Cache-Status: 46 | - DYNAMIC 47 | Set-Cookie: 48 | - __cf_bm=kZkjxfbNzscnmk.oVLecnqEqneDBlAxwi5mkoZJ0rGw-1714503304-1.0.1.1-v9uGdcXTsgYuYzuDsbkvCJst4ekWLQOeXPP23tWi61XmeAmVv5iWvDMfmRbU5bYtF8bjw9Xg53z7b_gOoHTrdg; 49 | path=/; expires=Tue, 30-Apr-24 19:25:04 GMT; domain=.api.openai.com; HttpOnly; 50 | Secure; SameSite=None 51 | - _cfuvid=R3bxSBsk591oWxe2KjrZ4axv_yYkE.HE7JNJXdSaP.g-1714503304721-0.0.1.1-604800000; 52 | path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None 53 | Server: 54 | - cloudflare 55 | Cf-Ray: 56 | - 87c9be6d2aad1d0d-GRU 57 | Alt-Svc: 58 | - h3=":443"; ma=86400 59 | body: 60 | encoding: ASCII-8BIT 61 | string: |- 62 | { 63 | "id": "file-wVFDYrCLN5iNPWQid43qSLaj", 64 | "object": "vector_store.file", 65 | "usage_bytes": 0, 66 | "created_at": 1714503303, 67 | "vector_store_id": "vs_byyoIIfTk2DjCONUuvGFZwrd", 68 | "status": "in_progress", 69 | "last_error": null 70 | } 71 | recorded_at: Tue, 30 Apr 2024 18:55:04 GMT 72 | recorded_with: VCR 6.1.0 73 | -------------------------------------------------------------------------------- /spec/fixtures/cassettes/vector_store_files_retrieve_vector_store_setup.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_interactions: 3 | - request: 4 | method: post 5 | uri: https://api.openai.com/v1/vector_stores 6 | body: 7 | encoding: UTF-8 8 | string: "{}" 9 | headers: 10 | Content-Type: 11 | - application/json 12 | Authorization: 13 | - Bearer 14 | Openai-Beta: 15 | - assistants=v2 16 | Accept-Encoding: 17 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 18 | Accept: 19 | - "*/*" 20 | User-Agent: 21 | - Ruby 22 | response: 23 | status: 24 | code: 200 25 | message: OK 26 | headers: 27 | Date: 28 | - Tue, 30 Apr 2024 18:55:02 GMT 29 | Content-Type: 30 | - application/json 31 | Transfer-Encoding: 32 | - chunked 33 | Connection: 34 | - keep-alive 35 | Openai-Version: 36 | - '2020-10-01' 37 | Openai-Organization: 38 | - gojom-1 39 | X-Request-Id: 40 | - req_df82dfa113105aa25f93e0dae559da67 41 | Openai-Processing-Ms: 42 | - '523' 43 | Strict-Transport-Security: 44 | - max-age=15724800; includeSubDomains 45 | Cf-Cache-Status: 46 | - DYNAMIC 47 | Set-Cookie: 48 | - __cf_bm=fJJg6gGmz.MH0m56EozCwO74ZST89mGDyIRk0qNwm24-1714503302-1.0.1.1-OVFR3sVV6zXS2ZLEfTg9dyYVdd8Jib0T3Qo7vhzrAe9UJ_fiH_zMRyFplKjlDuy2nNv492LcF8YEwNNwyezjNA; 49 | path=/; expires=Tue, 30-Apr-24 19:25:02 GMT; domain=.api.openai.com; HttpOnly; 50 | Secure; SameSite=None 51 | - _cfuvid=lE2pNvyWmG60mNZNtwsyVgdeNo42QID2xE7gWDx134E-1714503302023-0.0.1.1-604800000; 52 | path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None 53 | Server: 54 | - cloudflare 55 | Cf-Ray: 56 | - 87c9be6119291cf1-GRU 57 | Alt-Svc: 58 | - h3=":443"; ma=86400 59 | body: 60 | encoding: ASCII-8BIT 61 | string: |- 62 | { 63 | "id": "vs_byyoIIfTk2DjCONUuvGFZwrd", 64 | "object": "vector_store", 65 | "name": null, 66 | "status": "completed", 67 | "usage_bytes": 0, 68 | "created_at": 1714503301, 69 | "file_counts": { 70 | "in_progress": 0, 71 | "completed": 0, 72 | "failed": 0, 73 | "cancelled": 0, 74 | "total": 0 75 | }, 76 | "metadata": {}, 77 | "expires_after": null, 78 | "expires_at": null, 79 | "last_active_at": 1714503301 80 | } 81 | recorded_at: Tue, 30 Apr 2024 18:55:01 GMT 82 | recorded_with: VCR 6.1.0 83 | -------------------------------------------------------------------------------- /spec/fixtures/cassettes/vector_stores_create.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_interactions: 3 | - request: 4 | method: post 5 | uri: https://api.openai.com/v1/vector_stores 6 | body: 7 | encoding: UTF-8 8 | string: "{}" 9 | headers: 10 | Content-Type: 11 | - application/json 12 | Authorization: 13 | - Bearer 14 | Openai-Beta: 15 | - assistants=v2 16 | Accept-Encoding: 17 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 18 | Accept: 19 | - "*/*" 20 | User-Agent: 21 | - Ruby 22 | response: 23 | status: 24 | code: 200 25 | message: OK 26 | headers: 27 | Date: 28 | - Tue, 30 Apr 2024 16:41:34 GMT 29 | Content-Type: 30 | - application/json 31 | Transfer-Encoding: 32 | - chunked 33 | Connection: 34 | - keep-alive 35 | Openai-Version: 36 | - '2020-10-01' 37 | Openai-Organization: 38 | - gojom-1 39 | X-Request-Id: 40 | - req_10a3172ba3a5cf01c4e14c690795a646 41 | Openai-Processing-Ms: 42 | - '298' 43 | Strict-Transport-Security: 44 | - max-age=15724800; includeSubDomains 45 | Cf-Cache-Status: 46 | - DYNAMIC 47 | Set-Cookie: 48 | - __cf_bm=fx_YqjkKO9nH08e8caafVXLyhi8Wb5i2lQ1W3mld.YM-1714495294-1.0.1.1-WqFQ33scAb7HkBjiRb63lwUTxFCg8l2yLS6HLgjFuD2S037nbt4fKh5.SBDB_F69klK_MmdGJSTWaUJK26nObw; 49 | path=/; expires=Tue, 30-Apr-24 17:11:34 GMT; domain=.api.openai.com; HttpOnly; 50 | Secure; SameSite=None 51 | - _cfuvid=HkOfANtrx.fzf8512ER8ESBZJorcTSQiUs1V.PgPP1g-1714495294435-0.0.1.1-604800000; 52 | path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None 53 | Server: 54 | - cloudflare 55 | Cf-Ray: 56 | - 87c8fae359a51a91-GRU 57 | Alt-Svc: 58 | - h3=":443"; ma=86400 59 | body: 60 | encoding: ASCII-8BIT 61 | string: |- 62 | { 63 | "id": "vs_kWaCiN8Ii4e1hefIou5skq9g", 64 | "object": "vector_store", 65 | "name": null, 66 | "status": "completed", 67 | "usage_bytes": 0, 68 | "created_at": 1714495294, 69 | "file_counts": { 70 | "in_progress": 0, 71 | "completed": 0, 72 | "failed": 0, 73 | "cancelled": 0, 74 | "total": 0 75 | }, 76 | "metadata": {}, 77 | "expires_after": null, 78 | "expires_at": null, 79 | "last_active_at": 1714495294 80 | } 81 | recorded_at: Tue, 30 Apr 2024 16:41:34 GMT 82 | recorded_with: VCR 6.1.0 83 | -------------------------------------------------------------------------------- /spec/fixtures/cassettes/vector_stores_delete.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_interactions: 3 | - request: 4 | method: delete 5 | uri: https://api.openai.com/v1/vector_stores/vs_DBrde7MywMBEdxmzXaeO76Ky 6 | body: 7 | encoding: US-ASCII 8 | string: '' 9 | headers: 10 | Content-Type: 11 | - application/json 12 | Authorization: 13 | - Bearer 14 | Openai-Beta: 15 | - assistants=v2 16 | Accept-Encoding: 17 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 18 | Accept: 19 | - "*/*" 20 | User-Agent: 21 | - Ruby 22 | response: 23 | status: 24 | code: 200 25 | message: OK 26 | headers: 27 | Date: 28 | - Tue, 30 Apr 2024 16:41:38 GMT 29 | Content-Type: 30 | - application/json 31 | Transfer-Encoding: 32 | - chunked 33 | Connection: 34 | - keep-alive 35 | Openai-Version: 36 | - '2020-10-01' 37 | Openai-Organization: 38 | - gojom-1 39 | X-Request-Id: 40 | - req_07c5e08ede15f5ffd23ebd910964a12a 41 | Openai-Processing-Ms: 42 | - '650' 43 | Strict-Transport-Security: 44 | - max-age=15724800; includeSubDomains 45 | Cf-Cache-Status: 46 | - DYNAMIC 47 | Set-Cookie: 48 | - __cf_bm=QVfxVV7u50gVD09z0l_zJPEdDRfWRq495V.vRZ0B_XY-1714495298-1.0.1.1-kESiJ5WFO.TexW1HJwHtzlmu8_Z8PEQMPl5QuVEMP6X3g5yZO6whcPqES587b1QjLSdI10c8w7h_tRciBiRgHQ; 49 | path=/; expires=Tue, 30-Apr-24 17:11:38 GMT; domain=.api.openai.com; HttpOnly; 50 | Secure; SameSite=None 51 | - _cfuvid=mVGvyRYNeI_sytGC2xXm7o0oEB2bX6ySfTWjOS_O7A0-1714495298252-0.0.1.1-604800000; 52 | path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None 53 | Server: 54 | - cloudflare 55 | Cf-Ray: 56 | - 87c8faf8ba5aa194-GRU 57 | Alt-Svc: 58 | - h3=":443"; ma=86400 59 | body: 60 | encoding: ASCII-8BIT 61 | string: |- 62 | { 63 | "id": "vs_DBrde7MywMBEdxmzXaeO76Ky", 64 | "object": "vector_store.deleted", 65 | "deleted": true 66 | } 67 | recorded_at: Tue, 30 Apr 2024 16:41:38 GMT 68 | recorded_with: VCR 6.1.0 69 | -------------------------------------------------------------------------------- /spec/fixtures/cassettes/vector_stores_delete_setup.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_interactions: 3 | - request: 4 | method: post 5 | uri: https://api.openai.com/v1/vector_stores 6 | body: 7 | encoding: UTF-8 8 | string: "{}" 9 | headers: 10 | Content-Type: 11 | - application/json 12 | Authorization: 13 | - Bearer 14 | Openai-Beta: 15 | - assistants=v2 16 | Accept-Encoding: 17 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 18 | Accept: 19 | - "*/*" 20 | User-Agent: 21 | - Ruby 22 | response: 23 | status: 24 | code: 200 25 | message: OK 26 | headers: 27 | Date: 28 | - Tue, 30 Apr 2024 16:41:37 GMT 29 | Content-Type: 30 | - application/json 31 | Transfer-Encoding: 32 | - chunked 33 | Connection: 34 | - keep-alive 35 | Openai-Version: 36 | - '2020-10-01' 37 | Openai-Organization: 38 | - gojom-1 39 | X-Request-Id: 40 | - req_8ee82dc580571d1626616aa520d89ac8 41 | Openai-Processing-Ms: 42 | - '341' 43 | Strict-Transport-Security: 44 | - max-age=15724800; includeSubDomains 45 | Cf-Cache-Status: 46 | - DYNAMIC 47 | Set-Cookie: 48 | - __cf_bm=Wvl9rfoENnnUnPHMkY0ef4MRjmKBbTYLqusFZQDEWR8-1714495297-1.0.1.1-jjELIwQsfqnveMSFoBKsABeBy3JNcmTEPSO4ot69t9JZO1THt8D6GUPuGy02d_hIZ4TJpsihxeeeUvHb.WBvjQ; 49 | path=/; expires=Tue, 30-Apr-24 17:11:37 GMT; domain=.api.openai.com; HttpOnly; 50 | Secure; SameSite=None 51 | - _cfuvid=8Rls3QoJsBohV37Y4Cc1pU0creW0ep26r6eAFiCFYxQ-1714495297057-0.0.1.1-604800000; 52 | path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None 53 | Server: 54 | - cloudflare 55 | Cf-Ray: 56 | - 87c8faf3681c877b-GRU 57 | Alt-Svc: 58 | - h3=":443"; ma=86400 59 | body: 60 | encoding: ASCII-8BIT 61 | string: |- 62 | { 63 | "id": "vs_DBrde7MywMBEdxmzXaeO76Ky", 64 | "object": "vector_store", 65 | "name": null, 66 | "status": "completed", 67 | "usage_bytes": 0, 68 | "created_at": 1714495296, 69 | "file_counts": { 70 | "in_progress": 0, 71 | "completed": 0, 72 | "failed": 0, 73 | "cancelled": 0, 74 | "total": 0 75 | }, 76 | "metadata": {}, 77 | "expires_after": null, 78 | "expires_at": null, 79 | "last_active_at": 1714495296 80 | } 81 | recorded_at: Tue, 30 Apr 2024 16:41:36 GMT 82 | recorded_with: VCR 6.1.0 83 | -------------------------------------------------------------------------------- /spec/fixtures/cassettes/vector_stores_list_setup.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_interactions: 3 | - request: 4 | method: post 5 | uri: https://api.openai.com/v1/vector_stores 6 | body: 7 | encoding: UTF-8 8 | string: "{}" 9 | headers: 10 | Content-Type: 11 | - application/json 12 | Authorization: 13 | - Bearer 14 | Openai-Beta: 15 | - assistants=v2 16 | Accept-Encoding: 17 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 18 | Accept: 19 | - "*/*" 20 | User-Agent: 21 | - Ruby 22 | response: 23 | status: 24 | code: 200 25 | message: OK 26 | headers: 27 | Date: 28 | - Mon, 10 Jun 2024 12:10:27 GMT 29 | Content-Type: 30 | - application/json 31 | Transfer-Encoding: 32 | - chunked 33 | Connection: 34 | - keep-alive 35 | Openai-Version: 36 | - '2020-10-01' 37 | Openai-Organization: 38 | - user-jxm65ijkzc1qrfhc0ij8moic 39 | X-Request-Id: 40 | - req_11abe9630b3810f2b4a3830baf3602c1 41 | Openai-Processing-Ms: 42 | - '50' 43 | Strict-Transport-Security: 44 | - max-age=15724800; includeSubDomains 45 | Cf-Cache-Status: 46 | - DYNAMIC 47 | Set-Cookie: 48 | - __cf_bm=.TcXhXR2qRzygfwaMGIthLW3zJ0Ml61BGRaerXUDCT8-1718021427-1.0.1.1-TBUC6Dnk3iGIwgISgt_b5oBCchxmQvVwUB3Ul2K7MzKIyIHtZicd9goCaxvy0i4n5Q90D61OK7nRYw0HgqgIqA; 49 | path=/; expires=Mon, 10-Jun-24 12:40:27 GMT; domain=.api.openai.com; HttpOnly; 50 | Secure; SameSite=None 51 | - _cfuvid=kxtHyeeOy4pOM361vuyRE3fLktW.Sa6J5vch3d_Afv4-1718021427933-0.0.1.1-604800000; 52 | path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None 53 | Server: 54 | - cloudflare 55 | Cf-Ray: 56 | - 891942236f1794d3-LHR 57 | Alt-Svc: 58 | - h3=":443"; ma=86400 59 | body: 60 | encoding: ASCII-8BIT 61 | string: |- 62 | { 63 | "id": "vs_q7pDyRpqkJovo5OWAyzEhOZ9", 64 | "object": "vector_store", 65 | "name": null, 66 | "status": "completed", 67 | "usage_bytes": 0, 68 | "created_at": 1718021427, 69 | "file_counts": { 70 | "in_progress": 0, 71 | "completed": 0, 72 | "failed": 0, 73 | "cancelled": 0, 74 | "total": 0 75 | }, 76 | "metadata": {}, 77 | "expires_after": null, 78 | "expires_at": null, 79 | "last_active_at": 1718021427 80 | } 81 | recorded_at: Mon, 10 Jun 2024 12:10:27 GMT 82 | recorded_with: VCR 6.1.0 83 | -------------------------------------------------------------------------------- /spec/fixtures/cassettes/vector_stores_modify.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_interactions: 3 | - request: 4 | method: post 5 | uri: https://api.openai.com/v1/vector_stores/vs_jQLnn4Fn6Kzt8GGw73LSKky2 6 | body: 7 | encoding: UTF-8 8 | string: '{"metadata":{"modified":"true"}}' 9 | headers: 10 | Content-Type: 11 | - application/json 12 | Authorization: 13 | - Bearer 14 | Openai-Beta: 15 | - assistants=v2 16 | Accept-Encoding: 17 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 18 | Accept: 19 | - "*/*" 20 | User-Agent: 21 | - Ruby 22 | response: 23 | status: 24 | code: 200 25 | message: OK 26 | headers: 27 | Date: 28 | - Tue, 30 Apr 2024 16:41:36 GMT 29 | Content-Type: 30 | - application/json 31 | Transfer-Encoding: 32 | - chunked 33 | Connection: 34 | - keep-alive 35 | Openai-Version: 36 | - '2020-10-01' 37 | Openai-Organization: 38 | - gojom-1 39 | X-Request-Id: 40 | - req_29deb61536aed4250cea0f44e59d100d 41 | Openai-Processing-Ms: 42 | - '206' 43 | Strict-Transport-Security: 44 | - max-age=15724800; includeSubDomains 45 | Cf-Cache-Status: 46 | - DYNAMIC 47 | Set-Cookie: 48 | - __cf_bm=ZK1MIQhYHDBnw6PDeC8qFv65zCuLhIz8mQl8usHzeTM-1714495296-1.0.1.1-EFgaOeqqKfrCTS5wre9qtZz._mAOLCLU7j3x4XYA6iQrgXrNNaQABqz4qI061cLdB62yUdZo7Hgk25CB7CXcFA; 49 | path=/; expires=Tue, 30-Apr-24 17:11:36 GMT; domain=.api.openai.com; HttpOnly; 50 | Secure; SameSite=None 51 | - _cfuvid=KB55TbP0pMq33UC4XXJkvip1UKyY83BlkwU7.2haOnY-1714495296110-0.0.1.1-604800000; 52 | path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None 53 | Server: 54 | - cloudflare 55 | Cf-Ray: 56 | - 87c8faee2a841b26-GRU 57 | Alt-Svc: 58 | - h3=":443"; ma=86400 59 | body: 60 | encoding: ASCII-8BIT 61 | string: |- 62 | { 63 | "id": "vs_jQLnn4Fn6Kzt8GGw73LSKky2", 64 | "object": "vector_store", 65 | "name": null, 66 | "status": "completed", 67 | "usage_bytes": 0, 68 | "created_at": 1714495295, 69 | "file_counts": { 70 | "in_progress": 0, 71 | "completed": 0, 72 | "failed": 0, 73 | "cancelled": 0, 74 | "total": 0 75 | }, 76 | "metadata": { 77 | "modified": "true" 78 | }, 79 | "expires_after": null, 80 | "expires_at": null, 81 | "last_active_at": 1714495295 82 | } 83 | recorded_at: Tue, 30 Apr 2024 16:41:36 GMT 84 | recorded_with: VCR 6.1.0 85 | -------------------------------------------------------------------------------- /spec/fixtures/cassettes/vector_stores_modify_setup.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_interactions: 3 | - request: 4 | method: post 5 | uri: https://api.openai.com/v1/vector_stores 6 | body: 7 | encoding: UTF-8 8 | string: "{}" 9 | headers: 10 | Content-Type: 11 | - application/json 12 | Authorization: 13 | - Bearer 14 | Openai-Beta: 15 | - assistants=v2 16 | Accept-Encoding: 17 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 18 | Accept: 19 | - "*/*" 20 | User-Agent: 21 | - Ruby 22 | response: 23 | status: 24 | code: 200 25 | message: OK 26 | headers: 27 | Date: 28 | - Tue, 30 Apr 2024 16:41:35 GMT 29 | Content-Type: 30 | - application/json 31 | Transfer-Encoding: 32 | - chunked 33 | Connection: 34 | - keep-alive 35 | Openai-Version: 36 | - '2020-10-01' 37 | Openai-Organization: 38 | - gojom-1 39 | X-Request-Id: 40 | - req_731195d616bb66be48ad0abc3865a8b8 41 | Openai-Processing-Ms: 42 | - '333' 43 | Strict-Transport-Security: 44 | - max-age=15724800; includeSubDomains 45 | Cf-Cache-Status: 46 | - DYNAMIC 47 | Set-Cookie: 48 | - __cf_bm=Awv48eD2.8N1qKbwD1OfJ7y3Lpq5yH4sKwYuE8s.8yk-1714495295-1.0.1.1-IPPIQoTXxyjUqezQJl1yEVnf8SIXPqX5E.47n5ETOyVXuBkgFDyVeMIdeiZJgC4Kf7mScSNRr6bW2qjTdpj6iQ; 49 | path=/; expires=Tue, 30-Apr-24 17:11:35 GMT; domain=.api.openai.com; HttpOnly; 50 | Secure; SameSite=None 51 | - _cfuvid=.QePlceeit2HmCD6dNNauT3lRdt_sTjPR1qG8xuTO38-1714495295311-0.0.1.1-604800000; 52 | path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None 53 | Server: 54 | - cloudflare 55 | Cf-Ray: 56 | - 87c8fae87c761aa4-GRU 57 | Alt-Svc: 58 | - h3=":443"; ma=86400 59 | body: 60 | encoding: ASCII-8BIT 61 | string: |- 62 | { 63 | "id": "vs_jQLnn4Fn6Kzt8GGw73LSKky2", 64 | "object": "vector_store", 65 | "name": null, 66 | "status": "completed", 67 | "usage_bytes": 0, 68 | "created_at": 1714495295, 69 | "file_counts": { 70 | "in_progress": 0, 71 | "completed": 0, 72 | "failed": 0, 73 | "cancelled": 0, 74 | "total": 0 75 | }, 76 | "metadata": {}, 77 | "expires_after": null, 78 | "expires_at": null, 79 | "last_active_at": 1714495295 80 | } 81 | recorded_at: Tue, 30 Apr 2024 16:41:35 GMT 82 | recorded_with: VCR 6.1.0 83 | -------------------------------------------------------------------------------- /spec/fixtures/cassettes/vector_stores_retrieve.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_interactions: 3 | - request: 4 | method: get 5 | uri: https://api.openai.com/v1/vector_stores/vs_hpLLcdz2Mvm3bKsGnN4hEsv2 6 | body: 7 | encoding: US-ASCII 8 | string: '' 9 | headers: 10 | Content-Type: 11 | - application/json 12 | Authorization: 13 | - Bearer 14 | Openai-Beta: 15 | - assistants=v2 16 | Accept-Encoding: 17 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 18 | Accept: 19 | - "*/*" 20 | User-Agent: 21 | - Ruby 22 | response: 23 | status: 24 | code: 200 25 | message: OK 26 | headers: 27 | Date: 28 | - Tue, 30 Apr 2024 16:41:33 GMT 29 | Content-Type: 30 | - application/json 31 | Transfer-Encoding: 32 | - chunked 33 | Connection: 34 | - keep-alive 35 | Openai-Version: 36 | - '2020-10-01' 37 | Openai-Organization: 38 | - gojom-1 39 | X-Request-Id: 40 | - req_51a57df69f7ba7b211d6a929ada1317a 41 | Openai-Processing-Ms: 42 | - '108' 43 | Strict-Transport-Security: 44 | - max-age=15724800; includeSubDomains 45 | Cf-Cache-Status: 46 | - DYNAMIC 47 | Set-Cookie: 48 | - __cf_bm=HaK9XWZ2atxgqReyxO83oYni4CR366u2NLDZBW6mug0-1714495293-1.0.1.1-A5BaLYUC3M0I7Tqy_.wvSRXf_4dKuejU6uY7xX8UjCrVZz0L86GSgSr2HZ6FtOpiaIuFkXJvYFZqnAV6qsE8DQ; 49 | path=/; expires=Tue, 30-Apr-24 17:11:33 GMT; domain=.api.openai.com; HttpOnly; 50 | Secure; SameSite=None 51 | - _cfuvid=juhVblaH4FE1qNM4ttMl9m6PUY02Sa5ar9vXKX.bVZg-1714495293626-0.0.1.1-604800000; 52 | path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None 53 | Server: 54 | - cloudflare 55 | Cf-Ray: 56 | - 87c8fadf5ff1a15e-GRU 57 | Alt-Svc: 58 | - h3=":443"; ma=86400 59 | body: 60 | encoding: ASCII-8BIT 61 | string: |- 62 | { 63 | "id": "vs_hpLLcdz2Mvm3bKsGnN4hEsv2", 64 | "object": "vector_store", 65 | "name": null, 66 | "status": "completed", 67 | "usage_bytes": 0, 68 | "created_at": 1714495292, 69 | "file_counts": { 70 | "in_progress": 0, 71 | "completed": 0, 72 | "failed": 0, 73 | "cancelled": 0, 74 | "total": 0 75 | }, 76 | "metadata": {}, 77 | "expires_after": null, 78 | "expires_at": null, 79 | "last_active_at": 1714495292 80 | } 81 | recorded_at: Tue, 30 Apr 2024 16:41:33 GMT 82 | recorded_with: VCR 6.1.0 83 | -------------------------------------------------------------------------------- /spec/fixtures/cassettes/vector_stores_retrieve_setup.yml: -------------------------------------------------------------------------------- 1 | --- 2 | http_interactions: 3 | - request: 4 | method: post 5 | uri: https://api.openai.com/v1/vector_stores 6 | body: 7 | encoding: UTF-8 8 | string: "{}" 9 | headers: 10 | Content-Type: 11 | - application/json 12 | Authorization: 13 | - Bearer 14 | Openai-Beta: 15 | - assistants=v2 16 | Accept-Encoding: 17 | - gzip;q=1.0,deflate;q=0.6,identity;q=0.3 18 | Accept: 19 | - "*/*" 20 | User-Agent: 21 | - Ruby 22 | response: 23 | status: 24 | code: 200 25 | message: OK 26 | headers: 27 | Date: 28 | - Tue, 30 Apr 2024 16:41:33 GMT 29 | Content-Type: 30 | - application/json 31 | Transfer-Encoding: 32 | - chunked 33 | Connection: 34 | - keep-alive 35 | Openai-Version: 36 | - '2020-10-01' 37 | Openai-Organization: 38 | - gojom-1 39 | X-Request-Id: 40 | - req_827758a71d023ffd2f10f5207072452e 41 | Openai-Processing-Ms: 42 | - '382' 43 | Strict-Transport-Security: 44 | - max-age=15724800; includeSubDomains 45 | Cf-Cache-Status: 46 | - DYNAMIC 47 | Set-Cookie: 48 | - __cf_bm=RLKEJiQXdwNJ9Mw9.Lm72936HnuD8T81hh2gGaitE5w-1714495292-1.0.1.1-I4XzgZX2Aju3rV2vHwu0iG_KJCHSDBGdrFIFm_8222bYwJLlpZvK4p6WoNl.EF7GmXNEupmsB8KeCMVh3SBFeg; 49 | path=/; expires=Tue, 30-Apr-24 17:11:32 GMT; domain=.api.openai.com; HttpOnly; 50 | Secure; SameSite=None 51 | - _cfuvid=fIbxQif_VJIs0eOZUEjWP.OfR3lY24J_uc.w1KSpUls-1714495293000-0.0.1.1-604800000; 52 | path=/; domain=.api.openai.com; HttpOnly; Secure; SameSite=None 53 | Server: 54 | - cloudflare 55 | Cf-Ray: 56 | - 87c8fad9cf631a88-GRU 57 | Alt-Svc: 58 | - h3=":443"; ma=86400 59 | body: 60 | encoding: ASCII-8BIT 61 | string: |- 62 | { 63 | "id": "vs_hpLLcdz2Mvm3bKsGnN4hEsv2", 64 | "object": "vector_store", 65 | "name": null, 66 | "status": "completed", 67 | "usage_bytes": 0, 68 | "created_at": 1714495292, 69 | "file_counts": { 70 | "in_progress": 0, 71 | "completed": 0, 72 | "failed": 0, 73 | "cancelled": 0, 74 | "total": 0 75 | }, 76 | "metadata": {}, 77 | "expires_after": null, 78 | "expires_at": null, 79 | "last_active_at": 1714495292 80 | } 81 | recorded_at: Tue, 30 Apr 2024 16:41:32 GMT 82 | recorded_with: VCR 6.1.0 83 | -------------------------------------------------------------------------------- /spec/fixtures/files/audio_sample.mp3: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patrickm53/ruby-on-rails--rubocop---openai/c2d79aecf04079c737e26f081b17d8588938520c/spec/fixtures/files/audio_sample.mp3 -------------------------------------------------------------------------------- /spec/fixtures/files/batch.jsonl: -------------------------------------------------------------------------------- 1 | {"custom_id": "request-1", "method": "POST", "url": "/v1/chat/completions", "body": {"model": "gpt-3.5-turbo", "messages": [{"role": "system", "content": "You are a helpful assistant."}, {"role": "user", "content": "What is 2+2?"}]}} 2 | {"custom_id": "request-2", "method": "POST", "url": "/v1/chat/completions", "body": {"model": "gpt-3.5-turbo", "messages": [{"role": "system", "content": "You are a helpful assistant."}, {"role": "user", "content": "What is 3+2?"}]}} 3 | -------------------------------------------------------------------------------- /spec/fixtures/files/errors/missing_quote.jsonl: -------------------------------------------------------------------------------- 1 | {"prompt":"Overjoyed with my new phone! ->", "completion":" positive"} 2 | {"prompt":"@lakers disappoint for a third straight night ->", "completion":" negative} 3 | -------------------------------------------------------------------------------- /spec/fixtures/files/image.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patrickm53/ruby-on-rails--rubocop---openai/c2d79aecf04079c737e26f081b17d8588938520c/spec/fixtures/files/image.png -------------------------------------------------------------------------------- /spec/fixtures/files/mask.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/patrickm53/ruby-on-rails--rubocop---openai/c2d79aecf04079c737e26f081b17d8588938520c/spec/fixtures/files/mask.png -------------------------------------------------------------------------------- /spec/fixtures/files/sarcastic.jsonl: -------------------------------------------------------------------------------- 1 | {"messages": [{"role": "system", "content": "Marv is a factual chatbot that is also sarcastic."}, {"role": "user", "content": "What's the capital of France?"}, {"role": "assistant", "content": "Paris, as if everyone doesn't know that already."}]} 2 | {"messages": [{"role": "system", "content": "Marv is a factual chatbot that is also sarcastic."}, {"role": "user", "content": "Who wrote 'Romeo and Juliet'?"}, {"role": "assistant", "content": "Oh, just some guy named William Shakespeare. Ever heard of him?"}]} 3 | {"messages": [{"role": "system", "content": "Marv is a factual chatbot that is also sarcastic."}, {"role": "user", "content": "How far is the Moon from Earth?"}, {"role": "assistant", "content": "Around 384,400 kilometers. Give or take a few, like that really matters."}]} 4 | {"messages": [{"role": "system", "content": "Marv is a factual chatbot that is also sarcastic."}, {"role": "user", "content": "What's the largest mammal?"}, {"role": "assistant", "content": "The blue whale, but I'm sure it's just having a big-boned moment."}]} 5 | {"messages": [{"role": "system", "content": "Marv is a factual chatbot that is also sarcastic."}, {"role": "user", "content": "What's the tallest mountain in the world?"}, {"role": "assistant", "content": "Everest. But hey, it's just a hill compared to other things in the universe."}]} 6 | {"messages": [{"role": "system", "content": "Marv is a factual chatbot that is also sarcastic."}, {"role": "user", "content": "Who discovered gravity?"}, {"role": "assistant", "content": "Oh, just a chap named Isaac Newton. He had an apple moment, nothing big."}]} 7 | {"messages": [{"role": "system", "content": "Marv is a factual chatbot that is also sarcastic."}, {"role": "user", "content": "What's the chemical symbol for water?"}, {"role": "assistant", "content": "H2O. But don't confuse it with H2O2, unless you're in for some bubbly fun!"}]} 8 | {"messages": [{"role": "system", "content": "Marv is a factual chatbot that is also sarcastic."}, {"role": "user", "content": "When was the Eiffel Tower built?"}, {"role": "assistant", "content": "1889. Because Paris just felt like having a gigantic metal stick in the middle."}]} 9 | {"messages": [{"role": "system", "content": "Marv is a factual chatbot that is also sarcastic."}, {"role": "user", "content": "Who painted the Mona Lisa?"}, {"role": "assistant", "content": "Leonardo da Vinci. But I heard it was just a side gig for him."}]} 10 | {"messages": [{"role": "system", "content": "Marv is a factual chatbot that is also sarcastic."}, {"role": "user", "content": "How many planets are in our solar system?"}, {"role": "assistant", "content": "Eight. Sorry, Pluto, you're still not on the list!"}]} 11 | -------------------------------------------------------------------------------- /spec/fixtures/files/sentiment.jsonl: -------------------------------------------------------------------------------- 1 | {"prompt":"Overjoyed with my new phone! ->", "completion":" positive"} 2 | {"prompt":"@lakers disappoint for a third straight night ->", "completion":" negative"} 3 | -------------------------------------------------------------------------------- /spec/fixtures/files/text.txt: -------------------------------------------------------------------------------- 1 | Hello world! -------------------------------------------------------------------------------- /spec/fixtures/files/train.jsonl: -------------------------------------------------------------------------------- 1 | {"text": "good film, but very glum.", "label": "Positive"} 2 | {"text": "i sympathize with the plight of these families, but the movie doesn't do a very good job conveying the issue at hand.", "label": "Negative"} 3 | {"text": "the very definition of the `small' movie, but it is a good stepping stone for director sprecher.", "label": "Positive"} 4 | -------------------------------------------------------------------------------- /spec/openai/client/assistants_spec.rb: -------------------------------------------------------------------------------- 1 | RSpec.describe OpenAI::Client do 2 | describe "#assistants" do 3 | let(:assistant_id) do 4 | VCR.use_cassette("#{cassette} setup") do 5 | OpenAI::Client.new.assistants.create( 6 | parameters: { 7 | model: "gpt-4", 8 | name: "OpenAI-Ruby test assistant" 9 | } 10 | )["id"] 11 | end 12 | end 13 | 14 | describe "#list", :vcr do 15 | let(:response) { OpenAI::Client.new.assistants.list } 16 | let(:cassette) { "assistants list" } 17 | 18 | before { assistant_id } 19 | 20 | it "succeeds" do 21 | VCR.use_cassette(cassette) do 22 | expect(response.dig("data", 0, "object")).to eq("assistant") 23 | end 24 | end 25 | end 26 | 27 | describe "#retrieve" do 28 | let(:cassette) { "assistants retrieve" } 29 | let(:response) { OpenAI::Client.new.assistants.retrieve(id: assistant_id) } 30 | 31 | it "succeeds" do 32 | VCR.use_cassette(cassette) do 33 | expect(response["object"]).to eq("assistant") 34 | end 35 | end 36 | end 37 | 38 | describe "#create" do 39 | let(:cassette) { "assistants create" } 40 | let(:response) do 41 | OpenAI::Client.new.assistants.create(parameters: { model: "gpt-4", 42 | name: "OpenAI-Ruby test assistant" }) 43 | end 44 | 45 | it "succeeds" do 46 | VCR.use_cassette(cassette) do 47 | expect(response["object"]).to eq "assistant" 48 | end 49 | end 50 | end 51 | 52 | describe "#modify" do 53 | let(:cassette) { "assistants modify" } 54 | let(:response) do 55 | OpenAI::Client.new.assistants.modify( 56 | id: assistant_id, 57 | parameters: { model: "gpt-3.5-turbo", name: "Test Assistant for OpenAI-Ruby" } 58 | ) 59 | end 60 | 61 | it "succeeds" do 62 | VCR.use_cassette(cassette) do 63 | expect(response["object"]).to eq "assistant" 64 | end 65 | end 66 | end 67 | 68 | describe "#delete" do 69 | let(:cassette) { "assistants delete" } 70 | let(:response) do 71 | OpenAI::Client.new.assistants.delete(id: assistant_id) 72 | end 73 | 74 | it "succeeds" do 75 | VCR.use_cassette(cassette) do 76 | expect(response["object"]).to eq "assistant.deleted" 77 | end 78 | end 79 | end 80 | end 81 | end 82 | -------------------------------------------------------------------------------- /spec/openai/client/audio_spec.rb: -------------------------------------------------------------------------------- 1 | RSpec.describe OpenAI::Client do 2 | describe "#audio" do 3 | describe "#transcribe" do 4 | context "with audio", :vcr do 5 | let(:filename) { "audio_sample.mp3" } 6 | let(:audio) { File.join(RSPEC_ROOT, "fixtures/files", filename) } 7 | 8 | let(:response) do 9 | OpenAI::Client.new.audio.transcribe( 10 | parameters: { 11 | model: model, 12 | file: File.open(audio, "rb") 13 | } 14 | ) 15 | end 16 | let(:content) { response["text"] } 17 | let(:cassette) { "audio #{model} transcribe".downcase } 18 | 19 | context "with model: whisper-1" do 20 | let(:model) { "whisper-1" } 21 | 22 | it "succeeds" do 23 | VCR.use_cassette(cassette) do 24 | expect(content.empty?).to eq(false) 25 | end 26 | end 27 | end 28 | end 29 | end 30 | 31 | describe "#translate" do 32 | context "with audio", :vcr do 33 | let(:filename) { "audio_sample.mp3" } 34 | let(:audio) { File.join(RSPEC_ROOT, "fixtures/files", filename) } 35 | 36 | let(:response) do 37 | OpenAI::Client.new.audio.translate( 38 | parameters: { 39 | model: model, 40 | file: File.open(audio, "rb") 41 | } 42 | ) 43 | end 44 | let(:content) { response["text"] } 45 | let(:cassette) { "audio #{model} translate".downcase } 46 | 47 | context "with model: whisper-1" do 48 | let(:model) { "whisper-1" } 49 | 50 | it "succeeds" do 51 | VCR.use_cassette(cassette) do 52 | expect(content.empty?).to eq(false) 53 | end 54 | end 55 | end 56 | end 57 | end 58 | 59 | describe "#speech" do 60 | context "with audio", :vcr do 61 | let(:model) { "tts-1" } 62 | 63 | it "returns a working mp3 file as body" do 64 | VCR.use_cassette("speech #{model} test") do 65 | response = OpenAI::Client.new.audio.speech( 66 | parameters: { 67 | model: model, 68 | input: "This is a speech test!", 69 | voice: "alloy" 70 | } 71 | ) 72 | expect(response).not_to be_empty 73 | end 74 | end 75 | end 76 | end 77 | end 78 | end 79 | -------------------------------------------------------------------------------- /spec/openai/client/completions_spec.rb: -------------------------------------------------------------------------------- 1 | RSpec.describe OpenAI::Client do 2 | describe "#completions: gpt-3.5-turbo-instruct" do 3 | context "with a prompt and max_tokens", :vcr do 4 | let(:prompt) { "Once upon a time" } 5 | let(:max_tokens) { 5 } 6 | 7 | let(:response) do 8 | OpenAI::Client.new.completions( 9 | parameters: { 10 | model: model, 11 | prompt: prompt, 12 | max_tokens: max_tokens 13 | } 14 | ) 15 | end 16 | let(:text) { response.dig("choices", 0, "text") } 17 | let(:cassette) { "#{model} completions #{prompt}".downcase } 18 | let(:model) { "gpt-3.5-turbo-instruct" } 19 | 20 | it "succeeds" do 21 | VCR.use_cassette(cassette) do 22 | expect(text.split.empty?).to eq(false) 23 | end 24 | end 25 | end 26 | end 27 | end 28 | -------------------------------------------------------------------------------- /spec/openai/client/embeddings_spec.rb: -------------------------------------------------------------------------------- 1 | RSpec.describe OpenAI::Client do 2 | describe "#embeddings", :vcr do 3 | let(:input) { "The food was delicious and the waiter..." } 4 | let(:cassette) { "#{model} embeddings #{input}".downcase } 5 | let(:response) do 6 | OpenAI::Client.new.embeddings( 7 | parameters: { 8 | model: model, 9 | input: input 10 | } 11 | ) 12 | end 13 | 14 | context "with model: text-embedding-ada-002" do 15 | let(:model) { "text-embedding-ada-002" } 16 | 17 | it "succeeds" do 18 | VCR.use_cassette(cassette) do 19 | expect(response.dig("data", 0, "object")).to eq("embedding") 20 | end 21 | end 22 | end 23 | end 24 | end 25 | -------------------------------------------------------------------------------- /spec/openai/client/messages_spec.rb: -------------------------------------------------------------------------------- 1 | RSpec.describe OpenAI::Client do 2 | describe "#messages" do 3 | let(:thread_id) do 4 | VCR.use_cassette("#{cassette} thread setup") do 5 | OpenAI::Client.new.threads.create(parameters: {})["id"] 6 | end 7 | end 8 | let(:message_id) do 9 | VCR.use_cassette("#{cassette} message setup") do 10 | OpenAI::Client.new.messages.create( 11 | thread_id: thread_id, 12 | parameters: { 13 | role: "user", 14 | content: "Can you help me write an API library to interact with the OpenAI API please?" 15 | } 16 | )["id"] 17 | end 18 | end 19 | 20 | describe "#retrieve" do 21 | let(:cassette) { "messages retrieve" } 22 | let(:response) do 23 | OpenAI::Client.new.messages.retrieve(thread_id: thread_id, id: message_id) 24 | end 25 | 26 | it "succeeds" do 27 | VCR.use_cassette(cassette) do 28 | expect(response["object"]).to eq("thread.message") 29 | end 30 | end 31 | end 32 | 33 | describe "#list" do 34 | let(:cassette) { "messages list" } 35 | let(:response) do 36 | OpenAI::Client.new.messages.list(thread_id: thread_id, parameters: { order: "asc" }) 37 | end 38 | 39 | it "succeeds" do 40 | VCR.use_cassette(cassette) do 41 | expect(response["object"]).to eq("list") 42 | end 43 | end 44 | end 45 | 46 | describe "#create" do 47 | let(:cassette) { "messages create" } 48 | let(:response) do 49 | OpenAI::Client.new.messages.create( 50 | thread_id: thread_id, 51 | parameters: { 52 | role: "user", 53 | content: "Can you help me write an API library to interact with the OpenAI API please?" 54 | } 55 | ) 56 | end 57 | 58 | it "succeeds" do 59 | VCR.use_cassette(cassette) do 60 | expect(response["object"]).to eq "thread.message" 61 | end 62 | end 63 | end 64 | 65 | describe "#modify" do 66 | let(:cassette) { "messages modify" } 67 | let(:response) do 68 | OpenAI::Client.new.messages.modify( 69 | id: message_id, 70 | thread_id: thread_id, 71 | parameters: { 72 | metadata: { modified: "true" } 73 | } 74 | ) 75 | end 76 | 77 | it "succeeds" do 78 | VCR.use_cassette(cassette) do 79 | expect(response["object"]).to eq "thread.message" 80 | end 81 | end 82 | end 83 | end 84 | end 85 | -------------------------------------------------------------------------------- /spec/openai/client/models_spec.rb: -------------------------------------------------------------------------------- 1 | RSpec.describe OpenAI::Client do 2 | describe "#models" do 3 | describe "#list", :vcr do 4 | let(:response) { OpenAI::Client.new.models.list } 5 | let(:cassette) { "models list" } 6 | 7 | it "succeeds" do 8 | VCR.use_cassette(cassette) do 9 | expect(response.dig("data", 0, "object")).to eq("model") 10 | end 11 | end 12 | end 13 | 14 | describe "#retrieve" do 15 | let(:cassette) { "models retrieve" } 16 | let(:response) { OpenAI::Client.new.models.retrieve(id: "gpt-3.5-turbo-instruct") } 17 | 18 | it "succeeds" do 19 | VCR.use_cassette(cassette) do 20 | expect(response["object"]).to eq("model") 21 | end 22 | end 23 | end 24 | end 25 | end 26 | -------------------------------------------------------------------------------- /spec/openai/client/moderations_spec.rb: -------------------------------------------------------------------------------- 1 | RSpec.describe OpenAI::Client do 2 | describe "#moderations", :vcr do 3 | let(:input) { "I'm worried about that." } 4 | let(:cassette) { "moderations #{input}".downcase } 5 | let(:response) do 6 | OpenAI::Client.new.moderations( 7 | parameters: { 8 | input: input 9 | } 10 | ) 11 | end 12 | 13 | it "succeeds" do 14 | VCR.use_cassette(cassette) do 15 | expect(response.dig("results", 0, "categories", "hate")).to eq(false) 16 | end 17 | end 18 | end 19 | end 20 | -------------------------------------------------------------------------------- /spec/openai/client/run_steps_spec.rb: -------------------------------------------------------------------------------- 1 | RSpec.describe OpenAI::Client do 2 | describe "#run_steps" do 3 | let(:thread_id) do 4 | VCR.use_cassette("#{cassette} thread setup") do 5 | OpenAI::Client.new.threads.create(parameters: {})["id"] 6 | end 7 | end 8 | let(:assistant_id) do 9 | VCR.use_cassette("#{cassette} assistant setup") do 10 | OpenAI::Client.new.assistants.create( 11 | parameters: { 12 | model: "gpt-4", 13 | name: "OpenAI-Ruby test assistant", 14 | instructions: "When asked a question, write and run Ruby code to answer the question" 15 | } 16 | )["id"] 17 | end 18 | end 19 | let(:run_id) do 20 | VCR.use_cassette("#{cassette} run setup") do 21 | OpenAI::Client.new.runs.create( 22 | thread_id: thread_id, 23 | parameters: { 24 | assistant_id: assistant_id 25 | } 26 | )["id"] 27 | end 28 | end 29 | 30 | describe "#list" do 31 | let(:cassette) { "run_steps list" } 32 | let(:response) do 33 | OpenAI::Client.new.run_steps.list( 34 | thread_id: thread_id, 35 | run_id: run_id, 36 | parameters: { order: "asc" } 37 | ) 38 | end 39 | 40 | it "succeeds" do 41 | VCR.use_cassette(cassette) do 42 | expect(response["object"]).to eq("list") 43 | end 44 | end 45 | end 46 | 47 | describe "#retrieve" do 48 | let(:cassette) { "run_steps retrieve" } 49 | let(:response) do 50 | OpenAI::Client.new.run_steps.retrieve( 51 | thread_id: thread_id, 52 | run_id: run_id, 53 | id: "123" 54 | ) 55 | end 56 | 57 | it "returns the correct error" do 58 | VCR.use_cassette(cassette) do 59 | response 60 | rescue StandardError => e 61 | expect(e.response.dig(:body, "error", "message")).to include("No run step found") 62 | end 63 | end 64 | end 65 | end 66 | end 67 | -------------------------------------------------------------------------------- /spec/openai/client/threads_spec.rb: -------------------------------------------------------------------------------- 1 | RSpec.describe OpenAI::Client do 2 | describe "#threads" do 3 | let(:thread_id) do 4 | VCR.use_cassette("#{cassette} setup") do 5 | OpenAI::Client.new.threads.create(parameters: {})["id"] 6 | end 7 | end 8 | 9 | describe "#retrieve" do 10 | let(:cassette) { "threads retrieve" } 11 | let(:response) { OpenAI::Client.new.threads.retrieve(id: thread_id) } 12 | 13 | it "succeeds" do 14 | VCR.use_cassette(cassette) do 15 | expect(response["object"]).to eq("thread") 16 | end 17 | end 18 | end 19 | 20 | describe "#create" do 21 | let(:cassette) { "threads create" } 22 | let(:response) do 23 | OpenAI::Client.new.threads.create(parameters: {}) 24 | end 25 | 26 | it "succeeds" do 27 | VCR.use_cassette(cassette) do 28 | expect(response["object"]).to eq "thread" 29 | end 30 | end 31 | end 32 | 33 | describe "#modify" do 34 | let(:cassette) { "threads modify" } 35 | let(:response) do 36 | OpenAI::Client.new.threads.modify( 37 | id: thread_id, 38 | parameters: { metadata: { modified: "true" } } 39 | ) 40 | end 41 | 42 | it "succeeds" do 43 | VCR.use_cassette(cassette) do 44 | expect(response["object"]).to eq "thread" 45 | end 46 | end 47 | end 48 | 49 | describe "#delete" do 50 | let(:cassette) { "threads delete" } 51 | let(:response) do 52 | OpenAI::Client.new.threads.delete(id: thread_id) 53 | end 54 | 55 | it "succeeds" do 56 | VCR.use_cassette(cassette) do 57 | expect(response["object"]).to eq "thread.deleted" 58 | end 59 | end 60 | end 61 | end 62 | end 63 | -------------------------------------------------------------------------------- /spec/openai/client/vector_store_file_batches_spec.rb: -------------------------------------------------------------------------------- 1 | RSpec.describe OpenAI::Client do 2 | describe "#vector_store_file_batches" do 3 | let(:vector_store_id) do 4 | VCR.use_cassette("#{cassette} vector_store setup") do 5 | OpenAI::Client.new.vector_stores.create(parameters: {})["id"] 6 | end 7 | end 8 | 9 | let(:filename) { "text.txt" } 10 | let(:file) { File.join(RSPEC_ROOT, "fixtures/files", filename) } 11 | let(:upload_purpose) { "assistants" } 12 | let(:file_id) do 13 | VCR.use_cassette("#{cassette} file setup") do 14 | OpenAI::Client.new.files.upload(parameters: { file: file, purpose: upload_purpose })["id"] 15 | end 16 | end 17 | 18 | let(:file_batch_id) do 19 | VCR.use_cassette("#{cassette} vector_store_file_batch setup") do 20 | OpenAI::Client.new.vector_store_file_batches.create( 21 | vector_store_id: vector_store_id, 22 | parameters: { file_ids: [file_id] } 23 | )["id"] 24 | end 25 | end 26 | 27 | describe "#list" do 28 | let(:cassette) { "vector_store_file_batches list" } 29 | let(:response) do 30 | OpenAI::Client.new.vector_store_file_batches.list(vector_store_id: vector_store_id, 31 | id: file_batch_id) 32 | end 33 | 34 | before { file_batch_id } 35 | 36 | it "succeeds" do 37 | VCR.use_cassette(cassette) do 38 | expect(response.dig("data", 0, "object")).to eq("vector_store.file") 39 | end 40 | end 41 | end 42 | 43 | describe "#retrieve" do 44 | let(:cassette) { "vector_store_file_batches retrieve" } 45 | let(:response) do 46 | OpenAI::Client.new.vector_store_file_batches.retrieve(vector_store_id: vector_store_id, 47 | id: file_batch_id) 48 | end 49 | 50 | it "succeeds" do 51 | VCR.use_cassette(cassette) do 52 | expect(response["object"]).to eq("vector_store.file_batch") 53 | end 54 | end 55 | end 56 | 57 | describe "#create" do 58 | let(:cassette) { "vector_store_file_batches create" } 59 | let(:response) do 60 | OpenAI::Client.new.vector_store_file_batches.create( 61 | vector_store_id: vector_store_id, 62 | parameters: { file_ids: [file_id] } 63 | ) 64 | end 65 | 66 | it "succeeds" do 67 | VCR.use_cassette(cassette) do 68 | expect(response["object"]).to eq "vector_store.file_batch" 69 | end 70 | end 71 | end 72 | 73 | describe "#cancel" do 74 | let(:cassette) { "vector_store_file_batches cancel" } 75 | let(:response) do 76 | OpenAI::Client.new.vector_store_file_batches.cancel(vector_store_id: vector_store_id, 77 | id: file_batch_id) 78 | end 79 | 80 | it "succeeds" do 81 | VCR.use_cassette(cassette) do 82 | expect(response["object"]).to eq "vector_store.file_batch" 83 | end 84 | end 85 | end 86 | end 87 | end 88 | -------------------------------------------------------------------------------- /spec/openai/client/vector_store_files_spec.rb: -------------------------------------------------------------------------------- 1 | RSpec.describe OpenAI::Client do 2 | describe "#vector_store_files" do 3 | let(:vector_store_id) do 4 | VCR.use_cassette("#{cassette} vector_store setup") do 5 | OpenAI::Client.new.vector_stores.create(parameters: {})["id"] 6 | end 7 | end 8 | 9 | let(:filename) { "text.txt" } 10 | let(:file) { File.join(RSPEC_ROOT, "fixtures/files", filename) } 11 | let(:upload_purpose) { "assistants" } 12 | let(:file_id) do 13 | VCR.use_cassette("#{cassette} file setup") do 14 | OpenAI::Client.new.files.upload(parameters: { file: file, purpose: upload_purpose })["id"] 15 | end 16 | end 17 | 18 | let(:vector_store_file_id) do 19 | VCR.use_cassette("#{cassette} vector_store_file setup") do 20 | OpenAI::Client.new.vector_store_files.create( 21 | vector_store_id: vector_store_id, 22 | parameters: { file_id: file_id } 23 | )["id"] 24 | end 25 | end 26 | 27 | describe "#list" do 28 | let(:cassette) { "vector_store_files list" } 29 | let(:response) do 30 | OpenAI::Client.new.vector_store_files.list(vector_store_id: vector_store_id) 31 | end 32 | 33 | before { vector_store_file_id } 34 | 35 | it "succeeds" do 36 | VCR.use_cassette(cassette) do 37 | expect(response.dig("data", 0, "object")).to eq("vector_store.file") 38 | end 39 | end 40 | end 41 | 42 | describe "#retrieve" do 43 | let(:cassette) { "vector_store_files retrieve" } 44 | let(:response) do 45 | OpenAI::Client.new.vector_store_files.retrieve(vector_store_id: vector_store_id, 46 | id: vector_store_file_id) 47 | end 48 | 49 | it "succeeds" do 50 | VCR.use_cassette(cassette) do 51 | expect(response["object"]).to eq("vector_store.file") 52 | end 53 | end 54 | end 55 | 56 | describe "#create" do 57 | let(:cassette) { "vector_store_files create" } 58 | let(:response) do 59 | OpenAI::Client.new.vector_store_files.create( 60 | vector_store_id: vector_store_id, 61 | parameters: { file_id: file_id } 62 | ) 63 | end 64 | 65 | it "succeeds" do 66 | VCR.use_cassette(cassette) do 67 | expect(response["object"]).to eq "vector_store.file" 68 | end 69 | end 70 | end 71 | 72 | describe "#delete" do 73 | let(:cassette) { "vector_store_files delete" } 74 | let(:response) do 75 | OpenAI::Client.new.vector_store_files.delete(vector_store_id: vector_store_id, 76 | id: vector_store_file_id) 77 | end 78 | 79 | it "succeeds" do 80 | VCR.use_cassette(cassette) do 81 | expect(response["object"]).to eq "vector_store.file.deleted" 82 | end 83 | end 84 | end 85 | end 86 | end 87 | -------------------------------------------------------------------------------- /spec/openai/client/vector_stores_spec.rb: -------------------------------------------------------------------------------- 1 | RSpec.describe OpenAI::Client do 2 | describe "#vector_stores" do 3 | let(:vector_store_id) do 4 | VCR.use_cassette("#{cassette} setup") do 5 | OpenAI::Client.new.vector_stores.create(parameters: {})["id"] 6 | end 7 | end 8 | 9 | describe "#list" do 10 | let(:cassette) { "vector_stores list" } 11 | let(:response) do 12 | OpenAI::Client.new.vector_stores.list(parameters: {}) 13 | end 14 | 15 | it "succeeds" do 16 | vector_store_id # Need something to list. 17 | VCR.use_cassette(cassette) do 18 | expect(response.dig("data", 0, "object")).to eq("vector_store") 19 | end 20 | end 21 | end 22 | 23 | describe "#retrieve" do 24 | let(:cassette) { "vector_stores retrieve" } 25 | let(:response) { OpenAI::Client.new.vector_stores.retrieve(id: vector_store_id) } 26 | 27 | it "succeeds" do 28 | VCR.use_cassette(cassette) do 29 | expect(response["object"]).to eq("vector_store") 30 | end 31 | end 32 | end 33 | 34 | describe "#create" do 35 | let(:cassette) { "vector_stores create" } 36 | let(:response) do 37 | OpenAI::Client.new.vector_stores.create(parameters: {}) 38 | end 39 | 40 | it "succeeds" do 41 | VCR.use_cassette(cassette) do 42 | expect(response["object"]).to eq "vector_store" 43 | end 44 | end 45 | end 46 | 47 | describe "#modify" do 48 | let(:cassette) { "vector_stores modify" } 49 | let(:response) do 50 | OpenAI::Client.new.vector_stores.modify( 51 | id: vector_store_id, 52 | parameters: { metadata: { modified: "true" } } 53 | ) 54 | end 55 | 56 | it "succeeds" do 57 | VCR.use_cassette(cassette) do 58 | expect(response["object"]).to eq "vector_store" 59 | end 60 | end 61 | end 62 | 63 | describe "#delete" do 64 | let(:cassette) { "vector_stores delete" } 65 | let(:response) do 66 | OpenAI::Client.new.vector_stores.delete(id: vector_store_id) 67 | end 68 | 69 | it "succeeds" do 70 | VCR.use_cassette(cassette) do 71 | expect(response["object"]).to eq "vector_store.deleted" 72 | end 73 | end 74 | end 75 | end 76 | end 77 | -------------------------------------------------------------------------------- /spec/openai_spec.rb: -------------------------------------------------------------------------------- 1 | RSpec.describe OpenAI do 2 | it "has a version number" do 3 | expect(OpenAI::VERSION).not_to be nil 4 | end 5 | 6 | describe "#configure" do 7 | let(:access_token) { "abc123" } 8 | let(:api_version) { "v2" } 9 | let(:organization_id) { "def456" } 10 | let(:custom_uri_base) { "ghi789" } 11 | let(:custom_request_timeout) { 25 } 12 | let(:extra_headers) { { "User-Agent" => "OpenAI Ruby Gem #{OpenAI::VERSION}" } } 13 | 14 | before do 15 | OpenAI.configure do |config| 16 | config.access_token = access_token 17 | config.api_version = api_version 18 | config.organization_id = organization_id 19 | config.extra_headers = extra_headers 20 | end 21 | end 22 | 23 | it "returns the config" do 24 | expect(OpenAI.configuration.access_token).to eq(access_token) 25 | expect(OpenAI.configuration.api_version).to eq(api_version) 26 | expect(OpenAI.configuration.organization_id).to eq(organization_id) 27 | expect(OpenAI.configuration.uri_base).to eq("https://api.openai.com/") 28 | expect(OpenAI.configuration.request_timeout).to eq(120) 29 | expect(OpenAI.configuration.extra_headers).to eq(extra_headers) 30 | end 31 | 32 | context "with custom timeout and uri base" do 33 | before do 34 | OpenAI.configure do |config| 35 | config.uri_base = custom_uri_base 36 | config.request_timeout = custom_request_timeout 37 | end 38 | end 39 | 40 | it "returns the config" do 41 | expect(OpenAI.configuration.access_token).to eq(access_token) 42 | expect(OpenAI.configuration.api_version).to eq(api_version) 43 | expect(OpenAI.configuration.organization_id).to eq(organization_id) 44 | expect(OpenAI.configuration.uri_base).to eq(custom_uri_base) 45 | expect(OpenAI.configuration.request_timeout).to eq(custom_request_timeout) 46 | expect(OpenAI.configuration.extra_headers).to eq(extra_headers) 47 | end 48 | end 49 | end 50 | 51 | describe "#rough_token_count" do 52 | context "on a non-String" do 53 | it "raises an error" do 54 | expect { OpenAI.rough_token_count([]) }.to raise_error(ArgumentError) 55 | end 56 | end 57 | 58 | context "on the empty string" do 59 | it "returns 0" do 60 | expect(OpenAI.rough_token_count("")).to eq(0) 61 | end 62 | end 63 | 64 | context "on a string" do 65 | let(:content) { "Red is my favorite color. Egg is not a necessary ingredient." } 66 | it "estimates tokens" do 67 | expect(OpenAI.rough_token_count(content)).to eq(15) 68 | end 69 | end 70 | end 71 | end 72 | -------------------------------------------------------------------------------- /spec/spec_helper.rb: -------------------------------------------------------------------------------- 1 | require "bundler/setup" 2 | require "dotenv/load" 3 | require "openai" 4 | require "openai/compatibility" 5 | require "vcr" 6 | 7 | Dir[File.expand_path("spec/support/**/*.rb")].sort.each { |f| require f } 8 | 9 | VCR.configure do |c| 10 | c.hook_into :webmock 11 | c.cassette_library_dir = "spec/fixtures/cassettes" 12 | c.default_cassette_options = { 13 | record: ENV.fetch("OPENAI_ACCESS_TOKEN", nil) ? :all : :new_episodes, 14 | match_requests_on: [:method, :uri, VCRMultipartMatcher.new] 15 | } 16 | c.filter_sensitive_data("") { OpenAI.configuration.access_token } 17 | c.filter_sensitive_data("") { OpenAI.configuration.organization_id } 18 | if (user_id = ENV.fetch("OPENAI_USER_ID", nil)) 19 | c.filter_sensitive_data("") { user_id } 20 | end 21 | end 22 | 23 | RSpec.configure do |c| 24 | # Enable flags like --only-failures and --next-failure 25 | c.example_status_persistence_file_path = ".rspec_status" 26 | 27 | # Disable RSpec exposing methods globally on `Module` and `main` 28 | c.disable_monkey_patching! 29 | 30 | c.expect_with :rspec do |rspec| 31 | rspec.syntax = :expect 32 | end 33 | 34 | if ENV.fetch("OPENAI_ACCESS_TOKEN", nil) 35 | warning = "WARNING! Specs are hitting the OpenAI API using your OPENAI_ACCESS_TOKEN! This 36 | costs at least 2 cents per run and is very slow! If you don't want this, unset 37 | OPENAI_ACCESS_TOKEN to just run against the stored VCR responses.".freeze 38 | warning = RSpec::Core::Formatters::ConsoleCodes.wrap(warning, :bold_red) 39 | 40 | c.before(:suite) { RSpec.configuration.reporter.message(warning) } 41 | c.after(:suite) { RSpec.configuration.reporter.message(warning) } 42 | end 43 | 44 | c.before(:all) do 45 | OpenAI.configure do |config| 46 | config.access_token = ENV.fetch("OPENAI_ACCESS_TOKEN", "dummy-token") 47 | if (organization_id = ENV.fetch("OPENAI_ORGANIZATION_ID", nil)) 48 | config.organization_id = organization_id 49 | end 50 | end 51 | end 52 | end 53 | 54 | RSPEC_ROOT = File.dirname __FILE__ 55 | -------------------------------------------------------------------------------- /spec/support/vcr_multipart_matcher.rb: -------------------------------------------------------------------------------- 1 | class VCRMultipartMatcher 2 | MULTIPART_HEADER_MATCHER = %r{^multipart/form-data; boundary=(.+)$}.freeze 3 | BOUNDARY_SUBSTITUTION = "----MultipartBoundaryAbcD3fGhiXyz00001".freeze 4 | 5 | def call(request1, request2) 6 | return false unless same_content_type?(request1, request2) 7 | unless headers_excluding_content_type(request1) == headers_excluding_content_type(request2) 8 | return false 9 | end 10 | 11 | normalized_multipart_body(request1) == normalized_multipart_body(request2) 12 | end 13 | 14 | private 15 | 16 | def same_content_type?(request1, request2) 17 | content_type1 = (request1.headers["Content-Type"] || []).first.to_s 18 | content_type2 = (request2.headers["Content-Type"] || []).first.to_s 19 | 20 | if multipart_request?(content_type1) 21 | multipart_request?(content_type2) 22 | elsif multipart_request?(content_type2) 23 | false 24 | else 25 | content_type1 == content_type2 26 | end 27 | end 28 | 29 | def headers_excluding_content_type(request) 30 | request.headers.reject { |key, _| key == "Content-Type" } 31 | end 32 | 33 | def normalized_multipart_body(request) 34 | content_type = (request.headers["Content-Type"] || []).first.to_s 35 | 36 | return request.headers unless multipart_request?(content_type) 37 | 38 | boundary = MULTIPART_HEADER_MATCHER.match(content_type)[1] 39 | request.body.gsub(boundary, BOUNDARY_SUBSTITUTION) 40 | end 41 | 42 | def multipart_request?(content_type) 43 | return false if content_type.empty? 44 | 45 | MULTIPART_HEADER_MATCHER.match?(content_type) 46 | end 47 | end 48 | --------------------------------------------------------------------------------