Class: LangsmithrbRails::Client

Inherits:
Object
  • Object
show all
Defined in:
lib/langsmithrb_rails/client.rb

Overview

Direct REST client for LangSmith API

Instance Method Summary collapse

Constructor Details

#initialize(api_key: Config[:api_key], api_url: Config[:api_url]) ⇒ Client

Initialize a new LangSmith client

Parameters:

  • api_key (String) (defaults to: Config[:api_key])

    LangSmith API key

  • api_url (String) (defaults to: Config[:api_url])

    LangSmith API URL



14
15
16
17
# File 'lib/langsmithrb_rails/client.rb', line 14

def initialize(api_key: Config[:api_key], api_url: Config[:api_url])
  @api_key = api_key
  @api_url = api_url.chomp("/")
end

Instance Method Details

#create_dataset(name, description: nil) ⇒ Hash

Create a dataset in LangSmith

Parameters:

  • name (String)

    Dataset name

  • description (String) (defaults to: nil)

    Dataset description

Returns:

  • (Hash)

    Response with status and body



65
66
67
68
69
70
71
# File 'lib/langsmithrb_rails/client.rb', line 65

def create_dataset(name, description: nil)
  payload = {
    name: name,
    description: description
  }.compact
  post("/datasets", payload)
end

#create_example(dataset_id, inputs, outputs = nil) ⇒ Hash

Create an example in a dataset

Parameters:

  • dataset_id (String)

    Dataset ID

  • inputs (Hash)

    Example inputs

  • outputs (Hash) (defaults to: nil)

    Example outputs (optional)

Returns:

  • (Hash)

    Response with status and body



93
94
95
96
97
98
99
100
# File 'lib/langsmithrb_rails/client.rb', line 93

def create_example(dataset_id, inputs, outputs = nil)
  payload = {
    dataset_id: dataset_id,
    inputs: inputs,
    outputs: outputs
  }.compact
  post("/examples", payload)
end

#create_feedback(run_id, key, score, value: nil, comment: nil) ⇒ Hash

Create feedback for a run

Parameters:

  • run_id (String)

    Run ID

  • key (String)

    Feedback key

  • score (Float, Integer, Boolean)

    Feedback score

  • value (Hash) (defaults to: nil)

    Additional feedback data (optional)

  • comment (String) (defaults to: nil)

    Feedback comment (optional)

Returns:

  • (Hash)

    Response with status and body



125
126
127
128
129
130
131
132
133
134
135
# File 'lib/langsmithrb_rails/client.rb', line 125

def create_feedback(run_id, key, score, value: nil, comment: nil)
  payload = {
    id: SecureRandom.uuid,
    run_id: run_id,
    key: key,
    score: score,
    value: value,
    comment: comment
  }.compact
  post("/feedback", payload)
end

#create_project(name, description: nil) ⇒ Hash

Create a project in LangSmith

Parameters:

  • name (String)

    Project name

  • description (String) (defaults to: nil)

    Project description (optional)

Returns:

  • (Hash)

    Response with status and body



155
156
157
158
159
160
161
# File 'lib/langsmithrb_rails/client.rb', line 155

def create_project(name, description: nil)
  payload = {
    name: name,
    description: description
  }.compact
  post("/projects", payload)
end

#create_run(payload) ⇒ Hash

Create a new run in LangSmith

Parameters:

  • payload (Hash)

    Run data

Returns:

  • (Hash)

    Response with status and body



22
23
24
# File 'lib/langsmithrb_rails/client.rb', line 22

def create_run(payload)
  post("/runs", payload)
end

#get_dataset(id) ⇒ Hash

Get a dataset by ID

Parameters:

  • id (String)

    Dataset ID

Returns:

  • (Hash)

    Response with status and body



76
77
78
# File 'lib/langsmithrb_rails/client.rb', line 76

def get_dataset(id)
  get("/datasets/#{id}")
end

#get_example(id) ⇒ Hash

Get an example by ID

Parameters:

  • id (String)

    Example ID

Returns:

  • (Hash)

    Response with status and body



105
106
107
# File 'lib/langsmithrb_rails/client.rb', line 105

def get_example(id)
  get("/examples/#{id}")
end

#get_feedback(id) ⇒ Hash

Get feedback by ID

Parameters:

  • id (String)

    Feedback ID

Returns:

  • (Hash)

    Response with status and body



140
141
142
# File 'lib/langsmithrb_rails/client.rb', line 140

def get_feedback(id)
  get("/feedback/#{id}")
end

#get_project(name) ⇒ Hash

Get a project by name

Parameters:

  • name (String)

    Project name

Returns:

  • (Hash)

    Response with status and body



166
167
168
# File 'lib/langsmithrb_rails/client.rb', line 166

def get_project(name)
  get("/projects/#{URI.encode_www_form_component(name)}")
end

#get_run(id) ⇒ Hash

Get a run by ID

Parameters:

  • id (String)

    Run ID

Returns:

  • (Hash)

    Response with status and body



37
38
39
# File 'lib/langsmithrb_rails/client.rb', line 37

