bitfab 0.23.7 → 0.23.8

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: fb51dda5edc6e1c4cf5cc439c766b52dad303f3838e5aae80b03cd521fa34d80
4
- data.tar.gz: a1b21474b8d32f22ed6a17e2ef65d865549fb23d7a25de9cbdfd03e64eb385a5
3
+ metadata.gz: 342b5de3b40edd60f060465123f21d1c5338063340b34ac7bb7067c7baedfe55
4
+ data.tar.gz: 2f73bec442f3570efe78253d28733942e00b46c03a26ce2731a72e778cd6d79f
5
5
  SHA512:
6
- metadata.gz: 9dfb2cb3e7eb9f845453f58e807c6150e8136c43fdc5e3aedfb65d89b61027772831775f0a7854559a89be4ddeae7084b6c26195ac165365083309429834057c
7
- data.tar.gz: '0785322f709aa5dbe67454f7ca743e5def622d9ed6981d4f62b5c222e1e730270bfc727805f7198a4a139d54ea966dc80df194107f1e90b575638f90e7f7a02e'
6
+ metadata.gz: c76023257bcdd959cb49d6881faf05e85013b2d30c02826fd57a2a2aa8a72d72d7f8f10716f9f4b2d850a84dfb4a6ef7151077b88f43e2e1e7bd5b4c81ed23ff
7
+ data.tar.gz: 37fb2e1215527c780253dd35e10e4ff01d735336d068d5d8ac16a75d4fcc17e1749f7718cf8ffc550e965a27a9f0ee8fb49b2b847724c10a1ae031f0f1470574
data/lib/bitfab/client.rb CHANGED
@@ -13,6 +13,7 @@ require_relative "warn_once"
13
13
  module Bitfab
14
14
  class Client
15
15
  SPAN_TYPES = %w[llm agent function guardrail handoff custom].freeze
16
+ UUID_PATTERN = /\A[0-9a-f]{8}-[0-9a-f]{4}-[1-8][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}\z/i
16
17
 
17
18
  # Sentinel returned by check_mock_replay when this span should run real
18
19
  # code (no mock active, wrong strategy, or no matching historical entry).
@@ -115,6 +116,26 @@ module Bitfab
115
116
  BitfabFunction.new(self, trace_function_key)
116
117
  end
117
118
 
119
+ # Fetch one persisted span without loading the full trace.
120
+ # Exactly one of id or name is required. Name lookups return the last
121
+ # matching span by default; occurrence also accepts "first" or a zero-based
122
+ # Integer index.
123
+ def get_trace_span(trace_id, id: nil, name: nil, occurrence: "last")
124
+ validate_trace_id(trace_id)
125
+ raise ArgumentError, "Provide exactly one of id or name" if id.nil? == name.nil?
126
+ validate_span_id(id) unless id.nil?
127
+ if !name.nil? && (!name.is_a?(String) || name.empty?)
128
+ raise ArgumentError, "name must be a non-empty string"
129
+ end
130
+
131
+ valid_occurrence = %w[first last].include?(occurrence) || (occurrence.is_a?(Integer) && occurrence >= 0)
132
+ unless valid_occurrence
133
+ raise ArgumentError, 'occurrence must be "first", "last", or a non-negative integer'
134
+ end
135
+
136
+ @http_client.get_trace_span(trace_id, id:, name:, occurrence:)
137
+ end
138
+
118
139
  # Execute a block inside a span context, sending trace data on completion.
119
140
  # Called by Traceable, not intended for direct use.
120
141
  def execute_span(trace_function_key:, span_name:, span_type:, function_name:, args:, kwargs:,
@@ -343,6 +364,14 @@ module Bitfab
343
364
 
344
365
  private
345
366
 
367
+ def validate_trace_id(trace_id)
368
+ raise ArgumentError, "trace_id must be a valid Bitfab trace ID" unless trace_id.is_a?(String) && UUID_PATTERN.match?(trace_id)
369
+ end
370
+
371
+ def validate_span_id(id)
372
+ raise ArgumentError, "id must be a valid Bitfab span ID" unless id.is_a?(String) && UUID_PATTERN.match?(id)
373
+ end
374
+
346
375
  # Resolve the API key lazily, the first time a span actually needs it.
347
376
  #
348
377
  # The key is intentionally NOT read at construction: a client built when a
@@ -462,6 +491,7 @@ module Bitfab
462
491
  end
463
492
 
464
493
  payload = {
494
+ "id" => trace_id,
465
495
  "type" => "sdk-function",
466
496
  "source" => "ruby-sdk-function",
467
497
  "traceFunctionKey" => trace_function_key,
@@ -540,6 +570,8 @@ module Bitfab
540
570
  raw_span["input_source_span_id"] = input_source_span_id if input_source_span_id
541
571
 
542
572
  payload = {
573
+ "id" => span_id,
574
+ "traceId" => trace_id,
543
575
  "type" => "sdk-function",
544
576
  "source" => "ruby-sdk-function",
545
577
  "sourceTraceId" => trace_id,
@@ -80,7 +80,7 @@ module Bitfab
80
80
  http.open_timeout = request_timeout
81
81
  http.read_timeout = request_timeout
82
82
 
83
- req = Net::HTTP::Get.new(uri.path, headers)
83
+ req = Net::HTTP::Get.new(uri.request_uri, headers)
84
84
  response = http.request(req)
85
85
 
86
86
  unless response.is_a?(Net::HTTPSuccess)
@@ -140,6 +140,19 @@ module Bitfab
140
140
  get("/api/sdk/externalSpans/#{span_id}", timeout: 30)
141
141
  end
142
142
 
143
+ def get_trace_span(trace_id, id: nil, name: nil, occurrence: "last")
144
+ query = if id
145
+ {id:}
146
+ else
147
+ {name:, occurrence: occurrence.to_s}
148
+ end
149
+ encoded_trace_id = URI.encode_www_form_component(trace_id)
150
+ get(
151
+ "/api/sdk/traces/#{encoded_trace_id}/span?#{URI.encode_www_form(query)}",
152
+ timeout: 30
153
+ )["span"]
154
+ end
155
+
143
156
  # Fetch the span tree rooted at an external span. Blocking GET request.
144
157
  # Used by replay when a mock strategy is active so child spans can be
145
158
  # matched against their historical outputs.
@@ -7,6 +7,11 @@ module Bitfab
7
7
  @span_state = span_state
8
8
  end
9
9
 
10
+ # The Bitfab ID for the current span.
11
+ def id
12
+ @span_state[:span_id]
13
+ end
14
+
10
15
  # The trace ID for the current span.
11
16
  def trace_id
12
17
  @span_state[:trace_id]
@@ -1,5 +1,5 @@
1
1
  # frozen_string_literal: true
2
2
 
3
3
  module Bitfab
4
- VERSION = "0.23.7"
4
+ VERSION = "0.23.8"
5
5
  end
data/lib/bitfab.rb CHANGED
@@ -18,6 +18,10 @@ module Bitfab
18
18
  # No-op span handle returned when outside a span context.
19
19
  # All methods do nothing, preventing crashes when called outside traced code.
20
20
  class NoOpCurrentSpan
21
+ def id
22
+ ""
23
+ end
24
+
21
25
  def trace_id
22
26
  ""
23
27
  end
metadata CHANGED
@@ -1,7 +1,7 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: bitfab
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.23.7
4
+ version: 0.23.8
5
5
  platform: ruby
6
6
  authors:
7
7
  - Harvest Team