zooid 0.1.0__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.
Files changed (47) hide show
  1. zooid-0.1.0/.gitignore +61 -0
  2. zooid-0.1.0/LICENSE +21 -0
  3. zooid-0.1.0/PKG-INFO +164 -0
  4. zooid-0.1.0/README.md +123 -0
  5. zooid-0.1.0/dashboards/trust_center_dashboard.json +102 -0
  6. zooid-0.1.0/dashboards/voice_agent_dashboard.json +114 -0
  7. zooid-0.1.0/examples/basic_voice_agent.py +64 -0
  8. zooid-0.1.0/examples/docker-compose.yml +14 -0
  9. zooid-0.1.0/examples/pipecat_agent.py +28 -0
  10. zooid-0.1.0/pyproject.toml +62 -0
  11. zooid-0.1.0/skills/zooid-instrumentation/SKILL.md +180 -0
  12. zooid-0.1.0/src/zooid/__init__.py +25 -0
  13. zooid-0.1.0/src/zooid/_version.py +1 -0
  14. zooid-0.1.0/src/zooid/context.py +218 -0
  15. zooid-0.1.0/src/zooid/exporters/__init__.py +1 -0
  16. zooid-0.1.0/src/zooid/exporters/signoz.py +49 -0
  17. zooid-0.1.0/src/zooid/instrumentor.py +150 -0
  18. zooid-0.1.0/src/zooid/metrics.py +108 -0
  19. zooid-0.1.0/src/zooid/scaffold/__init__.py +6 -0
  20. zooid-0.1.0/src/zooid/scaffold/cli.py +94 -0
  21. zooid-0.1.0/src/zooid/scaffold/generator.py +69 -0
  22. zooid-0.1.0/src/zooid/scaffold/templates/__init__.py +1 -0
  23. zooid-0.1.0/src/zooid/scaffold/templates/agent.py +262 -0
  24. zooid-0.1.0/src/zooid/scaffold/templates/common.py +95 -0
  25. zooid-0.1.0/src/zooid/scaffold/templates/frameworks.py +123 -0
  26. zooid-0.1.0/src/zooid/scaffold/templates/project.py +362 -0
  27. zooid-0.1.0/src/zooid/trust/__init__.py +27 -0
  28. zooid-0.1.0/src/zooid/trust/aggregator.py +64 -0
  29. zooid-0.1.0/src/zooid/trust/ai_advisor.py +64 -0
  30. zooid-0.1.0/src/zooid/trust/context_writer.py +115 -0
  31. zooid-0.1.0/src/zooid/trust/mcp_server.py +163 -0
  32. zooid-0.1.0/src/zooid/trust/recommendations.py +71 -0
  33. zooid-0.1.0/src/zooid/trust/reporter.py +40 -0
  34. zooid-0.1.0/src/zooid/trust/rules/__init__.py +9 -0
  35. zooid-0.1.0/src/zooid/trust/rules/base.py +61 -0
  36. zooid-0.1.0/src/zooid/trust/rules/naming_rules.py +58 -0
  37. zooid-0.1.0/src/zooid/trust/rules/resource_rules.py +86 -0
  38. zooid-0.1.0/src/zooid/trust/rules/span_rules.py +125 -0
  39. zooid-0.1.0/src/zooid/trust/rules/voice_rules.py +50 -0
  40. zooid-0.1.0/src/zooid/trust/scorer.py +87 -0
  41. zooid-0.1.0/src/zooid/wrappers/__init__.py +14 -0
  42. zooid-0.1.0/src/zooid/wrappers/base_wrapper.py +68 -0
  43. zooid-0.1.0/src/zooid/wrappers/deepgram_wrapper.py +121 -0
  44. zooid-0.1.0/src/zooid/wrappers/elevenlabs_wrapper.py +125 -0
  45. zooid-0.1.0/src/zooid/wrappers/openai_wrapper.py +180 -0
  46. zooid-0.1.0/tests/test_mcp_context.py +140 -0
  47. zooid-0.1.0/tests/test_scaffold.py +381 -0
