Class: LLM::OpenAI::VectorStores

Inherits:
Object
  • Object
show all
Defined in:
lib/llm/providers/openai/vector_stores.rb

Overview

The LLM::OpenAI::VectorStores class provides an interface for OpenAI's vector stores API.

Examples:

llm = LLM.openai(key: ENV["OPENAI_SECRET"])
files = %w(foo.pdf bar.pdf).map { llm.files.create(file: _1) }
store = llm.vector_stores.create_and_poll(name: "PDF Store", file_ids: files.map(&:id))
print "[-] store is ready", "\n"
chunks = llm.vector_stores.search(vector: store, query: "What is Ruby?")
chunks.each { |chunk| puts chunk }

Constant Summary collapse

PollError =
Class.new(LLM::Error)

Instance Method Summary collapse

Constructor Details

#initialize(provider) ⇒ VectorStores

Returns a new instance of VectorStores.

Parameters:



24
25
26
# File 'lib/llm/providers/openai/vector_stores.rb', line 24

def initialize(provider)
  @provider = provider
end

Instance Method Details

#add_file(vector:, file:, attributes: nil, **params) ⇒ LLM::Response Also known as: create_file

Add a file to a vector store

Parameters:

  • vector (String, #id)

    The ID of the vector store

  • file (String, #id)

    The ID of the file to add

  • attributes (Hash) (defaults to: nil)

    Attributes to associate with the file (optional)

  • params (Hash)

    Other parameters (see OpenAI docs)

Returns:

See Also:



145
146
147
148
149
150
151
152
# File 'lib/llm/providers/openai/vector_stores.rb', line 145

def add_file(vector:, file:, attributes: nil, **params)
  vector_id = vector.respond_to?(:id) ? vector.id : vector
  file_id = file.respond_to?(:id) ? file.id : file
  req = Net::HTTP::Post.new("/v1/vector_stores/#{vector_id}/files", headers)
  req.body = LLM.json.dump(params.merge({file_id:, attributes:}).compact)
  res = execute(request: req)
  LLM::Response.new(res)
end

#add_file_and_poll(vector:, file:, interval: INTERVAL, **rest) ⇒ LLM::Response Also known as: create_file_and_poll

Add a file to a vector store and poll until its status is "completed"

Parameters:

  • interval (Float) (defaults to: INTERVAL)

    The interval between polling attempts (seconds)

  • vector (String, #id)

    The ID of the vector store

  • file (String, #id)

    The ID of the file to add

  • attributes (Hash)

    Attributes to associate with the file (optional)

  • params (Hash)

    Other parameters (see OpenAI docs)

Returns:



160
161
162
# File 'lib/llm/providers/openai/vector_stores.rb', line 160

def add_file_and_poll(vector:, file:, interval: INTERVAL, **rest)
  poll(vector:, interval:, file: add_file(vector:, file:, **rest))
end

#all(**params) ⇒ LLM::Response

List all vector stores

Parameters:

  • params (Hash)

    Other parameters (see OpenAI docs)

Returns:



32
33
34
35
36
37
# File 'lib/llm/providers/openai/vector_stores.rb', line 32

def all(**params)
  query = URI.encode_www_form(params)
  req = Net::HTTP::Get.new("/v1/vector_stores?#{query}", headers)
  res = execute(request: req)
  ResponseAdapter.adapt(res, type: :enumerable)
end

#all_files(vector:, **params) ⇒ LLM::Response

List all files in a vector store

Parameters:

  • vector (String, #id)

    The ID of the vector store

  • params (Hash)

    Other parameters (see OpenAI docs)

Returns:

See Also:



128
129
130
131
132
133
134
# File 'lib/llm/providers/openai/vector_stores.rb', line 128

def all_files(vector:, **params)
  vector_id = vector.respond_to?(:id) ? vector.id : vector
  query = URI.encode_www_form(params)
  req = Net::HTTP::Get.new("/v1/vector_stores/#{vector_id}/files?#{query}", headers)
  res = execute(request: req)
  ResponseAdapter.adapt(res, type: :enumerable)
end

#create(name:, file_ids: nil, **params) ⇒ LLM::Response

Create a vector store

Parameters:

  • name (String)

    The name of the vector store

  • file_ids (Array<String>) (defaults to: nil)

    The IDs of the files to include in the vector store

  • params (Hash)

    Other parameters (see OpenAI docs)

Returns:

See Also:



47
48
49
50
51
52
# File 'lib/llm/providers/openai/vector_stores.rb', line 47

def create(name:, file_ids: nil, **params)
  req = Net::HTTP::Post.new("/v1/vector_stores", headers)
  req.body = LLM.json.dump(params.merge({name:, file_ids:}).compact)
  res = execute(request: req)
  LLM::Response.new(res)
end

#create_and_poll(interval: INTERVAL, **rest) ⇒ LLM::Response

Create a vector store and poll until its status is "completed"

Parameters:

  • interval (Float) (defaults to: INTERVAL)

    The interval between polling attempts (seconds)

  • name (String)

    The name of the vector store

  • file_ids (Array<String>)

    The IDs of the files to include in the vector store

  • params (Hash)

    Other parameters (see OpenAI docs)

Returns:



59
60
61
# File 'lib/llm/providers/openai/vector_stores.rb', line 59

def create_and_poll(interval: INTERVAL, **rest)
  poll(interval:, vector: create(**rest))
end

#delete(vector:) ⇒ LLM::Response

Delete a vector store

Parameters:

  • vector (String, #id)

    The ID of the vector store

Returns:

See Also:



98
99
100
101
102
103
# File 'lib/llm/providers/openai/vector_stores.rb', line 98

def delete(vector:)
  vector_id = vector.respond_to?(:id) ? vector.id : vector
  req = Net::HTTP::Delete.new("/v1/vector_stores/#{vector_id}", headers)
  res = execute(request: req)
  LLM::Response.new(res)
end

#delete_file(vector:, file:) ⇒ LLM::Response

Delete a file from a vector store

Parameters:

  • vector (String, #id)

    The ID of the vector store

  • file (String, #id)

    The ID of the file to delete

Returns:

See Also:



206
207
208
209
210
211
212
# File 'lib/llm/providers/openai/vector_stores.rb', line 206

def delete_file(vector:, file:)
  vector_id = vector.respond_to?(:id) ? vector.id : vector
  file_id = file.respond_to?(:id) ? file.id : file
  req = Net::HTTP::Delete.new("/v1/vector_stores/#{vector_id}/files/#{file_id}", headers)
  res = execute(request: req)
  LLM::Response.new(res)
end

#get(vector:) ⇒ LLM::Response

Get a vector store

Parameters:

  • vector (String, #id)

    The ID of the vector store

Returns:

See Also:



69
70
71
72
73
74
# File 'lib/llm/providers/openai/vector_stores.rb', line 69

def get(vector:)
  vector_id = vector.respond_to?(:id) ? vector.id : vector
  req = Net::HTTP::Get.new("/v1/vector_stores/#{vector_id}", headers)
  res = execute(request: req)
  LLM::Response.new(res)
end

#get_file(vector:, file:, **params) ⇒ LLM::Response

Get a file from a vector store

Parameters:

  • vector (String, #id)

    The ID of the vector store

  • file (String, #id)

    The ID of the file to retrieve

Returns:

See Also:



190
191
192
193
194
195
196
197
# File 'lib/llm/providers/openai/vector_stores.rb', line 190

def get_file(vector:, file:, **params)
  vector_id = vector.respond_to?(:id) ? vector.id : vector
  file_id = file.respond_to?(:id) ? file.id : file
  query = URI.encode_www_form(params)
  req = Net::HTTP::Get.new("/v1/vector_stores/#{vector_id}/files/#{file_id}?#{query}", headers)
  res = execute(request: req)
  LLM::Response.new(res)
end

#modify(vector:, name: nil, **params) ⇒ LLM::Response

Modify an existing vector store

Parameters:

  • vector (String, #id)

    The ID of the vector store

  • name (String) (defaults to: nil)

    The new name of the vector store

  • params (Hash)

    Other parameters (see OpenAI docs)

Returns:

See Also:



84
85
86
87
88
89
90
# File 'lib/llm/providers/openai/vector_stores.rb', line 84

def modify(vector:, name: nil, **params)
  vector_id = vector.respond_to?(:id) ? vector.id : vector
  req = Net::HTTP::Post.new("/v1/vector_stores/#{vector_id}", headers)
  req.body = LLM.json.dump(params.merge({name:}).compact)
  res = execute(request: req)
  LLM::Response.new(res)
end

#poll(vector:, file: nil, attempts: 0, max: 50, interval: INTERVAL) ⇒ LLM::Response

Poll a vector store or file until its status is "completed"

Parameters:

  • vector (String, #id)

    The ID of the vector store

  • file (String, #id) (defaults to: nil)

    The file to poll (optional)

  • attempts (Integer) (defaults to: 0)

    The current number of attempts (default: 0)

  • max (Integer) (defaults to: 50)

    The maximum number of iterations (default: 50)

  • interval (Float) (defaults to: INTERVAL)

    The interval between polling attempts (seconds)

Returns:

Raises:

  • (LLM::PollError)

    When the maximum number of iterations is reached



223
224
225
226
227
228
229
230
231
232
233
234
235
236
# File 'lib/llm/providers/openai/vector_stores.rb', line 223

def poll(vector:, file: nil, attempts: 0, max: 50, interval: INTERVAL)
  target = file || vector
  if attempts == max
    raise LLM::PollError, "'#{target.id}' has status '#{target.status}' after #{max} attempts"
  elsif target.status == "expired"
    raise LLM::PollError, "#{target.id}' has expired"
  elsif target.status != "completed"
    file ? (file = get_file(vector:, file:)) : (vector = get(vector:))
    sleep(interval * (2**attempts)) unless interval.zero?
    poll(vector:, file:, attempts: attempts + 1, max:, interval:)
  else
    target
  end
end

#search(vector:, query:, **params) ⇒ LLM::Response

Search a vector store

Parameters:

  • vector (String, #id)

    The ID of the vector store

  • query (String)

    The query to search for

  • params (Hash)

    Other parameters (see OpenAI docs)

Returns:

See Also:



113
114
115
116
117
118
119
# File 'lib/llm/providers/openai/vector_stores.rb', line 113

def search(vector:, query:, **params)
  vector_id = vector.respond_to?(:id) ? vector.id : vector
  req = Net::HTTP::Post.new("/v1/vector_stores/#{vector_id}/search", headers)
  req.body = LLM.json.dump(params.merge({query:}).compact)
  res = execute(request: req)
  ResponseAdapter.adapt(res, type: :enumerable)
end

#update_file(vector:, file:, attributes:, **params) ⇒ LLM::Response

Update a file in a vector store

Parameters:

  • vector (String, #id)

    The ID of the vector store

  • file (String, #id)

    The ID of the file to update

  • attributes (Hash)

    Attributes to associate with the file

  • params (Hash)

    Other parameters (see OpenAI docs)

Returns:

See Also:



174
175
176
177
178
179
180
181
# File 'lib/llm/providers/openai/vector_stores.rb', line 174

def update_file(vector:, file:, attributes:, **params)
  vector_id = vector.respond_to?(:id) ? vector.id : vector
  file_id = file.respond_to?(:id) ? file.id : file
  req = Net::HTTP::Post.new("/v1/vector_stores/#{vector_id}/files/#{file_id}", headers)
  req.body = LLM.json.dump(params.merge({attributes:}).compact)
  res = execute(request: req)
  LLM::Response.new(res)
end