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 +4 -4
- data/lib/bitfab/client.rb +32 -0
- data/lib/bitfab/http_client.rb +14 -1
- data/lib/bitfab/span_context.rb +5 -0
- data/lib/bitfab/version.rb +1 -1
- data/lib/bitfab.rb +4 -0
- metadata +1 -1
checksums.yaml
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
---
|
|
2
2
|
SHA256:
|
|
3
|
-
metadata.gz:
|
|
4
|
-
data.tar.gz:
|
|
3
|
+
metadata.gz: 342b5de3b40edd60f060465123f21d1c5338063340b34ac7bb7067c7baedfe55
|
|
4
|
+
data.tar.gz: 2f73bec442f3570efe78253d28733942e00b46c03a26ce2731a72e778cd6d79f
|
|
5
5
|
SHA512:
|
|
6
|
-
metadata.gz:
|
|
7
|
-
data.tar.gz:
|
|
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,
|
data/lib/bitfab/http_client.rb
CHANGED
|
@@ -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.
|
|
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.
|
data/lib/bitfab/span_context.rb
CHANGED
data/lib/bitfab/version.rb
CHANGED
data/lib/bitfab.rb
CHANGED