2.3 KiB
2.3 KiB
Package: dirigent_langfuse
Phase 4 stream backend that mirrors BusEvents to a Langfuse ingestion endpoint.
Scope
LangfuseFactoryregistered askind = "langfuse"in theStreamFactoryRegistry.LangfuseStreamimplementsSessionStream:- Maps each
BusEventviamapping::bus_event_to_items. - Buffers up to 32 items per flush; flushes eagerly when full and on shutdown.
- POSTs
{host}/api/public/ingestionwith basic-auth(public_key, secret_key).
- Maps each
File map
src/lib.rs— public API:LangfuseStream,LangfuseConfig,LangfuseFactory.src/client.rs—LangfuseClient(reqwest wrapper with retry) and theLangfuseStreamimplementation.src/mapping.rs—bus_event_to_itemsmapping.src/factory.rs—StreamFactoryimpl.
Event → ingestion mapping
| BusEvent variant | Langfuse item |
|---|---|
SessionCreated |
trace-create (id = scroll_id) |
MessageStarted |
generation-create |
MessageCompleted |
generation-update with output |
SessionUpdate (non-tool) |
skipped |
| All others | skipped |
Events without a bound scroll_id (no late-bind hit) are dropped — the
implementation does NOT buffer pending events keyed by connector_id /
native_session_id in Phase 4. If buffering is needed later, extend
LangfuseStream::on_event.
Failure modes
- Transport error →
StreamOutcome::Failed(StreamError::Transport). Health drift applies; the stream goes Degraded after one failure and Unavailable after five consecutive failures. - 5xx response → retried up to 3 times with exponential backoff (100ms → 200 → 400 → 800, capped at 1s).
- 4xx response → returned as
LangfuseError::Status(code); no retry. - Empty scroll_id →
StreamOutcome::Skipped(not a failure).
Configuration
[[streams]]
name = "langfuse-prod"
type = "langfuse"
enabled = true
[streams.scope]
kind = "connector"
connector_uid = "01985d00-..."
[streams.params]
host = "https://langfuse.example.com"
public_key = "pk-lf-..."
secret_key = "sk-lf-..."
Deferred
- Tool-call → span mapping (
SpanCreate/SpanUpdate): scaffolded but not yet populated. - Buffering pending events keyed by
(connector_id, native_session_id)for late-bind scenarios.