# Package: dirigent_langfuse Phase 4 stream backend that mirrors BusEvents to a Langfuse ingestion endpoint. ## Scope - `LangfuseFactory` registered as `kind = "langfuse"` in the `StreamFactoryRegistry`. - `LangfuseStream` implements `SessionStream`: - Maps each `BusEvent` via `mapping::bus_event_to_items`. - Buffers up to 32 items per flush; flushes eagerly when full and on shutdown. - POSTs `{host}/api/public/ingestion` with basic-auth `(public_key, secret_key)`. ## File map - `src/lib.rs` — public API: `LangfuseStream`, `LangfuseConfig`, `LangfuseFactory`. - `src/client.rs` — `LangfuseClient` (reqwest wrapper with retry) and the `LangfuseStream` implementation. - `src/mapping.rs` — `bus_event_to_items` mapping. - `src/factory.rs` — `StreamFactory` impl. ## 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 ```toml [[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.