Skip to content

feat(ai): native Langfuse and Datadog usage sinks#554

Merged
rickcrawford merged 2 commits into
mainfrom
rickcrawford/wor-1528-native-usage-sinks
Jun 27, 2026
Merged

feat(ai): native Langfuse and Datadog usage sinks#554
rickcrawford merged 2 commits into
mainfrom
rickcrawford/wor-1528-native-usage-sinks

Conversation

@rickcrawford

Copy link
Copy Markdown
Contributor

What

Two native usage sinks behind the existing UsageSink seam, so a completed-call event can be forwarded directly to Langfuse or Datadog instead of via the generic webhook:

  • type: langfusehost + public_key + secret_key. POSTs a generation-create observation to {host}/api/public/ingestion with public/secret-key basic auth. Token counts go in usage; provider, cost, latency, status, and identifiers go in metadata.
  • type: datadogapi_key + optional site (default datadoghq.com) + optional service (default sbproxy). POSTs to https://http-intake.logs.{site}/api/v2/logs with the DD-API-KEY header.

Both are fire-and-forget on a spawned task and swallow errors, so a broken or misconfigured sink can never block or fail the request it records (same contract as the existing webhook/jsonl/ledger sinks).

Tests

  • Pure, deterministic unit tests for the payload builders (langfuse_ingestion_body, datadog_log_body) and config parsing/build (8 usage_sink tests pass).
  • Full sbproxy-ai lib suite (962) passes; clippy -D warnings and rustdoc -D warnings -D missing_docs clean; regenerated config schema is byte-identical (the sink config is deserialize-only).

Caveat / scope

The payload shapes follow Langfuse's public ingestion API and Datadog's logs-intake API as documented. CI can unit-test the JSON I construct but cannot validate it against a live endpoint, so these should be confirmed against a real Langfuse/Datadog before relying on them in production. Object-store sinks (S3/GCS, which need cloud SDKs) and an OTel usage sink (overlaps the existing OTLP span pipeline) are intentionally not included here.

rickcrawford and others added 2 commits June 26, 2026 19:30
Adds two provider sinks behind the existing UsageSink seam, next to the
JSONL-file / webhook / ledger sinks:

- langfuse: posts a generation observation to {host}/api/public/ingestion
  with public/secret-key basic auth.
- datadog: posts to https://http-intake.logs.{site}/api/v2/logs with the
  DD-API-KEY header; site defaults to datadoghq.com, optional service tag.

The request-body shaping (langfuse_ingestion_body, datadog_log_body) is
pure and unit-tested; the sinks are fire-and-forget and swallow errors so
a broken sink can never fail the request it records. Config is
deserialize-only, so no schema change. Object-store (S3/GCS) and OTel
usage sinks are not yet included.

Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01X19S6eQzKKExZ9RUPAHuGy
…-native-usage-sinks

# Conflicts:
#	CHANGELOG.md
@rickcrawford rickcrawford merged commit d04272f into main Jun 27, 2026
8 checks passed
@rickcrawford rickcrawford deleted the rickcrawford/wor-1528-native-usage-sinks branch June 27, 2026 03:25
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant