agentledger-langfuse 1.2.3__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,96 @@
1
+ from __future__ import annotations
2
+
3
+ import json
4
+ from dataclasses import dataclass
5
+ from typing import Any
6
+ from urllib.request import Request, urlopen
7
+
8
+ from agentledger.trace import TraceExporter, TraceSpan
9
+
10
+ __version__ = "1.2.3"
11
+
12
+
13
+ @dataclass(frozen=True)
14
+ class LangfuseProject:
15
+ public_key: str | None = None
16
+ project: str | None = None
17
+ environment: str | None = None
18
+ release: str | None = None
19
+ tags: tuple[str, ...] = ()
20
+
21
+
22
+ class LangfuseTraceExporter:
23
+ """Convert AgentLedger evidence spans into Langfuse-style ingestion records.
24
+
25
+ The exporter is dependency-free and SDK-neutral. Applications that already
26
+ use the Langfuse SDK can consume `to_ingestion_payload(...)`; deployments
27
+ that prefer HTTP can call `post_json(...)` with their own endpoint and auth
28
+ headers. Runtime-core does not own Langfuse project/key management.
29
+ """
30
+
31
+ def __init__(self, *, project: LangfuseProject | None = None, trace_exporter: TraceExporter | None = None) -> None:
32
+ self.project = project or LangfuseProject()
33
+ self.trace_exporter = trace_exporter or TraceExporter()
34
+
35
+ def to_ingestion_payload(self, evidence: Any) -> dict[str, Any]:
36
+ spans = self.trace_exporter.spans(evidence)
37
+ return {
38
+ "batch": [self._span_record(span) for span in spans],
39
+ "metadata": {
40
+ "source": "agentledger",
41
+ "project": self.project.project,
42
+ "environment": self.project.environment,
43
+ "release": self.project.release,
44
+ "tags": list(self.project.tags),
45
+ },
46
+ }
47
+
48
+ def to_json(self, evidence: Any) -> str:
49
+ return json.dumps(self.to_ingestion_payload(evidence), ensure_ascii=False, indent=2, sort_keys=True)
50
+
51
+ def post_json(
52
+ self,
53
+ evidence: Any,
54
+ endpoint: str,
55
+ *,
56
+ secret_key: str | None = None,
57
+ timeout: float = 10.0,
58
+ opener: Any | None = None,
59
+ headers: dict[str, str] | None = None,
60
+ ) -> dict[str, Any]:
61
+ body = self.to_json(evidence).encode("utf-8")
62
+ request_headers = {"Content-Type": "application/json", **(headers or {})}
63
+ if self.project.public_key:
64
+ request_headers["X-Langfuse-Public-Key"] = self.project.public_key
65
+ if secret_key:
66
+ request_headers["Authorization"] = f"Bearer {secret_key}"
67
+ request = Request(endpoint, data=body, headers=request_headers, method="POST")
68
+ sender = opener or urlopen
69
+ response = sender(request, timeout=timeout)
70
+ status = getattr(response, "status", getattr(response, "code", None))
71
+ response_body = response.read().decode("utf-8", errors="replace") if hasattr(response, "read") else ""
72
+ if status is not None and int(status) >= 400:
73
+ raise RuntimeError(f"Langfuse endpoint returned HTTP {status}: {response_body}")
74
+ return {"endpoint": endpoint, "status": status, "bytes_sent": len(body), "response": response_body}
75
+
76
+ def _span_record(self, span: TraceSpan) -> dict[str, Any]:
77
+ return {
78
+ "type": "trace-span",
79
+ "traceId": span.trace_id,
80
+ "id": span.span_id,
81
+ "parentObservationId": span.parent_span_id,
82
+ "name": span.name,
83
+ "startTime": span.start_time,
84
+ "endTime": span.end_time,
85
+ "metadata": {
86
+ **span.attributes,
87
+ "agentledger.exporter": "langfuse",
88
+ "agentledger.project": self.project.project,
89
+ "agentledger.environment": self.project.environment,
90
+ "agentledger.release": self.project.release,
91
+ },
92
+ "tags": list(self.project.tags),
93
+ }
94
+
95
+
96
+ __all__ = ["LangfuseProject", "LangfuseTraceExporter", "__version__"]
@@ -0,0 +1,37 @@
1
+ Metadata-Version: 2.4
2
+ Name: agentledger-langfuse
3
+ Version: 1.2.3
4
+ Summary: Langfuse evidence and trace export adapter package for AgentLedger
5
+ Project-URL: Homepage, https://github.com/yaogdu/AgentLedger
6
+ Project-URL: Repository, https://github.com/yaogdu/AgentLedger
7
+ Project-URL: Documentation, https://github.com/yaogdu/AgentLedger/tree/main/docs
8
+ Project-URL: Issues, https://github.com/yaogdu/AgentLedger/issues
9
+ Author: AgentLedger Contributors
10
+ License: Apache-2.0
11
+ Keywords: agents,evidence,langfuse,runtime,tracing
12
+ Requires-Python: >=3.11
13
+ Requires-Dist: agentledger-runtime<2,>=1.2
14
+ Description-Content-Type: text/markdown
15
+
16
+ # agentledger-langfuse
17
+
18
+ Langfuse evidence and trace export adapter package for AgentLedger.
19
+
20
+ ```bash
21
+ pip install agentledger-langfuse
22
+ pip install "agentledger-runtime[langfuse]"
23
+ ```
24
+
25
+ ```python
26
+ from agentledger_langfuse import LangfuseTraceExporter
27
+
28
+ payload = LangfuseTraceExporter().to_ingestion_payload(evidence_bundle)
29
+ ```
30
+
31
+ This adapter is intentionally thin. It converts AgentLedger evidence spans into Langfuse-style ingestion records and can POST JSON to a user-provided endpoint. It does not replace Langfuse, own project/key management, or import the Langfuse SDK in runtime-core.
32
+
33
+ Certification:
34
+
35
+ ```bash
36
+ python3 -m agentledger adapter certify --kind langfuse --adapter-version 1.2.3
37
+ ```
@@ -0,0 +1,4 @@
1
+ agentledger_langfuse/__init__.py,sha256=BGeJw8mCxh4WqMWc1ZI7jGdBJC-jztXOME54Pste2FY,3790
2
+ agentledger_langfuse-1.2.3.dist-info/METADATA,sha256=aedRO5C0AVSPnV9Ft-WnxfqPo76OxStfny_ju5Hr1Ig,1319
3
+ agentledger_langfuse-1.2.3.dist-info/WHEEL,sha256=QccIxa26bgl1E6uMy58deGWi-0aeIkkangHcxk2kWfw,87
4
+ agentledger_langfuse-1.2.3.dist-info/RECORD,,
@@ -0,0 +1,4 @@
1
+ Wheel-Version: 1.0
2
+ Generator: hatchling 1.29.0
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any