traceAI-livekit 0.1.0__tar.gz → 0.1.2__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,128 @@
1
+ Metadata-Version: 2.3
2
+ Name: traceAI-livekit
3
+ Version: 0.1.2
4
+ Summary: OpenTelemetry instrumentation for LiveKit
5
+ Author: Future AGI
6
+ Author-email: no-reply@futureagi.com
7
+ Requires-Python: >3.9,<3.14
8
+ Classifier: Programming Language :: Python :: 3
9
+ Classifier: Programming Language :: Python :: 3.10
10
+ Classifier: Programming Language :: Python :: 3.11
11
+ Classifier: Programming Language :: Python :: 3.12
12
+ Classifier: Programming Language :: Python :: 3.13
13
+ Requires-Dist: fi-instrumentation-otel (>=1.1.0)
14
+ Description-Content-Type: text/markdown
15
+
16
+ # traceAI-livekit
17
+
18
+ OpenTelemetry instrumentation for LiveKit agents integrated with Future AGI.
19
+
20
+ This package provides automatic attribute mapping from LiveKit's native OpenTelemetry instrumentation to Future AGI's semantic conventions, ensuring rich and structured traces in your dashboard.
21
+
22
+ ## Installation
23
+
24
+ ```bash
25
+ pip install traceai-livekit
26
+ ```
27
+
28
+ ## Quick Start
29
+
30
+ To instrument your LiveKit agent, simply initialize `fi-instrumentation` and enable the attribute mapping **inside your agent's entrypoint**.
31
+
32
+ ```python
33
+ from livekit.agents import AgentServer, JobContext
34
+ from fi_instrumentation.otel import register, ProjectType
35
+ from traceai_livekit import enable_http_attribute_mapping
36
+
37
+ server = AgentServer()
38
+
39
+ @server.rtc_session()
40
+ async def entrypoint(ctx: JobContext):
41
+ # 1. Initialize TraceAI (inside entrypoint for multiprocessing safety)
42
+ register(
43
+ project_name="My LiveKit Agent",
44
+ project_type=ProjectType.OBSERVE,
45
+ set_global_tracer_provider=True,
46
+ )
47
+
48
+ # 2. Enable LiveKit attribute mapping
49
+ # This automatically hooks into LiveKit's telemetry system
50
+ enable_http_attribute_mapping()
51
+
52
+ # ... rest of your agent logic ...
53
+ await ctx.connect()
54
+
55
+ if __name__ == "__main__":
56
+ server.run()
57
+ ```
58
+
59
+ `enable_http_attribute_mapping()` (or `enable_grpc_attribute_mapping()`) hands the provider to LiveKit for you. If you call
60
+ LiveKit's `set_tracer_provider` yourself on the provider `register()` returned, call it after `enable_*`: before it, the call
61
+ drops the Future AGI exporter. LiveKit installs its privacy filter once per provider, so an `allow_pii` passed in a later call is
62
+ ignored. To keep conversation content out of your traces, set `LIVEKIT_TELEMETRY_ALLOW_PII=false` before calling `enable_*`
63
+ (livekit-agents 1.8 and later).
64
+
65
+ ### Flushing at the end of a job
66
+
67
+ On Linux a LiveKit job process ends without running `atexit`, and LiveKit flushes only its own processors, so the spans
68
+ still queued when a job ends, such as the root `agent_session` span, used to never reach Future AGI. `enable_*` now sends
69
+ them twice over:
70
+
71
+ - **When the job shuts down**, if `enable_*` runs inside a job (the usual place, the entrypoint): this sends the voice
72
+ trace, `agent_session` included, as soon as the call ends.
73
+ - **When the process exits**, just before it stops: this sends what LiveKit ends after the shutdown callbacks, its own
74
+ `job_shutdown` span, and the job's root `job_entrypoint` span when tracing is set up before the job starts. With
75
+ set-up inside the entrypoint, LiveKit starts `job_entrypoint` before tracing is on, so it is never recorded and the
76
+ job trace arrives rooted at `job_shutdown`.
77
+
78
+ Each waits at most 3 seconds for the collector, well inside the 10 seconds LiveKit gives a job process to exit, so its own
79
+ clean-up still runs when the collector is slow.
80
+
81
+ If you set tracing up outside a job (for example at import time, in the job process), only the process-exit flush runs.
82
+ To also send each call's trace as soon as the call ends, call `flush_on_job_shutdown()` in each job entrypoint:
83
+
84
+ ```python
85
+ from traceai_livekit import flush_on_job_shutdown
86
+
87
+ @server.rtc_session()
88
+ async def entrypoint(ctx: JobContext):
89
+ flush_on_job_shutdown()
90
+ ...
91
+ ```
92
+
93
+ Do not pass `provider.force_flush` to `ctx.add_shutdown_callback`: LiveKit calls it with the shutdown reason, which
94
+ `force_flush` takes as its timeout, so it fails and nothing is flushed.
95
+
96
+ Limits:
97
+ - A process LiveKit kills (for example when a worker drains and the job overruns its exit time) sends nothing more.
98
+ - Before livekit-agents 1.3, LiveKit closes the session at the same time as the job-shutdown flush, so that flush can miss
99
+ `agent_session`; the process-exit flush still sends it.
100
+ - A second `AgentSession` in one job that is still closing when the shutdown callbacks run is sent by the process-exit
101
+ flush, not the job-shutdown one.
102
+ - In LiveKit Cloud observability mode the session's parent span is recorded on LiveKit's own provider and never reaches
103
+ Future AGI, so the trace has no stored root there.
104
+
105
+ ## Compatibility
106
+
107
+ * **livekit-agents**: 1.x. 1.8 is the tested version (it needs Python 3.10 or later). Since 1.7, LiveKit names its content
108
+ attributes `lk.pii.*` (for example `lk.pii.user_input`); both those names and the earlier ones are mapped to `input.value`
109
+ and `output.value`.
110
+ * **fi-instrumentation-otel**: 1.1.0 or later (1.0.0 fails inside `register()` with OpenTelemetry 1.45, which livekit-agents
111
+ 1.8.7 and later require). 1.0 moved span attributes from the `llm.*` names to the OpenTelemetry GenAI `gen_ai.*` names, and
112
+ renamed the `SpanAttributes` constants with them. Code that only calls `register()` is unaffected; if your code sets or reads
113
+ those attributes directly, see the
114
+ [mapping from the old names](https://github.com/future-agi/traceAI/blob/main/docs/OTEL_GENAI_SEMANTIC_CONVENTIONS.md#migration-from-openinference-llm).
115
+
116
+ ## Features
117
+
118
+ * **Automatic Attribute Mapping**: Converts LiveKit attributes (like `lk.user_input`, `gen_ai.usage.input_tokens`) to Future AGI standard attributes (`input.value`, `llm.tokenCount.prompt`).
119
+ * **Raw Data Preservation**: Keeps original LiveKit attributes and adds `raw.input` / `raw.output` for full debugging context.
120
+ * **Multiprocessing Support**: Designed to work with LiveKit's worker process model.
121
+ * **Event Parsing**: Extracts LLM outputs from `gen_ai.choice` events when available.
122
+
123
+ ## Examples
124
+
125
+ Check the `examples/` directory for complete working agents:
126
+ * `simple_agent.py`: A basic voice assistant agent.
127
+ * `egress_agent.py`: An agent with call recording (Egress) enabled.
128
+
@@ -0,0 +1,112 @@
1
+ # traceAI-livekit
2
+
3
+ OpenTelemetry instrumentation for LiveKit agents integrated with Future AGI.
4
+
5
+ This package provides automatic attribute mapping from LiveKit's native OpenTelemetry instrumentation to Future AGI's semantic conventions, ensuring rich and structured traces in your dashboard.
6
+
7
+ ## Installation
8
+
9
+ ```bash
10
+ pip install traceai-livekit
11
+ ```
12
+
13
+ ## Quick Start
14
+
15
+ To instrument your LiveKit agent, simply initialize `fi-instrumentation` and enable the attribute mapping **inside your agent's entrypoint**.
16
+
17
+ ```python
18
+ from livekit.agents import AgentServer, JobContext
19
+ from fi_instrumentation.otel import register, ProjectType
20
+ from traceai_livekit import enable_http_attribute_mapping
21
+
22
+ server = AgentServer()
23
+
24
+ @server.rtc_session()
25
+ async def entrypoint(ctx: JobContext):
26
+ # 1. Initialize TraceAI (inside entrypoint for multiprocessing safety)
27
+ register(
28
+ project_name="My LiveKit Agent",
29
+ project_type=ProjectType.OBSERVE,
30
+ set_global_tracer_provider=True,
31
+ )
32
+
33
+ # 2. Enable LiveKit attribute mapping
34
+ # This automatically hooks into LiveKit's telemetry system
35
+ enable_http_attribute_mapping()
36
+
37
+ # ... rest of your agent logic ...
38
+ await ctx.connect()
39
+
40
+ if __name__ == "__main__":
41
+ server.run()
42
+ ```
43
+
44
+ `enable_http_attribute_mapping()` (or `enable_grpc_attribute_mapping()`) hands the provider to LiveKit for you. If you call
45
+ LiveKit's `set_tracer_provider` yourself on the provider `register()` returned, call it after `enable_*`: before it, the call
46
+ drops the Future AGI exporter. LiveKit installs its privacy filter once per provider, so an `allow_pii` passed in a later call is
47
+ ignored. To keep conversation content out of your traces, set `LIVEKIT_TELEMETRY_ALLOW_PII=false` before calling `enable_*`
48
+ (livekit-agents 1.8 and later).
49
+
50
+ ### Flushing at the end of a job
51
+
52
+ On Linux a LiveKit job process ends without running `atexit`, and LiveKit flushes only its own processors, so the spans
53
+ still queued when a job ends, such as the root `agent_session` span, used to never reach Future AGI. `enable_*` now sends
54
+ them twice over:
55
+
56
+ - **When the job shuts down**, if `enable_*` runs inside a job (the usual place, the entrypoint): this sends the voice
57
+ trace, `agent_session` included, as soon as the call ends.
58
+ - **When the process exits**, just before it stops: this sends what LiveKit ends after the shutdown callbacks, its own
59
+ `job_shutdown` span, and the job's root `job_entrypoint` span when tracing is set up before the job starts. With
60
+ set-up inside the entrypoint, LiveKit starts `job_entrypoint` before tracing is on, so it is never recorded and the
61
+ job trace arrives rooted at `job_shutdown`.
62
+
63
+ Each waits at most 3 seconds for the collector, well inside the 10 seconds LiveKit gives a job process to exit, so its own
64
+ clean-up still runs when the collector is slow.
65
+
66
+ If you set tracing up outside a job (for example at import time, in the job process), only the process-exit flush runs.
67
+ To also send each call's trace as soon as the call ends, call `flush_on_job_shutdown()` in each job entrypoint:
68
+
69
+ ```python
70
+ from traceai_livekit import flush_on_job_shutdown
71
+
72
+ @server.rtc_session()
73
+ async def entrypoint(ctx: JobContext):
74
+ flush_on_job_shutdown()
75
+ ...
76
+ ```
77
+
78
+ Do not pass `provider.force_flush` to `ctx.add_shutdown_callback`: LiveKit calls it with the shutdown reason, which
79
+ `force_flush` takes as its timeout, so it fails and nothing is flushed.
80
+
81
+ Limits:
82
+ - A process LiveKit kills (for example when a worker drains and the job overruns its exit time) sends nothing more.
83
+ - Before livekit-agents 1.3, LiveKit closes the session at the same time as the job-shutdown flush, so that flush can miss
84
+ `agent_session`; the process-exit flush still sends it.
85
+ - A second `AgentSession` in one job that is still closing when the shutdown callbacks run is sent by the process-exit
86
+ flush, not the job-shutdown one.
87
+ - In LiveKit Cloud observability mode the session's parent span is recorded on LiveKit's own provider and never reaches
88
+ Future AGI, so the trace has no stored root there.
89
+
90
+ ## Compatibility
91
+
92
+ * **livekit-agents**: 1.x. 1.8 is the tested version (it needs Python 3.10 or later). Since 1.7, LiveKit names its content
93
+ attributes `lk.pii.*` (for example `lk.pii.user_input`); both those names and the earlier ones are mapped to `input.value`
94
+ and `output.value`.
95
+ * **fi-instrumentation-otel**: 1.1.0 or later (1.0.0 fails inside `register()` with OpenTelemetry 1.45, which livekit-agents
96
+ 1.8.7 and later require). 1.0 moved span attributes from the `llm.*` names to the OpenTelemetry GenAI `gen_ai.*` names, and
97
+ renamed the `SpanAttributes` constants with them. Code that only calls `register()` is unaffected; if your code sets or reads
98
+ those attributes directly, see the
99
+ [mapping from the old names](https://github.com/future-agi/traceAI/blob/main/docs/OTEL_GENAI_SEMANTIC_CONVENTIONS.md#migration-from-openinference-llm).
100
+
101
+ ## Features
102
+
103
+ * **Automatic Attribute Mapping**: Converts LiveKit attributes (like `lk.user_input`, `gen_ai.usage.input_tokens`) to Future AGI standard attributes (`input.value`, `llm.tokenCount.prompt`).
104
+ * **Raw Data Preservation**: Keeps original LiveKit attributes and adds `raw.input` / `raw.output` for full debugging context.
105
+ * **Multiprocessing Support**: Designed to work with LiveKit's worker process model.
106
+ * **Event Parsing**: Extracts LLM outputs from `gen_ai.choice` events when available.
107
+
108
+ ## Examples
109
+
110
+ Check the `examples/` directory for complete working agents:
111
+ * `simple_agent.py`: A basic voice assistant agent.
112
+ * `egress_agent.py`: An agent with call recording (Egress) enabled.
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "traceAI-livekit"
3
- version = "0.1.0"
3
+ version = "0.1.2"
4
4
  description = "OpenTelemetry instrumentation for LiveKit"
5
5
  authors = ["Future AGI <no-reply@futureagi.com>"]
6
6
  readme = "README.md"
@@ -10,13 +10,15 @@ packages = [
10
10
 
11
11
  [tool.poetry.dependencies]
12
12
  python = ">3.9,<3.14"
13
- fi-instrumentation-otel = ">=0.1.14"
13
+ fi-instrumentation-otel = ">=1.1.0"
14
14
 
15
15
  [tool.poetry.group.dev.dependencies]
16
- livekit-agents = "*"
17
- livekit-plugins-openai = "*"
18
- livekit-plugins-silero = "*"
16
+ # livekit-agents 1.8 is the version whose privacy filter the tests cover; it needs Python 3.10+.
17
+ livekit-agents = { version = "~1.8", python = ">=3.10" }
18
+ livekit-plugins-openai = { version = "~1.8", python = ">=3.10" }
19
+ livekit-plugins-silero = { version = "~1.8", python = ">=3.10" }
19
20
  python-dotenv = "*"
21
+ pytest = ">=7.0"
20
22
 
21
23
  [build-system]
22
24
  requires = ["poetry-core"]
@@ -16,9 +16,10 @@ from .integration import (
16
16
  enable_fi_attribute_mapping,
17
17
  enable_grpc_attribute_mapping,
18
18
  enable_http_attribute_mapping,
19
+ flush_on_job_shutdown,
19
20
  )
20
21
 
21
- __version__ = "0.1.0"
22
+ __version__ = "0.1.2"
22
23
 
23
24
  __all__ = [
24
25
  "enable_fi_attribute_mapping",
@@ -26,6 +27,7 @@ __all__ = [
26
27
  "enable_grpc_attribute_mapping",
27
28
  "create_mapped_http_exporter",
28
29
  "create_mapped_grpc_exporter",
30
+ "flush_on_job_shutdown",
29
31
  # Exporters
30
32
  "MappedHTTPSpanExporter",
31
33
  "MappedGRPCSpanExporter",