kryten-robot 0.6.9__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.
kryten/CONFIG.md ADDED
@@ -0,0 +1,504 @@
1
+ # Kryten Configuration Guide
2
+
3
+ This guide explains all configuration options for the Kryten CyTube connector.
4
+
5
+ ## Quick Start
6
+
7
+ 1. Copy `config.example.json` to `config.json`
8
+ 2. Edit required fields (marked with ⚠️ below)
9
+ 3. Customize optional fields as needed
10
+ 4. Run Kryten: `python -m bot.kryten config.json`
11
+
12
+ ## Configuration File Format
13
+
14
+ Kryten uses JSON configuration files. JSON does not support comments, so this guide explains each field.
15
+
16
+ ## Configuration Sections
17
+
18
+ ### CyTube Connection (`cytube`)
19
+
20
+ Configures connection to CyTube chat server.
21
+
22
+ | Field | Type | Required | Default | Description |
23
+ |-------|------|----------|---------|-------------|
24
+ | `domain` | string | ⚠️ Yes | - | CyTube server domain (e.g., "cytu.be") |
25
+ | `channel` | string | ⚠️ Yes | - | Channel name to join (case-sensitive) |
26
+ | `channel_password` | string\|null | No | `null` | Password for password-protected channels |
27
+ | `user` | string\|null | No | `null` | Bot username for authentication |
28
+ | `password` | string\|null | No | `null` | Bot password (use env var for security) |
29
+
30
+ **Examples:**
31
+
32
+ ```json
33
+ {
34
+ "cytube": {
35
+ "domain": "cytu.be",
36
+ "channel": "MyAwesomeChannel",
37
+ "channel_password": null,
38
+ "user": "MyBot",
39
+ "password": null
40
+ }
41
+ }
42
+ ```
43
+
44
+ **Security Notes:**
45
+ - Never commit passwords to version control
46
+ - Use environment variables: `KRYTEN_CYTUBE_USER`, `KRYTEN_CYTUBE_PASSWORD`
47
+ - Set `password: null` if using guest access
48
+
49
+ ### NATS Message Bus (`nats`)
50
+
51
+ Configures connection to NATS message broker.
52
+
53
+ | Field | Type | Required | Default | Description |
54
+ |-------|------|----------|---------|-------------|
55
+ | `servers` | array[string] | ⚠️ Yes | - | NATS server URLs (e.g., ["nats://localhost:4222"]) |
56
+ | `user` | string\|null | No | `null` | NATS username for authentication |
57
+ | `password` | string\|null | No | `null` | NATS password (use env var for security) |
58
+ | `connect_timeout` | integer | No | `10` | Connection timeout in seconds |
59
+ | `reconnect_time_wait` | integer | No | `2` | Wait time between reconnects in seconds |
60
+ | `max_reconnect_attempts` | integer | No | `10` | Maximum reconnection attempts |
61
+ | `allow_reconnect` | boolean | No | `true` | Enable automatic reconnection |
62
+
63
+ **Examples:**
64
+
65
+ Development (local NATS):
66
+ ```json
67
+ {
68
+ "nats": {
69
+ "servers": ["nats://localhost:4222"],
70
+ "user": null,
71
+ "password": null,
72
+ "connect_timeout": 10,
73
+ "reconnect_time_wait": 2,
74
+ "max_reconnect_attempts": 10,
75
+ "allow_reconnect": true
76
+ }
77
+ }
78
+ ```
79
+
80
+ Production (authenticated, clustered):
81
+ ```json
82
+ {
83
+ "nats": {
84
+ "servers": [
85
+ "nats://nats1.example.com:4222",
86
+ "nats://nats2.example.com:4222",
87
+ "nats://nats3.example.com:4222"
88
+ ],
89
+ "user": "kryten_user",
90
+ "password": null,
91
+ "connect_timeout": 15,
92
+ "reconnect_time_wait": 5,
93
+ "max_reconnect_attempts": -1,
94
+ "allow_reconnect": true
95
+ }
96
+ }
97
+ ```
98
+
99
+ **Security Notes:**
100
+ - Use environment variable: `KRYTEN_NATS_URL`
101
+ - Set `max_reconnect_attempts: -1` for infinite retries in production
102
+ - Use TLS URLs for production: `tls://nats.example.com:4222`
103
+
104
+ ### Logging (`logging`)
105
+
106
+ Configures structured logging output.
107
+
108
+ | Field | Type | Required | Default | Description |
109
+ |-------|------|----------|---------|-------------|
110
+ | `level` | string | No | `"INFO"` | Global log level: DEBUG, INFO, WARNING, ERROR, CRITICAL |
111
+ | `format` | string | No | `"text"` | Output format: "text" (human-readable) or "json" (structured) |
112
+ | `output` | string | No | `"console"` | Output destination: "console" (stdout) or "file" |
113
+ | `file_path` | string\|null | No | `null` | Log file path (required if output="file") |
114
+ | `max_bytes` | integer | No | `10485760` | Max log file size before rotation (10MB default) |
115
+ | `backup_count` | integer | No | `5` | Number of backup files to keep |
116
+ | `component_levels` | object | No | `{}` | Per-component log levels (see below) |
117
+
118
+ **Valid Log Levels:**
119
+ - `DEBUG` - Detailed diagnostic information
120
+ - `INFO` - General informational messages (default)
121
+ - `WARNING` - Warning messages for unexpected events
122
+ - `ERROR` - Error messages for failures
123
+ - `CRITICAL` - Critical failures requiring immediate attention
124
+
125
+ **Examples:**
126
+
127
+ Development (console, text, verbose):
128
+ ```json
129
+ {
130
+ "logging": {
131
+ "level": "DEBUG",
132
+ "format": "text",
133
+ "output": "console",
134
+ "file_path": null,
135
+ "component_levels": {
136
+ "bot.kryten.nats_client": "DEBUG",
137
+ "bot.kryten.cytube_connector": "DEBUG"
138
+ }
139
+ }
140
+ }
141
+ ```
142
+
143
+ Production (file, JSON, structured):
144
+ ```json
145
+ {
146
+ "logging": {
147
+ "level": "INFO",
148
+ "format": "json",
149
+ "output": "file",
150
+ "file_path": "/var/log/kryten/kryten.log",
151
+ "max_bytes": 104857600,
152
+ "backup_count": 10,
153
+ "component_levels": {
154
+ "bot.kryten.nats_client": "WARNING",
155
+ "bot.kryten.health_monitor": "WARNING"
156
+ }
157
+ }
158
+ }
159
+ ```
160
+
161
+ **Component-Specific Logging:**
162
+
163
+ You can set different log levels for specific components using `component_levels`:
164
+
165
+ ```json
166
+ {
167
+ "logging": {
168
+ "level": "INFO",
169
+ "component_levels": {
170
+ "bot.kryten.nats_client": "DEBUG",
171
+ "bot.kryten.cytube_connector": "WARNING",
172
+ "bot.kryten.event_publisher": "DEBUG"
173
+ }
174
+ }
175
+ }
176
+ ```
177
+
178
+ Available components:
179
+ - `bot.kryten.nats_client` - NATS connection and publishing
180
+ - `bot.kryten.cytube_connector` - CyTube Socket.IO connection
181
+ - `bot.kryten.event_publisher` - Event bridging logic
182
+ - `bot.kryten.health_monitor` - Health check HTTP server
183
+ - `bot.kryten.shutdown_handler` - Graceful shutdown coordination
184
+
185
+ **Sensitive Data Redaction:**
186
+
187
+ Kryten automatically redacts sensitive data in logs:
188
+ - Passwords → `***REDACTED***`
189
+ - Tokens → `***REDACTED***`
190
+ - API keys → `***REDACTED***`
191
+
192
+ ### Health Monitoring (`health`)
193
+
194
+ Configures HTTP health check endpoint for operational visibility.
195
+
196
+ | Field | Type | Required | Default | Description |
197
+ |-------|------|----------|---------|-------------|
198
+ | `enabled` | boolean | No | `true` | Enable health monitoring HTTP server |
199
+ | `host` | string | No | `"0.0.0.0"` | HTTP server bind address |
200
+ | `port` | integer | No | `8080` | HTTP server port |
201
+
202
+ **Examples:**
203
+
204
+ Development (localhost only):
205
+ ```json
206
+ {
207
+ "health": {
208
+ "enabled": true,
209
+ "host": "127.0.0.1",
210
+ "port": 8080
211
+ }
212
+ }
213
+ ```
214
+
215
+ Production (all interfaces, non-standard port):
216
+ ```json
217
+ {
218
+ "health": {
219
+ "enabled": true,
220
+ "host": "0.0.0.0",
221
+ "port": 9090
222
+ }
223
+ }
224
+ ```
225
+
226
+ Disabled:
227
+ ```json
228
+ {
229
+ "health": {
230
+ "enabled": false
231
+ }
232
+ }
233
+ ```
234
+
235
+ **Health Endpoints:**
236
+
237
+ When enabled, health monitoring exposes:
238
+
239
+ - **`GET /health`** - JSON health status
240
+ - Returns 200 OK when healthy
241
+ - Returns 503 Service Unavailable when unhealthy
242
+ - Response includes component states and metrics
243
+
244
+ - **`GET /metrics`** - Prometheus-compatible metrics
245
+ - Text format for Prometheus scraping
246
+ - Includes uptime, event counts, error rates
247
+
248
+ **Example Response:**
249
+
250
+ ```json
251
+ {
252
+ "status": "healthy",
253
+ "uptime_seconds": 3600.45,
254
+ "components": {
255
+ "cytube_connector": "connected",
256
+ "nats_client": "connected",
257
+ "event_publisher": "running"
258
+ },
259
+ "metrics": {
260
+ "events_received": 15420,
261
+ "events_published": 15420,
262
+ "publish_errors": 2,
263
+ "nats_bytes_sent": 2048576
264
+ }
265
+ }
266
+ ```
267
+
268
+ **Kubernetes Integration:**
269
+
270
+ Use health endpoint for liveness and readiness probes:
271
+
272
+ ```yaml
273
+ livenessProbe:
274
+ httpGet:
275
+ path: /health
276
+ port: 8080
277
+ initialDelaySeconds: 10
278
+ periodSeconds: 30
279
+
280
+ readinessProbe:
281
+ httpGet:
282
+ path: /health
283
+ port: 8080
284
+ initialDelaySeconds: 5
285
+ periodSeconds: 10
286
+ ```
287
+
288
+ ### Legacy Top-Level Field
289
+
290
+ | Field | Type | Required | Default | Description |
291
+ |-------|------|----------|---------|-------------|
292
+ | `log_level` | string | No | `"INFO"` | **DEPRECATED**: Use `logging.level` instead |
293
+
294
+ This field is maintained for backward compatibility but will be removed in a future version.
295
+
296
+ ## Environment Variable Overrides
297
+
298
+ Kryten supports environment variables to override sensitive configuration:
299
+
300
+ | Variable | Overrides | Example |
301
+ |----------|-----------|---------|
302
+ | `KRYTEN_CYTUBE_USER` | `cytube.user` | `export KRYTEN_CYTUBE_USER=MyBot` |
303
+ | `KRYTEN_CYTUBE_PASSWORD` | `cytube.password` | `export KRYTEN_CYTUBE_PASSWORD=secret` |
304
+ | `KRYTEN_NATS_URL` | `nats.servers[0]` | `export KRYTEN_NATS_URL=nats://prod:4222` |
305
+
306
+ **Docker Example:**
307
+
308
+ ```bash
309
+ docker run -d \
310
+ -e KRYTEN_CYTUBE_USER=MyBot \
311
+ -e KRYTEN_CYTUBE_PASSWORD=secret123 \
312
+ -e KRYTEN_NATS_URL=nats://nats:4222 \
313
+ -v $(pwd)/config.json:/config/config.json \
314
+ kryten:latest /config/config.json
315
+ ```
316
+
317
+ **Kubernetes Secret:**
318
+
319
+ ```yaml
320
+ apiVersion: v1
321
+ kind: Secret
322
+ metadata:
323
+ name: kryten-secrets
324
+ type: Opaque
325
+ stringData:
326
+ KRYTEN_CYTUBE_USER: "MyBot"
327
+ KRYTEN_CYTUBE_PASSWORD: "secret123"
328
+ KRYTEN_NATS_URL: "nats://nats:4222"
329
+ ---
330
+ apiVersion: apps/v1
331
+ kind: Deployment
332
+ spec:
333
+ template:
334
+ spec:
335
+ containers:
336
+ - name: kryten
337
+ envFrom:
338
+ - secretRef:
339
+ name: kryten-secrets
340
+ ```
341
+
342
+ ## Complete Examples
343
+
344
+ ### Development Configuration
345
+
346
+ **File: `config-dev.json`**
347
+
348
+ ```json
349
+ {
350
+ "cytube": {
351
+ "domain": "cytu.be",
352
+ "channel": "test-channel",
353
+ "channel_password": null,
354
+ "user": "DevBot",
355
+ "password": null
356
+ },
357
+ "nats": {
358
+ "servers": ["nats://localhost:4222"],
359
+ "user": null,
360
+ "password": null,
361
+ "connect_timeout": 10,
362
+ "reconnect_time_wait": 2,
363
+ "max_reconnect_attempts": 10,
364
+ "allow_reconnect": true
365
+ },
366
+ "logging": {
367
+ "level": "DEBUG",
368
+ "format": "text",
369
+ "output": "console",
370
+ "file_path": null,
371
+ "max_bytes": 10485760,
372
+ "backup_count": 5,
373
+ "component_levels": {
374
+ "bot.kryten.nats_client": "DEBUG",
375
+ "bot.kryten.cytube_connector": "DEBUG",
376
+ "bot.kryten.event_publisher": "DEBUG"
377
+ }
378
+ },
379
+ "health": {
380
+ "enabled": true,
381
+ "host": "127.0.0.1",
382
+ "port": 8080
383
+ },
384
+ "log_level": "DEBUG"
385
+ }
386
+ ```
387
+
388
+ ### Production Configuration
389
+
390
+ **File: `config-prod.json`**
391
+
392
+ ```json
393
+ {
394
+ "cytube": {
395
+ "domain": "cytu.be",
396
+ "channel": "production-channel",
397
+ "channel_password": null,
398
+ "user": null,
399
+ "password": null
400
+ },
401
+ "nats": {
402
+ "servers": [
403
+ "nats://nats1.prod.example.com:4222",
404
+ "nats://nats2.prod.example.com:4222",
405
+ "nats://nats3.prod.example.com:4222"
406
+ ],
407
+ "user": "kryten_prod",
408
+ "password": null,
409
+ "connect_timeout": 15,
410
+ "reconnect_time_wait": 5,
411
+ "max_reconnect_attempts": -1,
412
+ "allow_reconnect": true
413
+ },
414
+ "logging": {
415
+ "level": "INFO",
416
+ "format": "json",
417
+ "output": "file",
418
+ "file_path": "/var/log/kryten/kryten.log",
419
+ "max_bytes": 104857600,
420
+ "backup_count": 10,
421
+ "component_levels": {
422
+ "bot.kryten.health_monitor": "WARNING"
423
+ }
424
+ },
425
+ "health": {
426
+ "enabled": true,
427
+ "host": "0.0.0.0",
428
+ "port": 8080
429
+ },
430
+ "log_level": "INFO"
431
+ }
432
+ ```
433
+
434
+ ## Validation
435
+
436
+ Test your configuration file:
437
+
438
+ ```bash
439
+ # Validate JSON syntax
440
+ python -m json.tool config.json
441
+
442
+ # Test Kryten can load it
443
+ python -c "from bot.kryten import load_config; cfg = load_config('config.json'); print('Valid!')"
444
+ ```
445
+
446
+ ## Troubleshooting
447
+
448
+ ### Common Errors
449
+
450
+ **FileNotFoundError: Configuration file not found**
451
+ - Check file path is correct
452
+ - Use absolute path if relative path fails
453
+
454
+ **ValueError: Invalid JSON**
455
+ - Validate JSON syntax (no trailing commas, proper quotes)
456
+ - Use `python -m json.tool config.json` to check
457
+
458
+ **ValueError: Missing required field: cytube.domain**
459
+ - Ensure all required fields present
460
+ - Check field names match exactly (case-sensitive)
461
+
462
+ **ValueError: Invalid log_level: 'debug'**
463
+ - Log levels must be uppercase: DEBUG, INFO, WARNING, ERROR, CRITICAL
464
+ - Check both `log_level` and `logging.level`
465
+
466
+ ### Getting Help
467
+
468
+ - Documentation: `docs/guides/LLM_CONFIGURATION.md`
469
+ - Architecture: `docs/ARCHITECTURE.md`
470
+ - Issues: File a GitHub issue with your config (redact passwords!)
471
+
472
+ ## Migration from Old Format
473
+
474
+ If migrating from old Kryten config format:
475
+
476
+ **Old format:**
477
+ ```json
478
+ {
479
+ "cytube": {...},
480
+ "nats": {
481
+ "url": "nats://localhost:4222"
482
+ },
483
+ "log_level": "INFO"
484
+ }
485
+ ```
486
+
487
+ **New format:**
488
+ ```json
489
+ {
490
+ "cytube": {...},
491
+ "nats": {
492
+ "servers": ["nats://localhost:4222"]
493
+ },
494
+ "logging": {
495
+ "level": "INFO"
496
+ },
497
+ "log_level": "INFO"
498
+ }
499
+ ```
500
+
501
+ Key changes:
502
+ - `nats.url` → `nats.servers` (now array)
503
+ - Add `logging` section for advanced options
504
+ - Keep `log_level` for backward compatibility
kryten/__init__.py ADDED
@@ -0,0 +1,127 @@
1
+ """Kryten CyTube Connector Package.
2
+
3
+ This package provides a standalone Socket.IO client that connects to CyTube
4
+ chat servers and publishes events to NATS for consumption by Rosey-Robot plugins.
5
+ """
6
+
7
+ from pathlib import Path
8
+ from typing import Final
9
+
10
+
11
+ def _read_version() -> str:
12
+ """Read version from VERSION file at repository root.
13
+
14
+ Returns:
15
+ Semantic version string, or "0.1.0-dev" if file unavailable.
16
+ """
17
+ try:
18
+ # Try package root first (for installed package)
19
+ version_file = Path(__file__).parent.parent / "VERSION"
20
+ if not version_file.exists():
21
+ # Fallback to repo root (for development)
22
+ version_file = Path(__file__).parent.parent.parent / "VERSION"
23
+
24
+ version_text = version_file.read_text(encoding="utf-8")
25
+ return version_text.strip()
26
+ except (FileNotFoundError, OSError, UnicodeDecodeError):
27
+ return "0.1.0-dev"
28
+
29
+
30
+ __version__: Final[str] = _read_version()
31
+ """Semantic version of the Kryten connector package."""
32
+
33
+
34
+ def get_version() -> str:
35
+ """Return the semantic version string.
36
+
37
+ Returns:
38
+ Version string in MAJOR.MINOR.PATCH or MAJOR.MINOR.PATCH-suffix format.
39
+
40
+ Example:
41
+ >>> from bot import kryten
42
+ >>> kryten.get_version()
43
+ '0.5.0'
44
+ """
45
+ return __version__
46
+
47
+
48
+ from .command_subscriber import CommandSubscriber
49
+ from .config import CytubeConfig, KrytenConfig, NatsConfig, load_config
50
+ from .connection_watchdog import ConnectionWatchdog
51
+ from .correlation import (
52
+ CorrelationContext,
53
+ CorrelationFilter,
54
+ clear_correlation_context,
55
+ generate_correlation_id,
56
+ get_correlation_context,
57
+ set_correlation_context,
58
+ )
59
+ from .cytube_connector import CytubeConnector
60
+ from .cytube_event_sender import CytubeEventSender
61
+ from .event_publisher import EventPublisher
62
+ from .health_monitor import (
63
+ HealthMonitor,
64
+ HealthStatus,
65
+ )
66
+ from .lifecycle_events import LifecycleEventPublisher
67
+ from .logging_config import (
68
+ LoggingConfig,
69
+ get_logger,
70
+ setup_logging,
71
+ )
72
+ from .nats_client import NatsClient
73
+ from .raw_event import RawEvent
74
+ from .shutdown_handler import (
75
+ ShutdownHandler,
76
+ ShutdownPhase,
77
+ ShutdownResult,
78
+ )
79
+ from .state_manager import StateManager
80
+ from .state_query_handler import StateQueryHandler
81
+ from .state_updater import StateUpdater
82
+ from .subject_builder import (
83
+ SUBJECT_PREFIX,
84
+ build_event_subject,
85
+ build_subject,
86
+ parse_subject,
87
+ sanitize_token,
88
+ )
89
+
90
+ __all__ = [
91
+ "__version__",
92
+ "get_version",
93
+ "CommandSubscriber",
94
+ "ConnectionWatchdog",
95
+ "CytubeConfig",
96
+ "KrytenConfig",
97
+ "NatsConfig",
98
+ "load_config",
99
+ "CorrelationContext",
100
+ "CorrelationFilter",
101
+ "clear_correlation_context",
102
+ "generate_correlation_id",
103
+ "get_correlation_context",
104
+ "set_correlation_context",
105
+ "CytubeConnector",
106
+ "CytubeEventSender",
107
+ "EventPublisher",
108
+ "HealthMonitor",
109
+ "HealthStatus",
110
+ "LifecycleEventPublisher",
111
+ "LoggingConfig",
112
+ "get_logger",
113
+ "setup_logging",
114
+ "NatsClient",
115
+ "RawEvent",
116
+ "ShutdownHandler",
117
+ "ShutdownPhase",
118
+ "ShutdownResult",
119
+ "StateManager",
120
+ "StateQueryHandler",
121
+ "StateUpdater",
122
+ "SUBJECT_PREFIX",
123
+ "build_subject",
124
+ "build_event_subject",
125
+ "parse_subject",
126
+ "sanitize_token",
127
+ ]