Use this file to discover all available pages before exploring further.
The Bitfab Go SDK captures your AI function calls to automatically generate evaluations. Re-run your prompts with different models, parameters, and inputs to iterate faster.
Framework-native adapters (LangGraph, OpenAI Agents, BAML, Claude Agent SDK) are not yet available for Go. See Frameworks overview for current coverage. Instrument Go code manually via client.Span or client.Start.
Copy this prompt into your coding agent (tested with Cursor and Claude Code using Sonnet 4.5):
Modify existing Go code to add Bitfab tracing.Do NOT browse or web search. Use ONLY the API described below.Bitfab Go SDK (authoritative excerpt):- Install: `go get github.com/Project-White-Rabbit/bitfab-go`- Init: import bitfab "github.com/Project-White-Rabbit/bitfab-go" client := bitfab.NewClient(os.Getenv("BITFAB_API_KEY"))- Start/End style (PREFERRED for existing functions): func myFunc(ctx context.Context, arg1 string) (Result, error) { ctx, span := client.Start(ctx, "<trace_function_key>", "<SpanName>", bitfab.WithType("function")) defer span.End() span.SetInput(arg1) result, err := doWork(ctx, arg1) if err != nil { span.SetError(err) return Result{}, err } span.SetOutput(result) return result, nil }- Closure style (for inline code): result, err := client.Span(ctx, "<trace_function_key>", func(ctx context.Context) (any, error) { return doWork(ctx), nil }, bitfab.WithName("<SpanName>"), bitfab.WithType("function"), bitfab.WithInput(args...))- Fluent API: fn := client.GetFunction("<trace_function_key>") ctx, span := fn.Start(ctx, "<SpanName>", bitfab.WithType("function")) defer span.End()- Span types: "llm", "agent", "function", "guardrail", "handoff", "custom"- Always pass ctx from Start or Span callback into nested calls for parent-child linking.- Always call client.FlushTraces(5 * time.Second) before program exit.Task:1) Ensure the bitfab-go module is added (`go get github.com/Project-White-Rabbit/bitfab-go`).2) Ensure a client is initialized with the API key.3) Read the codebase and identify ALL AI workflows (LLM calls, agent runs, AI-driven decisions).4) Present me with a numbered list of workflows you found. For each, describe: - What it does - Why it's worth instrumenting — what visibility tracing gives you into each step5) After I choose which workflow(s) to instrument: - Add Start/End at the top of each function (preferred) or wrap in Span closure - Use SetInput/SetOutput/SetError to capture data - Instrument intermediate steps (not just the final output) so each trace has enough context to diagnose issues - Pass `ctx` through for nested span support6) Do not change function signature, behavior, or return value. Minimal diff.Output:- First: your numbered list of workflows with why each is worth instrumenting- After my selection: minimal diffs for go.mod and the instrumented functions
// Default (production URL)client := bitfab.NewClient(apiKey)// Custom service URLclient := bitfab.NewClient(apiKey, bitfab.WithServiceURL("http://localhost:4000"))// Disable tracing (functions still execute, but no spans are sent)client := bitfab.NewClient(apiKey, bitfab.WithEnabled(false))
Missing API key doesn’t crash. If the API key is missing, empty, or whitespace-only, the SDK automatically disables tracing and logs a warning. All instrumented functions still execute normally — no spans are sent, no errors are thrown. You don’t need any conditional logic around the API key.
For projects with instrumented functions spread across multiple files, create a dedicated package that initializes the client and exposes a function handle. Import it wherever you need to instrument.
// pkg/tracing/tracing.go — single source of truthpackage tracingimport ( "os" bitfab "github.com/Project-White-Rabbit/bitfab-go")var Client = bitfab.NewClient(os.Getenv("BITFAB_API_KEY"))var OrderService = Client.GetFunction("order-processing")
Use span.AddContext() on an ActiveSpan (Start/End style) to attach contextual key-value pairs at runtime — useful when context depends on computed values:
Use span.SetPrompt() on an ActiveSpan (Start/End style) to set the prompt string on the current span. This is stored in span_data.prompt and is useful for capturing the exact prompt text sent to an LLM:
The last SetPrompt call wins — it overwrites any previously set prompt on the span. Calling SetPrompt outside a span context is a no-op (it never crashes).
Use bitfab.GetCurrentTrace(ctx) to set context that applies to the entire trace (all spans within a single execution). This is useful for grouping traces by session or attaching trace-level metadata:
result, err := client.Span(ctx, "order-processing", func(ctx context.Context) (any, error) { trace := bitfab.GetCurrentTrace(ctx) // Set session ID (stored as database column, filterable in dashboard) trace.SetSessionID("session-123") // Set trace metadata (stored in raw trace data) trace.SetMetadata(map[string]any{"region": "us-west-2", "environment": "production"}) // Add context entries (stored as key-value pairs, accumulates across calls) trace.AddContext(map[string]any{"workflow": "checkout-flow", "batch_id": "batch-2024-01"}) return map[string]any{"status": "completed"}, nil}, bitfab.WithName("ProcessOrder"), bitfab.WithType("function"))
SetSessionID(id) — Groups traces by user session. Stored as a database column for efficient filtering.
SetMetadata(map) — Arbitrary key-value metadata on the trace. Merges with existing metadata.
AddContext(map) — Key-value context entries. Accumulates across multiple calls.
Errors are captured in the span and returned to the caller:
result, err := client.Span(ctx, "risky-service", func(ctx context.Context) (any, error) { return nil, errors.New("something went wrong")}, bitfab.WithName("RiskyOperation"), bitfab.WithType("function"))// err contains "something went wrong"// The span records the error message and timing