Skip to main content

Documentation Index

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

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

Migrating from Raindrop to BentoLabs is a manual port. Function shapes are similar but not identical. Read this table once and translate mechanically.

Translation table

RaindropBentoLabs
import raindrop.analytics as raindropimport bentolabs_sdk.analytics as bento
raindrop.init(write_key)bento.init(api_key=...) (or set BENTOLABS_API_KEY)
raindrop.track_ai(user_id=, event=, input=, output=, model=, convo_id=)bento.track_ai(event=, user_id=, input=, output=, model=, provider=, convo_id=)
interaction = raindrop.begin(...) / interaction.finish(...)interaction = bento.begin(...) / interaction.finish(...)
(no equivalent)with bento.begin(...) as interaction: context-manager form
@raindrop.interaction()@bento.interaction() (also accepts @bento.interaction no-parens)
@raindrop.tool()@bento.tool() (also accepts @bento.tool no-parens)
raindrop.identify(user_id, traits)Removed. BentoLabs does not store user profiles. Delete these calls.
raindrop.track_signal(...)Removed. Not yet implemented in BentoLabs. Delete or stub.
raindrop.flush()bento.flush()

The one new kwarg

Add provider="..." on every track_ai call. Raindrop infers provider from model name; BentoLabs does not.
# Raindrop
raindrop.track_ai(event="chat", model="claude-3-5-sonnet", input="...", output="...")

# BentoLabs
bento.track_ai(
    event="chat",
    model="claude-3-5-sonnet",
    provider="anthropic",
    input="...",
    output="...",
)
Common provider values: openai, anthropic, google, aws_bedrock, azure_openai, cohere, mistral.
Bedrock model IDs are ambiguous on purpose. For model="anthropic.claude-3-sonnet-20240229-v1:0", pass provider="aws_bedrock", not "anthropic".

Behavior differences

BentoLabs stores user_id as a pass-through string only. There is no equivalent of raindrop.identify(user_id, traits). If you relied on Raindrop’s profile data for filtering or aggregation, attach those traits as properties=... on each track_ai call instead.
Both SDKs ship spans to a backend, but BentoLabs detaches track_ai calls from any outer OTel context so they don’t accidentally get parented to a customer’s FastAPI/Django span. Open a trajectory with bento.begin(...) if you want subsequent track_ai calls to nest under it.
BentoLabs preserves int / float / bool / str types in properties so the dashboard can filter experiment_id > 100. Dicts and mixed arrays fall back to JSON-string. See Properties.
BentoLabs enforces reverse-open-order finish on nested trajectories. Out-of-order interaction.finish() raises RuntimeError. The context-manager form (with bento.begin(...) as i:) guarantees correct nesting.

Setup checklist

1

Install the new SDK

pip install bentolabs-sdk
pip uninstall raindrop  # once migration is complete
2

Update environment variables

Replace RAINDROP_WRITE_KEY (or equivalent) with:
export BENTOLABS_API_KEY="bl_pk_..."
3

Find-and-replace imports

grep -rn "import raindrop" src/
Update each import per the table above.
4

Add provider= to track_ai calls

grep -rn "track_ai" src/
Every call needs provider="..." now.
5

Delete identify() and track_signal() calls

They have no BentoLabs equivalent. Remove them or stub if you still need a no-op.
6

Verify in your dashboard

Run one end-to-end flow and confirm the trace appears in platform.bentolabs.ai with the right user, conversation, model, and provider tags.