agentledger-langfuse 1.2.3__tar.gz

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,64 @@
1
+ .agentledger/
2
+ go/.agentledger-go/
3
+ rust/.agentledger-rust/
4
+ *.db
5
+ *.sqlite
6
+ *.sqlite3
7
+
8
+ __pycache__/
9
+ **/__pycache__/
10
+ *.py[cod]
11
+ *.pyo
12
+ *.pyd
13
+ $py.class
14
+ .pytest_cache/
15
+ .mypy_cache/
16
+ .ruff_cache/
17
+ .coverage
18
+ coverage.xml
19
+ dist/
20
+ build/
21
+ *.egg-info/
22
+ .venv/
23
+ venv/
24
+ .env
25
+ .DS_Store
26
+ **/.DS_Store
27
+ node_modules/
28
+ **/node_modules/
29
+ npm-debug.log*
30
+ yarn-debug.log*
31
+ yarn-error.log*
32
+ pnpm-debug.log*
33
+
34
+ # Local notes, research dumps, and generated reports that should not ship.
35
+ .claude/
36
+ AI_Agent_Runtime_开源项目构想.md
37
+ *.pdf
38
+ *.docx
39
+ *.pptx
40
+ *.pages
41
+ *.key
42
+ evidence/
43
+ evidence*.html
44
+ time-travel*.html
45
+
46
+ # Local external installer/download artifacts.
47
+ rce
48
+
49
+ # Rust build outputs.
50
+ target/
51
+ **/target/
52
+ rust/crates/*/Cargo.lock
53
+ # Local transient files
54
+ *.tmp
55
+ *.log
56
+ *.bak
57
+ *.swp
58
+ *.swo
59
+ *.orig
60
+
61
+ # Python/pytest leftovers not always covered by tool output
62
+ .coverage.*
63
+ htmlcov/
64
+ .ipynb_checkpoints/
@@ -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,22 @@
1
+ # agentledger-langfuse
2
+
3
+ Langfuse evidence and trace export adapter package for AgentLedger.
4
+
5
+ ```bash
6
+ pip install agentledger-langfuse
7
+ pip install "agentledger-runtime[langfuse]"
8
+ ```
9
+
10
+ ```python
11
+ from agentledger_langfuse import LangfuseTraceExporter
12
+
13
+ payload = LangfuseTraceExporter().to_ingestion_payload(evidence_bundle)
14
+ ```
15
+
16
+ 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.
17
+
18
+ Certification:
19
+
20
+ ```bash
21
+ python3 -m agentledger adapter certify --kind langfuse --adapter-version 1.2.3
22
+ ```
@@ -0,0 +1,23 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "agentledger-langfuse"
7
+ version = "1.2.3"
8
+ description = "Langfuse evidence and trace export adapter package for AgentLedger"
9
+ readme = "README.md"
10
+ requires-python = ">=3.11"
11
+ license = {text = "Apache-2.0"}
12
+ authors = [{name = "AgentLedger Contributors"}]
13
+ keywords = ["agents", "runtime", "langfuse", "tracing", "evidence"]
14
+ dependencies = ["agentledger-runtime>=1.2,<2"]
15
+
16
+ [project.urls]
17
+ Homepage = "https://github.com/yaogdu/AgentLedger"
18
+ Repository = "https://github.com/yaogdu/AgentLedger"
19
+ Documentation = "https://github.com/yaogdu/AgentLedger/tree/main/docs"
20
+ Issues = "https://github.com/yaogdu/AgentLedger/issues"
21
+
22
+ [tool.hatch.build.targets.wheel]
23
+ packages = ["src/agentledger_langfuse"]
@@ -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,5 @@
1
+ def test_imports() -> None:
2
+ from agentledger_langfuse import LangfuseProject, LangfuseTraceExporter
3
+
4
+ assert LangfuseProject.__name__ == "LangfuseProject"
5
+ assert LangfuseTraceExporter.__name__ == "LangfuseTraceExporter"