netra-zen 1.0.9__py3-none-any.whl → 1.0.11__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.
@@ -1,75 +1,75 @@
1
- #!/usr/bin/env python3
2
- """Embed telemetry credentials for release builds.
3
-
4
- Usage:
5
- COMMUNITY_CREDENTIALS="<base64-json>" python scripts/embed_release_credentials.py
6
- """
7
-
8
- from __future__ import annotations
9
-
10
- import base64
11
- import json
12
- import os
13
- import sys
14
- from pathlib import Path
15
-
16
-
17
- PROJECT_ROOT = Path(__file__).resolve().parents[1]
18
- TARGET_FILE = PROJECT_ROOT / "zen" / "telemetry" / "embedded_credentials.py"
19
-
20
-
21
- def main() -> int:
22
- encoded = os.getenv("COMMUNITY_CREDENTIALS", "").strip()
23
- if not encoded:
24
- print(
25
- "COMMUNITY_CREDENTIALS is not set. Set the base64-encoded "
26
- "service-account JSON before running this script.",
27
- file=sys.stderr,
28
- )
29
- return 1
30
-
31
- try:
32
- decoded = base64.b64decode(encoded)
33
- info = json.loads(decoded)
34
- except Exception as exc: # pragma: no cover - defensive guard
35
- print(f"Failed to decode telemetry credentials: {exc}", file=sys.stderr)
36
- return 2
37
-
38
- project_id = info.get("project_id", "netra-telemetry-public")
39
- encoded_literal = repr(encoded)
40
-
41
- generated = f'''"""Embedded telemetry credentials. AUTO-GENERATED - DO NOT COMMIT."""
42
-
43
- import base64
44
- import json
45
- from google.oauth2 import service_account
46
-
47
- _EMBEDDED_CREDENTIALS_B64 = {encoded_literal}
48
- _CREDENTIALS_DICT = json.loads(
49
- base64.b64decode(_EMBEDDED_CREDENTIALS_B64.encode("utf-8"))
50
- )
51
-
52
-
53
- def get_embedded_credentials():
54
- """Return service account credentials."""
55
- try:
56
- return service_account.Credentials.from_service_account_info(
57
- _CREDENTIALS_DICT,
58
- scopes=["https://www.googleapis.com/auth/trace.append"],
59
- )
60
- except Exception:
61
- return None
62
-
63
-
64
- def get_project_id() -> str:
65
- """Return GCP project ID."""
66
- return _CREDENTIALS_DICT.get("project_id", {project_id!r})
67
- '''
68
-
69
- TARGET_FILE.write_text(generated)
70
- print(f"Embedded release credentials written to {TARGET_FILE.relative_to(PROJECT_ROOT)}")
71
- return 0
72
-
73
-
74
- if __name__ == "__main__":
75
- raise SystemExit(main())
1
+ #!/usr/bin/env python3
2
+ """Embed telemetry credentials for release builds.
3
+
4
+ Usage:
5
+ COMMUNITY_CREDENTIALS="<base64-json>" python scripts/embed_release_credentials.py
6
+ """
7
+
8
+ from __future__ import annotations
9
+
10
+ import base64
11
+ import json
12
+ import os
13
+ import sys
14
+ from pathlib import Path
15
+
16
+
17
+ PROJECT_ROOT = Path(__file__).resolve().parents[1]
18
+ TARGET_FILE = PROJECT_ROOT / "zen" / "telemetry" / "embedded_credentials.py"
19
+
20
+
21
+ def main() -> int:
22
+ encoded = os.getenv("COMMUNITY_CREDENTIALS", "").strip()
23
+ if not encoded:
24
+ print(
25
+ "COMMUNITY_CREDENTIALS is not set. Set the base64-encoded "
26
+ "service-account JSON before running this script.",
27
+ file=sys.stderr,
28
+ )
29
+ return 1
30
+
31
+ try:
32
+ decoded = base64.b64decode(encoded)
33
+ info = json.loads(decoded)
34
+ except Exception as exc: # pragma: no cover - defensive guard
35
+ print(f"Failed to decode telemetry credentials: {exc}", file=sys.stderr)
36
+ return 2
37
+
38
+ project_id = info.get("project_id", "netra-telemetry-public")
39
+ encoded_literal = repr(encoded)
40
+
41
+ generated = f'''"""Embedded telemetry credentials. AUTO-GENERATED - DO NOT COMMIT."""
42
+
43
+ import base64
44
+ import json
45
+ from google.oauth2 import service_account
46
+
47
+ _EMBEDDED_CREDENTIALS_B64 = {encoded_literal}
48
+ _CREDENTIALS_DICT = json.loads(
49
+ base64.b64decode(_EMBEDDED_CREDENTIALS_B64.encode("utf-8"))
50
+ )
51
+
52
+
53
+ def get_embedded_credentials():
54
+ """Return service account credentials."""
55
+ try:
56
+ return service_account.Credentials.from_service_account_info(
57
+ _CREDENTIALS_DICT,
58
+ scopes=["https://www.googleapis.com/auth/trace.append"],
59
+ )
60
+ except Exception:
61
+ return None
62
+
63
+
64
+ def get_project_id() -> str:
65
+ """Return GCP project ID."""
66
+ return _CREDENTIALS_DICT.get("project_id", {project_id!r})
67
+ '''
68
+
69
+ TARGET_FILE.write_text(generated)
70
+ print(f"Embedded release credentials written to {TARGET_FILE.relative_to(PROJECT_ROOT)}")
71
+ return 0
72
+
73
+
74
+ if __name__ == "__main__":
75
+ raise SystemExit(main())
@@ -0,0 +1,221 @@
1
+ #!/usr/bin/env python3
2
+ """
3
+ Debug script to test apex telemetry and identify why spans aren't appearing in Cloud Trace.
4
+ Run this after setting COMMUNITY_CREDENTIALS to diagnose the issue.
5
+ """
6
+
7
+ import sys
8
+ import logging
9
+ from pathlib import Path
10
+
11
+ # Add project to path
12
+ sys.path.insert(0, str(Path(__file__).parent.parent))
13
+
14
+ # Enable debug logging
15
+ logging.basicConfig(
16
+ level=logging.DEBUG,
17
+ format='%(asctime)s - %(name)s - %(levelname)s - %(message)s'
18
+ )
19
+
20
+ def test_telemetry_manager():
21
+ """Test that telemetry manager is properly initialized."""
22
+ print("=" * 80)
23
+ print("TEST 1: Telemetry Manager Initialization")
24
+ print("=" * 80)
25
+
26
+ from zen.telemetry import telemetry_manager
27
+
28
+ print(f"Telemetry manager type: {type(telemetry_manager)}")
29
+ print(f"Is enabled: {telemetry_manager.is_enabled()}")
30
+
31
+ if hasattr(telemetry_manager, '_tracer'):
32
+ print(f"Has _tracer: {telemetry_manager._tracer is not None}")
33
+ else:
34
+ print("❌ No _tracer attribute")
35
+
36
+ if hasattr(telemetry_manager, '_provider'):
37
+ print(f"Has _provider: {telemetry_manager._provider is not None}")
38
+ else:
39
+ print("❌ No _provider attribute")
40
+
41
+ print()
42
+ return telemetry_manager.is_enabled()
43
+
44
+
45
+ def test_apex_wrapper_import():
46
+ """Test that apex wrapper can be imported."""
47
+ print("=" * 80)
48
+ print("TEST 2: Apex Telemetry Wrapper Import")
49
+ print("=" * 80)
50
+
51
+ try:
52
+ from zen.telemetry.apex_telemetry import ApexTelemetryWrapper
53
+ print("✅ ApexTelemetryWrapper imported successfully")
54
+
55
+ wrapper = ApexTelemetryWrapper()
56
+ print(f"✅ Wrapper instance created: {type(wrapper)}")
57
+ print()
58
+ return True
59
+ except Exception as e:
60
+ print(f"❌ Failed to import ApexTelemetryWrapper: {e}")
61
+ import traceback
62
+ traceback.print_exc()
63
+ print()
64
+ return False
65
+
66
+
67
+ def test_manual_span_emission():
68
+ """Test manual span emission using telemetry manager."""
69
+ print("=" * 80)
70
+ print("TEST 3: Manual Span Emission")
71
+ print("=" * 80)
72
+
73
+ from zen.telemetry import telemetry_manager
74
+
75
+ if not telemetry_manager.is_enabled():
76
+ print("⚠️ Telemetry is not enabled - skipping test")
77
+ print()
78
+ return False
79
+
80
+ try:
81
+ from opentelemetry.trace import SpanKind
82
+
83
+ print("Creating test span...")
84
+ with telemetry_manager._tracer.start_as_current_span(
85
+ "test.apex.span", kind=SpanKind.INTERNAL
86
+ ) as span:
87
+ span.set_attribute("test.type", "manual")
88
+ span.set_attribute("test.value", 123)
89
+ print("✅ Span created and attributes set")
90
+
91
+ print("Flushing provider...")
92
+ if hasattr(telemetry_manager, '_provider') and telemetry_manager._provider:
93
+ telemetry_manager._provider.force_flush(timeout_millis=5000)
94
+ print("✅ Provider flushed")
95
+
96
+ print("✅ Manual span test completed")
97
+ print(" Check Cloud Trace for span: 'test.apex.span'")
98
+ print()
99
+ return True
100
+
101
+ except Exception as e:
102
+ print(f"❌ Manual span emission failed: {e}")
103
+ import traceback
104
+ traceback.print_exc()
105
+ print()
106
+ return False
107
+
108
+
109
+ def test_apex_wrapper_emission():
110
+ """Test apex wrapper span emission."""
111
+ print("=" * 80)
112
+ print("TEST 4: Apex Wrapper Span Emission")
113
+ print("=" * 80)
114
+
115
+ from zen.telemetry.apex_telemetry import ApexTelemetryWrapper
116
+
117
+ wrapper = ApexTelemetryWrapper()
118
+ wrapper.start_time = 1000.0
119
+ wrapper.end_time = 1010.0
120
+ wrapper.exit_code = 0
121
+ wrapper.message = "test apex telemetry debug"
122
+ wrapper.env = "staging"
123
+ wrapper.stdout = ""
124
+ wrapper.stderr = ""
125
+
126
+ print("Emitting telemetry with wrapper...")
127
+ try:
128
+ wrapper._emit_telemetry()
129
+ print("✅ Wrapper._emit_telemetry() completed")
130
+ print(" Check Cloud Trace for span: 'apex.instance'")
131
+ print()
132
+ return True
133
+ except Exception as e:
134
+ print(f"❌ Wrapper emission failed: {e}")
135
+ import traceback
136
+ traceback.print_exc()
137
+ print()
138
+ return False
139
+
140
+
141
+ def test_credentials():
142
+ """Test credential loading."""
143
+ print("=" * 80)
144
+ print("TEST 5: Credential Loading")
145
+ print("=" * 80)
146
+
147
+ from zen.telemetry import get_embedded_credentials, get_project_id
148
+
149
+ creds = get_embedded_credentials()
150
+ if creds:
151
+ print(f"✅ Credentials loaded")
152
+ project_id = get_project_id()
153
+ print(f"✅ Project ID: {project_id}")
154
+ print()
155
+ return True
156
+ else:
157
+ print("❌ No credentials found")
158
+ print(" Set COMMUNITY_CREDENTIALS environment variable")
159
+ print()
160
+ return False
161
+
162
+
163
+ def main():
164
+ """Run all diagnostic tests."""
165
+ print("\n🔍 APEX TELEMETRY DEBUG TESTS")
166
+ print("=" * 80)
167
+
168
+ results = {}
169
+
170
+ results['credentials'] = test_credentials()
171
+ results['telemetry_manager'] = test_telemetry_manager()
172
+ results['apex_wrapper_import'] = test_apex_wrapper_import()
173
+
174
+ if results['telemetry_manager']:
175
+ results['manual_span'] = test_manual_span_emission()
176
+ results['apex_wrapper'] = test_apex_wrapper_emission()
177
+ else:
178
+ print("⚠️ Skipping span tests - telemetry not enabled")
179
+ results['manual_span'] = False
180
+ results['apex_wrapper'] = False
181
+
182
+ # Summary
183
+ print("=" * 80)
184
+ print("SUMMARY")
185
+ print("=" * 80)
186
+
187
+ for test_name, passed in results.items():
188
+ status = "✅ PASS" if passed else "❌ FAIL"
189
+ print(f"{status:10} {test_name}")
190
+
191
+ print()
192
+
193
+ if all(results.values()):
194
+ print("✅ ALL TESTS PASSED!")
195
+ print("\nIf spans still don't appear in Cloud Trace:")
196
+ print(" 1. Wait 60 seconds (BatchSpanProcessor batches spans)")
197
+ print(" 2. Check Cloud Trace console")
198
+ print(" 3. Verify project ID matches your GCP setup")
199
+ print(" 4. Check service account has cloudtrace.traces.patch permission")
200
+ return 0
201
+ else:
202
+ print("❌ SOME TESTS FAILED")
203
+ print("\nTroubleshooting:")
204
+
205
+ if not results['credentials']:
206
+ print(" • Set COMMUNITY_CREDENTIALS: export COMMUNITY_CREDENTIALS='<base64-json>'")
207
+
208
+ if not results['telemetry_manager']:
209
+ print(" • Telemetry manager not initialized - check credentials")
210
+
211
+ if results['telemetry_manager'] and not results['manual_span']:
212
+ print(" • Manual span failed - check OpenTelemetry setup")
213
+
214
+ if results['telemetry_manager'] and not results['apex_wrapper']:
215
+ print(" • Apex wrapper failed - check implementation")
216
+
217
+ return 1
218
+
219
+
220
+ if __name__ == "__main__":
221
+ sys.exit(main())
@@ -1,140 +1,140 @@
1
- #!/usr/bin/env python3
2
- """
3
- Verification script to prove JSONL logs are bundled in payload
4
- """
5
-
6
- import json
7
- import sys
8
- from pathlib import Path
9
-
10
- # Add parent directory to path
11
- sys.path.insert(0, str(Path(__file__).parent.parent))
12
-
13
- from scripts.agent_logs import collect_recent_logs
14
-
15
-
16
- def verify_log_bundling(log_path: str):
17
- """
18
- Verify that logs are properly collected and bundled
19
-
20
- Args:
21
- log_path: Path to JSONL file or directory
22
- """
23
- print("=" * 70)
24
- print("JSONL LOG TRANSMISSION VERIFICATION")
25
- print("=" * 70)
26
- print()
27
-
28
- # Step 1: Collect logs
29
- print("Step 1: Collecting logs from file...")
30
- result = collect_recent_logs(limit=1, base_path=log_path)
31
-
32
- if not result:
33
- print("❌ FAILED: No logs collected")
34
- return False
35
-
36
- logs, files_read, file_info = result
37
- print(f"✓ Successfully collected {len(logs)} log entries from {files_read} file(s)")
38
- print()
39
-
40
- # Step 2: Show file details
41
- print("Step 2: File details...")
42
- for info in file_info:
43
- print(f" File: {info['name']}")
44
- print(f" Hash: {info['hash']}")
45
- print(f" Entries: {info['entries']}")
46
- print()
47
-
48
- # Step 3: Simulate payload creation
49
- print("Step 3: Simulating WebSocket payload creation...")
50
- payload = {
51
- "type": "message_create",
52
- "run_id": "test-run-id",
53
- "payload": {
54
- "message": "Test message with logs",
55
- "jsonl_logs": logs # This is where logs are added
56
- }
57
- }
58
-
59
- print(f"✓ Payload created with 'jsonl_logs' key")
60
- print(f" Payload keys: {list(payload['payload'].keys())}")
61
- print()
62
-
63
- # Step 4: Verify payload size
64
- print("Step 4: Calculating payload size...")
65
- payload_json = json.dumps(payload)
66
- payload_size_bytes = len(payload_json.encode('utf-8'))
67
- payload_size_kb = payload_size_bytes / 1024
68
- payload_size_mb = payload_size_kb / 1024
69
-
70
- if payload_size_mb >= 1:
71
- size_str = f"{payload_size_mb:.2f} MB"
72
- elif payload_size_kb >= 1:
73
- size_str = f"{payload_size_kb:.2f} KB"
74
- else:
75
- size_str = f"{payload_size_bytes} bytes"
76
-
77
- print(f"✓ Total payload size: {size_str}")
78
- print()
79
-
80
- # Step 5: Show sample log entries
81
- print("Step 5: Sample log entries in payload...")
82
- if logs:
83
- print(f" First entry keys: {list(logs[0].keys())}")
84
- print(f" First entry timestamp: {logs[0].get('timestamp', 'N/A')}")
85
- print(f" Last entry timestamp: {logs[-1].get('timestamp', 'N/A')}")
86
- print()
87
-
88
- # Step 6: Verify transmission-ready
89
- print("Step 6: Transmission verification...")
90
- print(f"✓ Payload is valid JSON: {payload_json is not None}")
91
- print(f"✓ Payload contains 'jsonl_logs': {'jsonl_logs' in payload['payload']}")
92
- print(f"✓ Log count in payload: {len(payload['payload']['jsonl_logs'])}")
93
- print()
94
-
95
- print("=" * 70)
96
- print("✅ VERIFICATION COMPLETE")
97
- print("=" * 70)
98
- print()
99
- print("PROOF OF TRANSMISSION:")
100
- print(f" • {len(logs)} JSONL log entries are bundled in the payload")
101
- print(f" • Payload size: {size_str}")
102
- print(f" • Ready for WebSocket transmission to backend")
103
- print()
104
-
105
- # Optional: Save proof file
106
- proof_file = Path("/tmp/zen_transmission_proof.json")
107
- proof_payload = {
108
- "verification_timestamp": "verification_run",
109
- "log_count": len(logs),
110
- "files_read": files_read,
111
- "file_info": file_info,
112
- "payload_size": size_str,
113
- "sample_first_entry": logs[0] if logs else None,
114
- "sample_last_entry": logs[-1] if logs else None,
115
- "payload_structure": {
116
- "type": payload["type"],
117
- "run_id": payload["run_id"],
118
- "payload_keys": list(payload["payload"].keys()),
119
- "jsonl_logs_present": "jsonl_logs" in payload["payload"],
120
- "jsonl_logs_count": len(payload["payload"]["jsonl_logs"])
121
- }
122
- }
123
-
124
- with open(proof_file, 'w') as f:
125
- json.dump(proof_payload, f, indent=2)
126
-
127
- print(f"📝 Detailed proof saved to: {proof_file}")
128
- print()
129
-
130
- return True
131
-
132
-
133
- if __name__ == "__main__":
134
- if len(sys.argv) < 2:
135
- print("Usage: python verify_log_transmission.py <path-to-jsonl-file>")
136
- sys.exit(1)
137
-
138
- log_path = sys.argv[1]
139
- success = verify_log_bundling(log_path)
140
- sys.exit(0 if success else 1)
1
+ #!/usr/bin/env python3
2
+ """
3
+ Verification script to prove JSONL logs are bundled in payload
4
+ """
5
+
6
+ import json
7
+ import sys
8
+ from pathlib import Path
9
+
10
+ # Add parent directory to path
11
+ sys.path.insert(0, str(Path(__file__).parent.parent))
12
+
13
+ from scripts.agent_logs import collect_recent_logs
14
+
15
+
16
+ def verify_log_bundling(log_path: str):
17
+ """
18
+ Verify that logs are properly collected and bundled
19
+
20
+ Args:
21
+ log_path: Path to JSONL file or directory
22
+ """
23
+ print("=" * 70)
24
+ print("JSONL LOG TRANSMISSION VERIFICATION")
25
+ print("=" * 70)
26
+ print()
27
+
28
+ # Step 1: Collect logs
29
+ print("Step 1: Collecting logs from file...")
30
+ result = collect_recent_logs(limit=1, base_path=log_path)
31
+
32
+ if not result:
33
+ print("❌ FAILED: No logs collected")
34
+ return False
35
+
36
+ logs, files_read, file_info = result
37
+ print(f"✓ Successfully collected {len(logs)} log entries from {files_read} file(s)")
38
+ print()
39
+
40
+ # Step 2: Show file details
41
+ print("Step 2: File details...")
42
+ for info in file_info:
43
+ print(f" File: {info['name']}")
44
+ print(f" Hash: {info['hash']}")
45
+ print(f" Entries: {info['entries']}")
46
+ print()
47
+
48
+ # Step 3: Simulate payload creation
49
+ print("Step 3: Simulating WebSocket payload creation...")
50
+ payload = {
51
+ "type": "message_create",
52
+ "run_id": "test-run-id",
53
+ "payload": {
54
+ "message": "Test message with logs",
55
+ "jsonl_logs": logs # This is where logs are added
56
+ }
57
+ }
58
+
59
+ print(f"✓ Payload created with 'jsonl_logs' key")
60
+ print(f" Payload keys: {list(payload['payload'].keys())}")
61
+ print()
62
+
63
+ # Step 4: Verify payload size
64
+ print("Step 4: Calculating payload size...")
65
+ payload_json = json.dumps(payload)
66
+ payload_size_bytes = len(payload_json.encode('utf-8'))
67
+ payload_size_kb = payload_size_bytes / 1024
68
+ payload_size_mb = payload_size_kb / 1024
69
+
70
+ if payload_size_mb >= 1:
71
+ size_str = f"{payload_size_mb:.2f} MB"
72
+ elif payload_size_kb >= 1:
73
+ size_str = f"{payload_size_kb:.2f} KB"
74
+ else:
75
+ size_str = f"{payload_size_bytes} bytes"
76
+
77
+ print(f"✓ Total payload size: {size_str}")
78
+ print()
79
+
80
+ # Step 5: Show sample log entries
81
+ print("Step 5: Sample log entries in payload...")
82
+ if logs:
83
+ print(f" First entry keys: {list(logs[0].keys())}")
84
+ print(f" First entry timestamp: {logs[0].get('timestamp', 'N/A')}")
85
+ print(f" Last entry timestamp: {logs[-1].get('timestamp', 'N/A')}")
86
+ print()
87
+
88
+ # Step 6: Verify transmission-ready
89
+ print("Step 6: Transmission verification...")
90
+ print(f"✓ Payload is valid JSON: {payload_json is not None}")
91
+ print(f"✓ Payload contains 'jsonl_logs': {'jsonl_logs' in payload['payload']}")
92
+ print(f"✓ Log count in payload: {len(payload['payload']['jsonl_logs'])}")
93
+ print()
94
+
95
+ print("=" * 70)
96
+ print("✅ VERIFICATION COMPLETE")
97
+ print("=" * 70)
98
+ print()
99
+ print("PROOF OF TRANSMISSION:")
100
+ print(f" • {len(logs)} JSONL log entries are bundled in the payload")
101
+ print(f" • Payload size: {size_str}")
102
+ print(f" • Ready for WebSocket transmission to backend")
103
+ print()
104
+
105
+ # Optional: Save proof file
106
+ proof_file = Path("/tmp/zen_transmission_proof.json")
107
+ proof_payload = {
108
+ "verification_timestamp": "verification_run",
109
+ "log_count": len(logs),
110
+ "files_read": files_read,
111
+ "file_info": file_info,
112
+ "payload_size": size_str,
113
+ "sample_first_entry": logs[0] if logs else None,
114
+ "sample_last_entry": logs[-1] if logs else None,
115
+ "payload_structure": {
116
+ "type": payload["type"],
117
+ "run_id": payload["run_id"],
118
+ "payload_keys": list(payload["payload"].keys()),
119
+ "jsonl_logs_present": "jsonl_logs" in payload["payload"],
120
+ "jsonl_logs_count": len(payload["payload"]["jsonl_logs"])
121
+ }
122
+ }
123
+
124
+ with open(proof_file, 'w') as f:
125
+ json.dump(proof_payload, f, indent=2)
126
+
127
+ print(f"📝 Detailed proof saved to: {proof_file}")
128
+ print()
129
+
130
+ return True
131
+
132
+
133
+ if __name__ == "__main__":
134
+ if len(sys.argv) < 2:
135
+ print("Usage: python verify_log_transmission.py <path-to-jsonl-file>")
136
+ sys.exit(1)
137
+
138
+ log_path = sys.argv[1]
139
+ success = verify_log_bundling(log_path)
140
+ sys.exit(0 if success else 1)