Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.bitfab.ai/llms.txt

Use this file to discover all available pages before exploring further.

Gem: bitfab. Ruby ≥ 3.1. Uses a global singleton client pattern (Bitfab.configure / Bitfab.client).

Framework Integrations

No framework-native adapters are shipped for Ruby yet. Instrument Ruby code manually via Bitfab::Traceable / Bitfab.span — see the Ruby SDK guide. Framework coverage status: Frameworks overview.

Module Layout

Bitfab                   # top-level module & singleton facade
Bitfab::Client           # the underlying client class
Bitfab::BitfabFunction   # fluent wrapper bound to one trace_function_key
Bitfab::Traceable        # mixin for declarative span tracing
Bitfab::CurrentSpan      # span handle
Bitfab::CurrentTrace     # trace handle
Bitfab::NoOpCurrentSpan  # returned outside a span context
Bitfab::NoOpCurrentTrace # returned outside a span context
Bitfab::Replay           # replay orchestration (internal)
Bitfab::ReplayContext    # thread-local replay context (internal)
Bitfab::SpanContext      # thread-local span stack (internal)
Bitfab::TraceState       # trace state storage (internal)
Bitfab::MOCK_STRATEGIES  # %w[none all marked]

Module-Level API

Bitfab.configure(api_key:, service_url: nil, enabled: true)

Creates the global client. Subsequent calls replace it.
ParamTypeDefault
api_key:String
service_url:String, nil"https://bitfab.ai"
enabled:Booleantrue
Empty/whitespace api_key prints a warning and sets enabled = false.

Bitfab.client

Returns the configured Bitfab::Client. Raises RuntimeError("Bitfab not configured...") if configure has not been called.

Bitfab.reset!

Resets the global client to nil. Intended for tests.

Bitfab.current_span

Returns the active CurrentSpan, or Bitfab::NO_OP_SPAN outside a span context.

Bitfab.current_trace

Returns the active CurrentTrace, or Bitfab::NO_OP_TRACE outside a span context.

class Bitfab::Client

SPAN_TYPES

Bitfab::Client::SPAN_TYPES  # => %w[llm agent function guardrail handoff custom]

attr_reader :api_key, :service_url, :enabled

initialize(api_key:, service_url: nil, enabled: true)

Same semantics as Bitfab.configure.

replay(receiver, method_name, trace_function_key:, limit: 5, trace_ids: nil, max_concurrency: 10, code_change_description: nil, code_change_files: nil, mock: "none")

ParamTypeDescription
receiverObject or ClassInstance for instance methods; class for class methods
method_nameSymbolMethod to replay
trace_function_key:StringTrace function key for this method
limit:IntegerMax traces to replay (default 5)
trace_ids:Array<String>, nilOptional explicit trace IDs
max_concurrency:Integer, nilMax parallel threads (default 10; nil = unlimited)
code_change_description:String, nilOptional rationale for the code change being tested (stored on the experiment)
code_change_files:Array<Hash>, nilOptional list of edited files, each { path:, before:, after: }
mock:StringMock strategy for child spans: "none" (default), "all", or "marked". Raises ArgumentError on any other value.
Returns: Hash with keys :items, :test_run_id, :test_run_url. Each item has :input, :result, :original_output, :error, :duration_ms (Integer, nil), :tokens ({ input:, output:, cached:, total: } or nil), and :model (String, nil). The metric fields come from the historical trace the item replays. Mock strategies:
  • "none" — every child span runs real code (default).
  • "all" — every child span returns its historical output; real code is not executed.
  • "marked" — only child spans declared with mock_on_replay: true return historical output. Falls through to real execution when no historical entry matches.
Repeated calls to the same trace_function_key are distinguished by call order (step:0, step:1, …). The per-key counter advances on every non-root child invocation — including unmarked ones — so a marked sibling following an unmarked sibling lines up with the right historical entry.

get_function(trace_function_key)

Returns a Bitfab::BitfabFunction bound to trace_function_key. Mirrors client.get_function in the Python SDK and client.getFunction in TypeScript.

execute_span(...) (internal)

Called by Traceable. Not intended for direct use.

class Bitfab::BitfabFunction

Fluent wrapper bound to a single trace_function_key, returned by Bitfab::Client#get_function.

attr_reader :trace_function_key

wrap(klass, method_name, name: nil, type: "custom", mock_on_replay: false)

Wraps method_name on klass with span tracing under the bound trace_function_key. Delegates to Bitfab::Traceable.wrap.

module Bitfab::Traceable

Mixin for declarative instance-method tracing.

include Bitfab::Traceable

Extends the including class with ClassMethods below.

Class Methods (after include)

bitfab_function(key)

Sets the default trace_function_key for all bitfab_span declarations in this class.

bitfab_span(method_name, trace_function_key: nil, name: nil, type: "custom", mock_on_replay: false)

Wraps method_name with span tracing.
ParamTypeDefault
method_nameSymbolrequired
trace_function_key:String, nilfalls back to the class-level bitfab_function key
name:String, nildefaults to method_name.to_s
type:String"custom" — one of SPAN_TYPES
mock_on_replay:Booleanfalse — when true, replay invoked with mock: "marked" returns this span’s historical output
Supports three call styles:
  1. Before def — registered via method_added hook, wrapped when method is defined
  2. Inlinebitfab_span def foo ... end, type: "function" (Ruby’s def returns :foo)
  3. After def — wraps immediately if the method already exists
Raises RuntimeError if no trace_function_key is provided and no class-level bitfab_function was set.

Module-Level Wrapping

Bitfab::Traceable.wrap(klass, method_name, trace_function_key:, name: nil, type: "custom", mock_on_replay: false)

Wraps a method on a class you do not own. Uses Module#prepend.
ParamType
klassClass or Module
method_nameSymbol
trace_function_key:String
name:String, nil
type:String
mock_on_replay:Boolean

class Bitfab::CurrentSpan

def trace_id  # => String
def add_context(context)  # Hash → appends one entry; ignores non-Hash; never raises
def set_prompt(prompt)    # String → overwrites; ignores non-String; never raises

class Bitfab::CurrentTrace

def set_session_id(session_id)  # String
def set_metadata(metadata)      # Hash → shallow-merge, later keys win
def add_context(context)        # Hash → appends entry
All methods swallow exceptions internally; they never raise.

class Bitfab::NoOpCurrentSpan / NoOpCurrentTrace

Singleton instances exposed as Bitfab::NO_OP_SPAN and Bitfab::NO_OP_TRACE. All methods are no-ops. trace_id returns "".

Thread & Concurrency Model

  • Span stack is stored in Thread.current[:__bitfab_span_stack]not propagated to child threads automatically
  • Trace state is stored in a mutex-protected module-level hash (Bitfab::TraceState) keyed by trace_id
  • Span HTTP sends run in background threads; the client tracks pending threads per trace

Error Behavior Summary

SituationBehavior
Empty api_keyWarning via warn, enabled forced to false
bitfab_span method raisesSpan records error, exception re-raised
add_context / set_prompt with invalid inputSilently ignored. Never raises
Span transport failureSwallowed. Host app never crashes
Bitfab.client before configureRuntimeError("Bitfab not configured...")
bitfab_span without trace_function_keyRuntimeError