Class: Langsmith::Client

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

Overview

HTTP client for communicating with the LangSmith API. Handles authentication, retries, and batch operations.

Defined Under Namespace

Classes: APIError

Constant Summary collapse

RETRYABLE_EXCEPTIONS =
[
  Faraday::ConnectionFailed,
  Faraday::TimeoutError
].freeze
RETRY_STATUSES =
[429, 500, 502, 503, 504].freeze

Instance Method Summary collapse

Constructor Details

#initialize(api_key: nil, endpoint: nil, timeout: nil, max_retries: nil) ⇒ Client

Creates a new Client instance.

Parameters:

  • api_key (String, nil) (defaults to: nil)

    API key (defaults to configuration)

  • endpoint (String, nil) (defaults to: nil)

    API endpoint (defaults to configuration)

  • timeout (Integer, nil) (defaults to: nil)

    request timeout in seconds (defaults to configuration)

  • max_retries (Integer, nil) (defaults to: nil)

    max retry attempts (defaults to configuration)



43
44
45
46
47
48
49
# File 'lib/langsmith/client.rb', line 43

def initialize(api_key: nil, endpoint: nil, timeout: nil, max_retries: nil)
  config = Langsmith.configuration
  @api_key = api_key || config.api_key
  @endpoint = endpoint || config.endpoint
  @timeout = timeout || config.timeout
  @max_retries = max_retries || config.max_retries
end

Instance Method Details

#batch_ingest(post_runs: [], patch_runs: [], tenant_id: nil) ⇒ Hash?

Batch create/update runs using pre-serialized hashes. Used by BatchProcessor which snapshots run data at enqueue time.

Parameters:

  • post_runs (Array<Hash>) (defaults to: [])

    run hashes to create

  • patch_runs (Array<Hash>) (defaults to: [])

    run hashes to update

  • tenant_id (String, nil) (defaults to: nil)

    tenant ID for the request

Returns:

  • (Hash, nil)

    API response

Raises:



77
78
79
80
81
82
83
84
85
# File 'lib/langsmith/client.rb', line 77

def batch_ingest(post_runs: [], patch_runs: [], tenant_id: nil)
  return if post_runs.empty? && patch_runs.empty?

  payload = {}
  payload[:post] = post_runs unless post_runs.empty?
  payload[:patch] = patch_runs unless patch_runs.empty?

  post("/runs/batch", payload, tenant_id: tenant_id)
end

#close_experiment(experiment_id:, end_time:, tenant_id: nil) ⇒ Hash

Close an experiment by setting its end time.

Parameters:

  • experiment_id (String)

    the experiment (session) ID

  • end_time (String)

    ISO-8601 end time

  • tenant_id (String, nil) (defaults to: nil)

    tenant ID (falls back to configured tenant_id)

Returns:

  • (Hash)

    the updated experiment object

Raises:



131
132
133
# File 'lib/langsmith/client.rb', line 131

def close_experiment(experiment_id:, end_time:, tenant_id: nil)
  patch("/api/v1/sessions/#{experiment_id}", { end_time: end_time }, tenant_id: resolve_tenant_id(tenant_id))
end

#create_experiment(name:, dataset_id:, description: nil, metadata: nil, tenant_id: nil) ⇒ Hash

Create a new experiment (tracer session) linked to a dataset.

Parameters:

  • name (String)

    experiment name

  • dataset_id (String)

    reference dataset ID

  • description (String, nil) (defaults to: nil)

    optional experiment description

  • metadata (Hash, nil) (defaults to: nil)

    optional metadata (stored as extra)

  • tenant_id (String, nil) (defaults to: nil)

    tenant ID (falls back to configured tenant_id)

Returns:

  • (Hash)

    the created experiment object

Raises:



112
113
114
115
116
117
118
119
120
121
122
# File 'lib/langsmith/client.rb', line 112

def create_experiment(name:, dataset_id:, description: nil, metadata: nil, tenant_id: nil)
  payload = {
    name: name,
    reference_dataset_id: dataset_id,
    start_time: Time.now.utc.iso8601
  }
  payload[:description] = description if description
  payload[:extra] =  if 

  post("/api/v1/sessions", payload, tenant_id: resolve_tenant_id(tenant_id))
end

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

Create feedback (a score/annotation) on a run.

Parameters:

  • run_id (String)

    UUID of the run to attach feedback to

  • key (String)

    metric name (e.g. "correctness")

  • score (Numeric, nil) (defaults to: nil)

    numeric score (typically 0.0-1.0)

  • value (String, nil) (defaults to: nil)

    categorical value (alternative to score)

  • comment (String, nil) (defaults to: nil)

    explanation or reasoning

  • tenant_id (String, nil) (defaults to: nil)

    tenant ID (falls back to configured tenant_id)

Returns:

  • (Hash)

    the created feedback object

Raises:



145
146
147
148
149
150
151
152
# File 'lib/langsmith/client.rb', line 145

def create_feedback(run_id:, key:, score: nil, value: nil, comment: nil, tenant_id: nil)
  payload = { run_id: run_id, key: key }
  payload[:score] = score if score
  payload[:value] = value if value
  payload[:comment] = comment if comment

  post("/api/v1/feedback", payload, tenant_id: resolve_tenant_id(tenant_id))
end

#create_run(run) ⇒ Hash

Create a new run.

Parameters:

  • run (Run)

    the run to create

Returns:

  • (Hash)

    API response

Raises:



56
57
58
# File 'lib/langsmith/client.rb', line 56

def create_run(run)
  post("/runs", run.to_h, tenant_id: run.tenant_id)
end

#list_examples(dataset_id:, limit: nil, offset: nil, tenant_id: nil) ⇒ Array<Hash>

List examples from a LangSmith dataset.

Parameters:

  • dataset_id (String)

    the dataset ID to fetch examples from

  • limit (Integer, nil) (defaults to: nil)

    max number of examples to return (API max: 100)

  • offset (Integer, nil) (defaults to: nil)

    number of examples to skip

  • tenant_id (String, nil) (defaults to: nil)

    tenant ID (falls back to configured tenant_id)

Returns:

  • (Array<Hash>)

    array of example objects

Raises:



95
96
97
98
99
100
101
# File 'lib/langsmith/client.rb', line 95

def list_examples(dataset_id:, limit: nil, offset: nil, tenant_id: nil)
  params = { dataset: dataset_id }
  params[:limit] = limit if limit
  params[:offset] = offset if offset

  get("/api/v1/examples", params: params, tenant_id: resolve_tenant_id(tenant_id))
end

#read_run(run_id:, tenant_id: nil) ⇒ Hash

Read a single run by ID.

Parameters:

  • run_id (String)

    UUID of the run to fetch

  • tenant_id (String, nil) (defaults to: nil)

    tenant ID (falls back to configured tenant_id)

Returns:

  • (Hash)

    the run object (inputs, outputs, child_run_ids, tokens, etc.)

Raises:



160
161
162
# File 'lib/langsmith/client.rb', line 160

def read_run(run_id:, tenant_id: nil)
  get("/api/v1/runs/#{run_id}", tenant_id: resolve_tenant_id(tenant_id))
end

#update_run(run) ⇒ Hash

Update an existing run (typically when it ends).

Parameters:

  • run (Run)

    the run to update

Returns:

  • (Hash)

    API response

Raises:



65
66
67
# File 'lib/langsmith/client.rb', line 65

def update_run(run)
  patch("/runs/#{run.id}", run.to_h, tenant_id: run.tenant_id)
end