def get_run(id)
  get("/runs/#{id}")
end

#list_datasets(limit: 100, offset: 0) ⇒ Hash

List datasets

Parameters:

  • limit (Integer) (defaults to: 100)

    Maximum number of datasets to return

  • offset (Integer) (defaults to: 0)

    Offset for pagination

Returns:

  • (Hash)

    Response with status and body



84
85
86
# File 'lib/langsmithrb_rails/client.rb', line 84

def list_datasets(limit: 100, offset: 0)
  get("/datasets?limit=#{limit}&offset=#{offset}")
end

#list_examples(dataset_id, limit: 100, offset: 0) ⇒ Hash

List examples in a dataset

Parameters:

  • dataset_id (String)

    Dataset ID

  • limit (Integer) (defaults to: 100)

    Maximum number of examples to return

  • offset (Integer) (defaults to: 0)

    Offset for pagination

Returns:

  • (Hash)

    Response with status and body



114
115
116
# File 'lib/langsmithrb_rails/client.rb', line 114

def list_examples(dataset_id, limit: 100, offset: 0)
  get("/datasets/#{dataset_id}/examples?limit=#{limit}&offset=#{offset}")
end

#list_feedback(run_id) ⇒ Hash

List feedback for a run

Parameters:

  • run_id (String)

    Run ID

Returns:

  • (Hash)

    Response with status and body



147
148
149
# File 'lib/langsmithrb_rails/client.rb', line 147

def list_feedback(run_id)
  get("/runs/#{run_id}/feedback")
end

#list_projects(limit: 100, offset: 0) ⇒ Hash

List projects

Parameters:

  • limit (Integer) (defaults to: 100)

    Maximum number of projects to return

  • offset (Integer) (defaults to: 0)

    Offset for pagination

Returns:

  • (Hash)

    Response with status and body



174
175
176
# File 'lib/langsmithrb_rails/client.rb', line 174

def list_projects(limit: 100, offset: 0)
  get("/projects?limit=#{limit}&offset=#{offset}")
end

#list_runs(project_name: nil, trace_id: nil, run_type: nil, limit: 100, offset: 0) ⇒ Hash

List runs with optional filters

Parameters:

  • project_name (String) (defaults to: nil)

    Filter by project name

  • trace_id (String) (defaults to: nil)

    Filter by trace ID

  • run_type (String) (defaults to: nil)

    Filter by run type

  • limit (Integer) (defaults to: 100)

    Maximum number of runs to return

  • offset (Integer) (defaults to: 0)

    Offset for pagination

Returns:

  • (Hash)

    Response with status and body



48
49
50
51
52
53
54
55
56
57
58
59
# File 'lib/langsmithrb_rails/client.rb', line 48

def list_runs(project_name: nil, trace_id: nil, run_type: nil, limit: 100, offset: 0)
  query_params = {
    project_name: project_name,
    trace_id: trace_id,
    run_type: run_type,
    limit: limit,
    offset: offset
  }.compact
  
  query_string = query_params.map { |k, v| "#{k}=#{URI.encode_www_form_component(v.to_s)}" }.join("&")
  get("/runs?#{query_string}")
end

#update_run(id, payload) ⇒ Hash

Update an existing run in LangSmith

Parameters:

  • id (String)

    Run ID

  • payload (Hash)

    Updated run data

Returns:

  • (Hash)

    Response with status and body



30
31
32
# File 'lib/langsmithrb_rails/client.rb', line 30

def update_run(id, payload)
  patch("/runs/#{id}", payload)
end

#upload_file(file_path) ⇒ Hash

Upload a file attachment

Parameters:

  • file_path (String)

    Path to the file

Returns:

  • (Hash)

    Response with status and body containing the file ID



181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
# File 'lib/langsmithrb_rails/client.rb', line 181

def upload_file(file_path)
  uri = URI.parse("#{@api_url}/files")
  
  File.open(file_path, 'rb') do |file|
    boundary = SecureRandom.hex(16)
    
    req = Net::HTTP::Post.new(uri.request_uri)
    req['Authorization'] = "Bearer #{@api_key}" if @api_key
    req['Content-Type'] = "multipart/form-data; boundary=#{boundary}"
    
    body = []
    body << "--#{boundary}\r\n"
    body << "Content-Disposition: form-data; name=\"file\"; filename=\"#{File.basename(file_path)}\"\r\n"
    body << "Content-Type: #{content_type_for_file(file_path)}\r\n\r\n"
    body << file.read
    body << "\r\n--#{boundary}--\r\n"
    
    req.body = body.join
    
    http = Net::HTTP.new(uri.host, uri.port)
    http.use_ssl = uri.scheme == "https"
    http.open_timeout = Config[:open_timeout_seconds]
    http.read_timeout = Config[:timeout_seconds]
    
    res = http.request(req)
    { 
      status: res.code.to_i, 
      body: (JSON.parse(res.body) rescue { "raw" => res.body })
    }
  end
rescue => e
  { status: 0, error: e.message }
end