Skip to main content

Migrating from v0 to v1

Basalt v1 is a major update that introduces a unified observability system based on OpenTelemetry and a more consistent SDK API. This guide covers the main changes you need to make when upgrading.

Key Changes at a Glance

Featurev0 (Legacy)v1 (Current)
Prompts APIbasalt.promptbasalt.prompts
Tracingbasalt.monitor / generation.end()start_observe / observe
IdentityManual in log or traceAutomatic via context propagation
Error HandlingError as value (error, result = ...)Standard Python Exceptions

1. Prompts API

The prompts API has been renamed from prompt to prompts (plural) and now distinguishes between synchronous and asynchronous calls.
# Always async, returns a tuple
error, prompt, generation = await basalt.prompt.get('my-slug')

2. Observability & Tracing

The biggest change in v1 is the move to a unified observability model. Instead of manually logging generations or ending traces, you now use decorators or context managers.

Basic Tracing

error, prompt, generation = await basalt.prompt.get('my-slug')
output = call_llm(prompt.text)
generation.end(output)

3. Identity Tracking

In v0, you had to pass user and organization information to every log or trace call. In v1, you set it once at the start of your trace, and it flows automatically to all nested spans.
basalt.monitor.log(
    event="llm_call",
    user_id="user_123",
    org_id="org_456",
    ...
)

4. Error Handling (Exceptions vs Error as Value)

In v0, the SDK followed an “error as value” pattern (similar to Go), where most methods returned a tuple containing an error object and the result. In v1, the SDK uses standard Python exceptions for a more idiomatic experience.
# Methods return (error, result, ...)
error, prompt, generation = await basalt.prompt.get('my-slug')

if error:
    print(f"Error: {error.message}")
else:
    print(prompt.text)