zooid-0.1.0/.gitignore ADDED
@@ -0,0 +1,61 @@
1
+ # Python
2
+ __pycache__/
3
+ *.py[cod]
4
+ *$py.class
5
+ *.so
6
+ .Python
7
+ build/
8
+ develop-eggs/
9
+ dist/
10
+ downloads/
11
+ eggs/
12
+ .eggs/
13
+ lib/
14
+ lib64/
15
+ parts/
16
+ sdist/
17
+ var/
18
+ wheels/
19
+ share/python-wheels/
20
+ *.egg-info/
21
+ .installed.cfg
22
+ *.egg
23
+ MANIFEST
24
+ .pytest_cache/
25
+ .coverage
26
+ htmlcov/
27
+ .venv
28
+ venv/
29
+ ENV/
30
+ env/
31
+
32
+ # Node / Web
33
+ node_modules/
34
+ web/node_modules/
35
+ web/dist/
36
+ web/.vite/
37
+ .npm
38
+ *.log
39
+
40
+ # Web source dir — not the Python "lib/" build artifact excluded above
41
+ !web/src/lib/
42
+ !web/src/lib/**
43
+
44
+ # IDE & OS
45
+ .DS_Store
46
+ Thumbs.db
47
+ .vscode/
48
+ .idea/
49
+ *.swp
50
+
51
+ # Docker / Local logs
52
+ *.log
53
+ docker/*.log
54
+ docker/.bin/
55
+ docker/pours/
56
+ docker/casting.yaml.lock
57
+
58
+ # Secrets — never commit real API keys
59
+ .env
60
+ server/.env
61
+ !server/.env.example
zooid-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Zooid Team
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
zooid-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,164 @@
1
+ Metadata-Version: 2.4
2
+ Name: zooid
3
+ Version: 0.1.0
4
+ Summary: Zero-code OpenTelemetry auto-instrumentation for Voice AI pipelines & Telemetry Trust Center
5
+ Project-URL: Homepage, https://github.com/Priyank911/zooid
6
+ Project-URL: Repository, https://github.com/Priyank911/zooid
7
+ Author-email: Zooid Team <zooid@signoz.io>
8
+ License-File: LICENSE
9
+ Keywords: llm,opentelemetry,signoz,speech-to-text,text-to-speech,voice
10
+ Classifier: Development Status :: 3 - Alpha
11
+ Classifier: Intended Audience :: Developers
12
+ Classifier: License :: OSI Approved :: MIT License
13
+ Classifier: Programming Language :: Python :: 3
14
+ Classifier: Programming Language :: Python :: 3.10
15
+ Classifier: Programming Language :: Python :: 3.11
16
+ Classifier: Programming Language :: Python :: 3.12
17
+ Requires-Python: >=3.10
18
+ Requires-Dist: opentelemetry-api>=1.20.0
19
+ Requires-Dist: opentelemetry-exporter-otlp-proto-grpc>=1.20.0
20
+ Requires-Dist: opentelemetry-sdk>=1.20.0
21
+ Requires-Dist: wrapt>=1.14.0
22
+ Provides-Extra: all
23
+ Requires-Dist: deepgram-sdk>=3.0.0; extra == 'all'
24
+ Requires-Dist: elevenlabs>=0.2.0; extra == 'all'
25
+ Requires-Dist: mcp>=1.0.0; extra == 'all'
26
+ Requires-Dist: openai>=1.0.0; extra == 'all'
27
+ Provides-Extra: deepgram
28
+ Requires-Dist: deepgram-sdk>=3.0.0; extra == 'deepgram'
29
+ Provides-Extra: dev
30
+ Requires-Dist: mcp>=1.0.0; extra == 'dev'
31
+ Requires-Dist: pytest; extra == 'dev'
32
+ Requires-Dist: pytest-asyncio; extra == 'dev'
33
+ Requires-Dist: pytest-cov; extra == 'dev'
34
+ Provides-Extra: elevenlabs
35
+ Requires-Dist: elevenlabs>=0.2.0; extra == 'elevenlabs'
36
+ Provides-Extra: mcp
37
+ Requires-Dist: mcp>=1.0.0; extra == 'mcp'
38
+ Provides-Extra: openai
39
+ Requires-Dist: openai>=1.0.0; extra == 'openai'
40
+ Description-Content-Type: text/markdown
41
+
42
+ # zooid
43
+
44
+ `zooid` provides OpenTelemetry auto-instrumentation and SDK helpers specifically engineered for conversational Voice AI applications (such as speech-to-speech agents, streaming LLM cascades, and voice bots) along with Telemetry Trust Center scoring for **SigNoz**.
45
+
46
+ It helps you track critical voice metrics like Time-To-First-Audio (TTFA), token stream latencies, interruptions, and multi-stage (STT -> LLM -> TTS) timing boundaries.
47
+
48
+ ---
49
+
50
+ ## Installation
51
+
52
+ ```bash
53
+ pip install zooid
54
+ ```
55
+
56
+ For local development within this workspace:
57
+ ```bash
58
+ pip install -e .
59
+ ```
60
+
61
+ ---
62
+
63
+ ## Quick Start
64
+
65
+ ### 1. Initialize Instrumentation
66
+
67
+ Initialize OpenTelemetry providers and the Telemetry Trust Center at your application entry point:
68
+
69
+ ```python
70
+ from zooid import instrument_voice_app
71
+
72
+ handle = instrument_voice_app(
73
+ service_name="voice-assistant-service",
74
+ signoz_endpoint="localhost:4317",
75
+ insecure=True,
76
+ enable_trust_center=True
77
+ )
78
+ ```
79
+
80
+ ### 2. Trace Voice Turns
81
+
82
+ Wrap your conversational turns using the async context manager or decorator:
83
+
84
+ ```python
85
+ import asyncio
86
+ from zooid import VoiceTurnContext, voice_turn
87
+
88
+ # Option A: Async Context Manager (Recommended)
89
+ async def process_turn(audio_stream):
90
+ async with VoiceTurnContext(architecture_mode="cascade") as turn:
91
+ # 1. Speech-to-Text
92
+ text = await process_stt(audio_stream)
93
+ turn.mark_stt_complete()
94
+
95
+ # 2. LLM Streaming
96
+ async for chunk in stream_llm(text):
97
+ if turn.llm_first_token_ms is None:
98
+ turn.mark_llm_first_token()
99
+
100
+ # 3. Text-to-Speech Output
101
+ audio_out = await generate_tts(chunk)
102
+ turn.mark_first_audio() # Captures TTFA metric
103
+
104
+ # Option B: Decorator
105
+ @voice_turn(architecture_mode="hybrid")
106
+ async def handle_turn(input_data):
107
+ current_turn = VoiceTurnContext.get_current()
108
+ # Execute turn logic...
109
+ ```
110
+
111
+ ---
112
+
113
+ ## Core Features
114
+
115
+ - **Automatic TTFA Tracking:** Dedicated timing hooks to accurately record Time-To-First-Audio.
116
+ - **Stage Latency Isolation:** Measure STT duration, LLM Time-To-First-Token (TTFT), and TTS generation independently.
117
+ - **Telemetry Trust Center:** Live span quality evaluation calculating a score (0-100) with critical violation detection.
118
+ - **Asyncio Context Propagation:** Preserves OpenTelemetry trace context across `asyncio.create_task()` background loops.
119
+
120
+ ---
121
+
122
+ ## API Reference
123
+
124
+ ### `instrument_voice_app(...)`
125
+ Initializes OpenTelemetry Tracer and Meter Providers configured for SigNoz OTLP gRPC export.
126
+
127
+ ```python
128
+ def instrument_voice_app(
129
+ service_name: str = 'voice-agent',
130
+ signoz_endpoint: str = 'localhost:4317',
131
+ insecure: bool = True,
132
+ enable_trust_center: bool = True,
133
+ trust_center_mode: str = 'template',
134
+ llm_endpoint: Optional[str] = None,
135
+ export_interval_ms: int = 5000
136
+ ) -> InstrumentationHandle
137
+ ```
138
+
139
+ ### `VoiceTurnContext`
140
+ Context manager for tracking voice turn timing and metrics.
141
+
142
+ - `VoiceTurnContext.get_current()`: Returns the active `VoiceTurnContext` instance for the current `asyncio` context.
143
+ - `turn.mark_stt_complete()`: Marks STT processing completion and records STT duration.
144
+ - `turn.mark_llm_first_token()`: Marks the arrival of the first LLM token stream chunk.
145
+ - `turn.mark_first_audio()`: Marks the output of the first synthesized audio chunk and exports the TTFA metric.
146
+
147
+ ---
148
+
149
+ ## Metrics Reference
150
+
151
+ | Metric Name | Type | Unit | Description |
152
+ |---|---|---|---|
153
+ | `voice.time_to_first_audio_ms` | Histogram | ms | Time from user turn start to first synthesized audio |
154
+ | `voice.stt_duration_ms` | Histogram | ms | Speech-To-Text processing duration |
155
+ | `voice.llm_first_token_ms` | Histogram | ms | LLM Time-To-First-Token latency |
156
+ | `voice.turns_total` | Counter | 1 | Total number of conversational turns processed |
157
+ | `voice.interruptions_total` | Counter | 1 | Total number of user interruptions recorded |
158
+ | `instrumentation.score` | Gauge | 1 | Telemetry quality score (0-100) evaluated by Trust Center |
159
+
160
+ ---
161
+
162
+ ## License
163
+
164
+ Apache License 2.0
zooid-0.1.0/README.md ADDED
@@ -0,0 +1,123 @@
1
+ # zooid
2
+
3
+ `zooid` provides OpenTelemetry auto-instrumentation and SDK helpers specifically engineered for conversational Voice AI applications (such as speech-to-speech agents, streaming LLM cascades, and voice bots) along with Telemetry Trust Center scoring for **SigNoz**.
4
+
5
+ It helps you track critical voice metrics like Time-To-First-Audio (TTFA), token stream latencies, interruptions, and multi-stage (STT -> LLM -> TTS) timing boundaries.
6
+
7
+ ---
8
+
9
+ ## Installation
10
+
11
+ ```bash
12
+ pip install zooid
13
+ ```
14
+
15
+ For local development within this workspace:
16
+ ```bash
17
+ pip install -e .
18
+ ```
19
+
20
+ ---
21
+
22
+ ## Quick Start
23
+
24
+ ### 1. Initialize Instrumentation
25
+
26
+ Initialize OpenTelemetry providers and the Telemetry Trust Center at your application entry point:
27
+
28
+ ```python
29
+ from zooid import instrument_voice_app
30
+
31
+ handle = instrument_voice_app(
32
+ service_name="voice-assistant-service",
33
+ signoz_endpoint="localhost:4317",
34
+ insecure=True,
35
+ enable_trust_center=True
36
+ )
37
+ ```
38
+
39
+ ### 2. Trace Voice Turns
40
+
41
+ Wrap your conversational turns using the async context manager or decorator:
42
+
43
+ ```python
44
+ import asyncio
45
+ from zooid import VoiceTurnContext, voice_turn
46
+
47
+ # Option A: Async Context Manager (Recommended)
48
+ async def process_turn(audio_stream):
49
+ async with VoiceTurnContext(architecture_mode="cascade") as turn:
50
+ # 1. Speech-to-Text
51
+ text = await process_stt(audio_stream)
52
+ turn.mark_stt_complete()
53
+
54
+ # 2. LLM Streaming
55
+ async for chunk in stream_llm(text):
56
+ if turn.llm_first_token_ms is None:
57
+ turn.mark_llm_first_token()
58
+
59
+ # 3. Text-to-Speech Output
60
+ audio_out = await generate_tts(chunk)
61
+ turn.mark_first_audio() # Captures TTFA metric
62
+
63
+ # Option B: Decorator
64
+ @voice_turn(architecture_mode="hybrid")
65
+ async def handle_turn(input_data):
66
+ current_turn = VoiceTurnContext.get_current()
67
+ # Execute turn logic...
68
+ ```
69
+
70
+ ---
71
+
72
+ ## Core Features
73
+
74
+ - **Automatic TTFA Tracking:** Dedicated timing hooks to accurately record Time-To-First-Audio.
75
+ - **Stage Latency Isolation:** Measure STT duration, LLM Time-To-First-Token (TTFT), and TTS generation independently.
76
+ - **Telemetry Trust Center:** Live span quality evaluation calculating a score (0-100) with critical violation detection.
77
+ - **Asyncio Context Propagation:** Preserves OpenTelemetry trace context across `asyncio.create_task()` background loops.
78
+
79
+ ---
80
+
81
+ ## API Reference
82
+
83
+ ### `instrument_voice_app(...)`
84
+ Initializes OpenTelemetry Tracer and Meter Providers configured for SigNoz OTLP gRPC export.
85
+
86
+ ```python
87
+ def instrument_voice_app(
88
+ service_name: str = 'voice-agent',
89
+ signoz_endpoint: str = 'localhost:4317',
90
+ insecure: bool = True,
91
+ enable_trust_center: bool = True,
92
+ trust_center_mode: str = 'template',
93
+ llm_endpoint: Optional[str] = None,
94
+ export_interval_ms: int = 5000
95
+ ) -> InstrumentationHandle
96
+ ```
97
+
98
+ ### `VoiceTurnContext`
99
+ Context manager for tracking voice turn timing and metrics.
100
+
101
+ - `VoiceTurnContext.get_current()`: Returns the active `VoiceTurnContext` instance for the current `asyncio` context.
102
+ - `turn.mark_stt_complete()`: Marks STT processing completion and records STT duration.
103
+ - `turn.mark_llm_first_token()`: Marks the arrival of the first LLM token stream chunk.
104
+ - `turn.mark_first_audio()`: Marks the output of the first synthesized audio chunk and exports the TTFA metric.
105
+
106
+ ---
107
+
108
+ ## Metrics Reference
109
+
110
+ | Metric Name | Type | Unit | Description |
111
+ |---|---|---|---|
112
+ | `voice.time_to_first_audio_ms` | Histogram | ms | Time from user turn start to first synthesized audio |
113
+ | `voice.stt_duration_ms` | Histogram | ms | Speech-To-Text processing duration |
114
+ | `voice.llm_first_token_ms` | Histogram | ms | LLM Time-To-First-Token latency |
115
+ | `voice.turns_total` | Counter | 1 | Total number of conversational turns processed |
116
+ | `voice.interruptions_total` | Counter | 1 | Total number of user interruptions recorded |
117
+ | `instrumentation.score` | Gauge | 1 | Telemetry quality score (0-100) evaluated by Trust Center |
118
+
119
+ ---
120
+
121
+ ## License
122
+
123
+ Apache License 2.0
@@ -0,0 +1,102 @@
1
+ {
2
+ "title": "Zooid Trust Center",
3
+ "description": "Dashboard for voice agent instrumentation scoring and health",
4
+ "widgets": [
5
+ {
6
+ "id": "w1",
7
+ "title": "Instrumentation Score",
8
+ "description": "Average instrumentation score across services",
9
+ "panelType": "value",
10
+ "query": {
11
+ "metrics": [
12
+ {
13
+ "name": "instrumentation_score",
14
+ "aggregate": "avg",
15
+ "groupBy": ["service_name"]
16
+ }
17
+ ]
18
+ },
19
+ "layout": { "w": 4, "h": 2, "x": 0, "y": 0 }
20
+ },
21
+ {
22
+ "id": "w2",
23
+ "title": "Score by Service",
24
+ "description": "Detailed scores per service",
25
+ "panelType": "table",
26
+ "query": {
27
+ "metrics": [
28
+ {
29
+ "name": "instrumentation_score",
30
+ "aggregate": "avg",
31
+ "groupBy": ["service_name"]
32
+ }
33
+ ]
34
+ },
35
+ "layout": { "w": 8, "h": 4, "x": 4, "y": 0 }
36
+ },
37
+ {
38
+ "id": "w3",
39
+ "title": "Score Trend",
40
+ "description": "Score over time",
41
+ "panelType": "graph",
42
+ "query": {
43
+ "metrics": [
44
+ {
45
+ "name": "instrumentation_score",
46
+ "aggregate": "avg",
47
+ "groupBy": ["service_name"]
48
+ }
49
+ ]
50
+ },
51
+ "layout": { "w": 6, "h": 4, "x": 0, "y": 2 }
52
+ },
53
+ {
54
+ "id": "w4",
55
+ "title": "Top Violations",
56
+ "description": "Most frequent instrumentation violations",
57
+ "panelType": "bar",
58
+ "query": {
59
+ "metrics": [
60
+ {
61
+ "name": "instrumentation_violations_total",
62
+ "aggregate": "sum",
63
+ "groupBy": ["rule_id"]
64
+ }
65
+ ]
66
+ },
67
+ "layout": { "w": 6, "h": 4, "x": 6, "y": 4 }
68
+ },
69
+ {
70
+ "id": "w5",
71
+ "title": "Unscorable Spans",
72
+ "description": "Total unscorable spans",
73
+ "panelType": "value",
74
+ "query": {
75
+ "metrics": [
76
+ {
77
+ "name": "instrumentation_unscorable_total",
78
+ "aggregate": "sum"
79
+ }
80
+ ]
81
+ },
82
+ "layout": { "w": 4, "h": 2, "x": 0, "y": 6 }
83
+ },
84
+ {
85
+ "id": "w6",
86
+ "title": "Category Distribution",
87
+ "description": "Distribution of violation categories",
88
+ "panelType": "pie",
89
+ "query": {
90
+ "metrics": [
91
+ {
92
+ "name": "instrumentation_violations_total",
93
+ "aggregate": "sum",
94
+ "groupBy": ["category"]
95
+ }
96
+ ]
97
+ },
98
+ "layout": { "w": 4, "h": 4, "x": 4, "y": 6 }
99
+ }
100
+ ],
101
+ "layout": []
102
+ }
@@ -0,0 +1,114 @@
1
+ {
2
+ "title": "Voice Agent Dashboard",
3
+ "description": "Performance and health metrics for voice agents",
4
+ "widgets": [
5
+ {
6
+ "id": "w1",
7
+ "title": "TTFA (p50)",
8
+ "description": "Time to First Audio (50th percentile)",
9
+ "panelType": "value",
10
+ "query": {
11
+ "metrics": [
12
+ {
13
+ "name": "voice_time_to_first_audio_ms",
14
+ "aggregate": "p50"
15
+ }
16
+ ]
17
+ },
18
+ "layout": { "w": 4, "h": 2, "x": 0, "y": 0 }
19
+ },
20
+ {
21
+ "id": "w2",
22
+ "title": "TTFA Distribution",
23
+ "description": "Histogram of Time to First Audio",
24
+ "panelType": "graph",
25
+ "query": {
26
+ "metrics": [
27
+ {
28
+ "name": "voice_ttfa_distribution",
29
+ "aggregate": "sum"
30
+ }
31
+ ]
32
+ },
33
+ "layout": { "w": 8, "h": 4, "x": 4, "y": 0 }
34
+ },
35
+ {
36
+ "id": "w3",
37
+ "title": "TTFA by Architecture",
38
+ "description": "Time to First Audio categorized by voice architecture",
39
+ "panelType": "bar",
40
+ "query": {
41
+ "metrics": [
42
+ {
43
+ "name": "voice_time_to_first_audio_ms",
44
+ "aggregate": "avg",
45
+ "groupBy": ["voice_architecture"]
46
+ }
47
+ ]
48
+ },
49
+ "layout": { "w": 6, "h": 4, "x": 0, "y": 2 }
50
+ },
51
+ {
52
+ "id": "w4",
53
+ "title": "Stage Latency",
54
+ "description": "Latency for STT, LLM, TTS stages",
55
+ "panelType": "table",
56
+ "query": {
57
+ "metrics": [
58
+ {
59
+ "name": "voice_stage_latency_ms",
60
+ "aggregate": "avg",
61
+ "groupBy": ["stage_name"]
62
+ }
63
+ ]
64
+ },
65
+ "layout": { "w": 6, "h": 4, "x": 6, "y": 4 }
66
+ },
67
+ {
68
+ "id": "w5",
69
+ "title": "Total Turns",
70
+ "description": "Total number of conversational turns",
71
+ "panelType": "value",
72
+ "query": {
73
+ "metrics": [
74
+ {
75
+ "name": "voice_turns_total",
76
+ "aggregate": "sum"
77
+ }
78
+ ]
79
+ },
80
+ "layout": { "w": 4, "h": 2, "x": 0, "y": 6 }
81
+ },
82
+ {
83
+ "id": "w6",
84
+ "title": "Error Rate",
85
+ "description": "Percentage of turns with errors",
86
+ "panelType": "value",
87
+ "query": {
88
+ "metrics": [
89
+ {
90
+ "name": "voice_errors_total",
91
+ "aggregate": "sum"
92
+ }
93
+ ]
94
+ },
95
+ "layout": { "w": 4, "h": 2, "x": 4, "y": 6 }
96
+ },
97
+ {
98
+ "id": "w7",
99
+ "title": "Interruptions",
100
+ "description": "User interruptions during generation",
101
+ "panelType": "value",
102
+ "query": {
103
+ "metrics": [
104
+ {
105
+ "name": "voice_interruptions_total",
106
+ "aggregate": "sum"
107
+ }
108
+ ]
109
+ },
110
+ "layout": { "w": 4, "h": 2, "x": 8, "y": 6 }
111
+ }
112
+ ],
113
+ "layout": []
114
+ }
@@ -0,0 +1,64 @@
1
+ import asyncio
2
+ import random
3
+ import time
4
+ from zooid import instrument_voice_app, voice_turn, VoiceTurnContext
5
+
6
+ from opentelemetry import trace
7
+
8
+ # Initialize instrumentation for the demo
9
+ instrument_voice_app(service_name='demo-voice-agent', signoz_endpoint='localhost:4317')
10
+
11
+ @voice_turn()
12
+ async def process_turn(turn_idx: int):
13
+ print(f"--- Starting Turn {turn_idx} ---")
14
+ context = VoiceTurnContext.get_current()
15
+
16
+ # 1. STT Phase
17
+ with context.tracer.start_as_current_span("stt.transcribe") as span:
18
+ print("Listening...")
19
+ # Intentional "bad" instrumentation for turn 3
20
+ if turn_idx != 3:
21
+ span.set_attribute("gen_ai.system", "deepgram")
22
+ await asyncio.sleep(random.uniform(0.15, 0.25))
23
+ transcript = "Hello, how are you?"
24
+ span.set_attribute("stt.transcript", transcript)
25
+
26
+ # 2. LLM Phase
27
+ with context.tracer.start_as_current_span("llm.generate") as span:
28
+ print("Thinking...")
29
+ span.set_attribute("gen_ai.system", "openai")
30
+ span.set_attribute("llm.model", "gpt-4o-mini")
31
+
32
+ # Simulate LLM streaming and latency
33
+ await asyncio.sleep(random.uniform(0.2, 0.4))
34
+
35
+ if turn_idx == 7: # Simulate an error
36
+ span.record_exception(Exception("LLM API Timeout"))
37
+ span.set_status(2, "Error occurred") # Status.ERROR = 2
38
+ print("LLM Error!")
39
+ return
40
+
41
+ response_text = "I am doing great, thank you!"
42
+
43
+ # 3. TTS Phase
44
+ with context.tracer.start_as_current_span("tts.synthesize") as span:
45
+ print("Speaking...")
46
+ span.set_attribute("gen_ai.system", "elevenlabs")
47
+
48
+ await asyncio.sleep(random.uniform(0.05, 0.15))
49
+
50
+ # Mark time to first audio
51
+ context.record_ttfa()
52
+
53
+ await asyncio.sleep(0.5) # Simulate audio playing out
54
+ print("Finished speaking.")
55
+
56
+ async def main():
57
+ print("Starting simulated voice agent...")
58
+ for i in range(1, 11):
59
+ await process_turn(i)
60
+ await asyncio.sleep(1)
61
+ print("Simulation complete.")
62
+
63
+ if __name__ == "__main__":
64
+ asyncio.run(main())
@@ -0,0 +1,14 @@
1
+ version: "3"
2
+ services:
3
+ # This is a reference docker-compose for running examples.
4
+ # It assumes you have the main SigNoz stack running in the zooid-net network.
5
+ example-agent:
6
+ build: .
7
+ environment:
8
+ - OTEL_EXPORTER_OTLP_ENDPOINT=http://signoz-otel-collector:4317
9
+ networks:
10
+ - zooid-net
11
+
12
+ networks:
13
+ zooid-net:
14
+ external: true
@@ -0,0 +1,28 @@
1
+ import asyncio
2
+ from zooid import instrument_voice_app, voice_turn
3
+
4
+ # NOTE: This is a structural example showing how you might integrate with Pipecat.
5
+ # It assumes a typical Pipecat pipeline setup.
6
+
7
+ # instrument_voice_app(service_name='pipecat-voice-agent')
8
+
9
+ @voice_turn
10
+ async def handle_user_input(pipeline, user_audio):
11
+ """
12
+ In a real Pipecat app, you might wrap your main event handlers
13
+ or pipeline execution points with the @voice_turn decorator.
14
+ """
15
+ print("Processing user audio through Pipecat pipeline...")
16
+ # await pipeline.process(user_audio)
17
+ await asyncio.sleep(0.5)
18
+ print("Response generated.")
19
+
20
+ async def main():
21
+ print("Pipecat integration example (mocked)")
22
+ # pipeline = build_pipeline()
23
+ # while True:
24
+ # audio = get_audio()
25
+ # await handle_user_input(pipeline, audio)
26
+
27
+ if __name__ == "__main__":
28
+ asyncio.run(main())