tjbot-ce 3.0.1

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 (224) hide show
  1. package/LICENSE +202 -0
  2. package/README.md +382 -0
  3. package/dist/camera/camera.d.ts +62 -0
  4. package/dist/camera/camera.d.ts.map +1 -0
  5. package/dist/camera/camera.js +155 -0
  6. package/dist/camera/camera.js.map +1 -0
  7. package/dist/camera/index.d.ts +18 -0
  8. package/dist/camera/index.d.ts.map +1 -0
  9. package/dist/camera/index.js +18 -0
  10. package/dist/camera/index.js.map +1 -0
  11. package/dist/config/config-types.d.ts +75 -0
  12. package/dist/config/config-types.d.ts.map +1 -0
  13. package/dist/config/config-types.generated.d.ts +495 -0
  14. package/dist/config/config-types.generated.d.ts.map +1 -0
  15. package/dist/config/config-types.generated.js +2 -0
  16. package/dist/config/config-types.generated.js.map +1 -0
  17. package/dist/config/config-types.js +175 -0
  18. package/dist/config/config-types.js.map +1 -0
  19. package/dist/config/index.d.ts +20 -0
  20. package/dist/config/index.d.ts.map +1 -0
  21. package/dist/config/index.js +19 -0
  22. package/dist/config/index.js.map +1 -0
  23. package/dist/config/tjbot-config.d.ts +98 -0
  24. package/dist/config/tjbot-config.d.ts.map +1 -0
  25. package/dist/config/tjbot-config.js +309 -0
  26. package/dist/config/tjbot-config.js.map +1 -0
  27. package/dist/config/vendor/colors.yaml +61 -0
  28. package/dist/config/vendor/model-registry.yaml +275 -0
  29. package/dist/config/vendor/tjbot-config.schema.yaml +792 -0
  30. package/dist/config/vendor/tjbot.default.toml +452 -0
  31. package/dist/led/index.d.ts +20 -0
  32. package/dist/led/index.d.ts.map +1 -0
  33. package/dist/led/index.js +20 -0
  34. package/dist/led/index.js.map +1 -0
  35. package/dist/led/led-common-anode.d.ts +38 -0
  36. package/dist/led/led-common-anode.d.ts.map +1 -0
  37. package/dist/led/led-common-anode.js +79 -0
  38. package/dist/led/led-common-anode.js.map +1 -0
  39. package/dist/led/led-neopixel-spi.d.ts +60 -0
  40. package/dist/led/led-neopixel-spi.d.ts.map +1 -0
  41. package/dist/led/led-neopixel-spi.js +216 -0
  42. package/dist/led/led-neopixel-spi.js.map +1 -0
  43. package/dist/led/led-neopixel-ws281x.js +186 -0
  44. package/dist/led/led-neopixel.d.ts +57 -0
  45. package/dist/led/led-neopixel.d.ts.map +1 -0
  46. package/dist/led/led-neopixel.js +235 -0
  47. package/dist/led/led-neopixel.js.map +1 -0
  48. package/dist/microphone/index.d.ts +18 -0
  49. package/dist/microphone/index.d.ts.map +1 -0
  50. package/dist/microphone/index.js +18 -0
  51. package/dist/microphone/index.js.map +1 -0
  52. package/dist/microphone/microphone.d.ts +65 -0
  53. package/dist/microphone/microphone.d.ts.map +1 -0
  54. package/dist/microphone/microphone.js +179 -0
  55. package/dist/microphone/microphone.js.map +1 -0
  56. package/dist/rpi-drivers/index.d.ts +22 -0
  57. package/dist/rpi-drivers/index.d.ts.map +1 -0
  58. package/dist/rpi-drivers/index.js +22 -0
  59. package/dist/rpi-drivers/index.js.map +1 -0
  60. package/dist/rpi-drivers/rpi-detect.d.ts +24 -0
  61. package/dist/rpi-drivers/rpi-detect.d.ts.map +1 -0
  62. package/dist/rpi-drivers/rpi-detect.js +49 -0
  63. package/dist/rpi-drivers/rpi-detect.js.map +1 -0
  64. package/dist/rpi-drivers/rpi-driver.d.ts +116 -0
  65. package/dist/rpi-drivers/rpi-driver.d.ts.map +1 -0
  66. package/dist/rpi-drivers/rpi-driver.js +261 -0
  67. package/dist/rpi-drivers/rpi-driver.js.map +1 -0
  68. package/dist/rpi-drivers/rpi3-driver.d.ts +47 -0
  69. package/dist/rpi-drivers/rpi3-driver.d.ts.map +1 -0
  70. package/dist/rpi-drivers/rpi3-driver.js +145 -0
  71. package/dist/rpi-drivers/rpi3-driver.js.map +1 -0
  72. package/dist/rpi-drivers/rpi4-driver.d.ts +35 -0
  73. package/dist/rpi-drivers/rpi4-driver.d.ts.map +1 -0
  74. package/dist/rpi-drivers/rpi4-driver.js +101 -0
  75. package/dist/rpi-drivers/rpi4-driver.js.map +1 -0
  76. package/dist/rpi-drivers/rpi5-driver.d.ts +33 -0
  77. package/dist/rpi-drivers/rpi5-driver.d.ts.map +1 -0
  78. package/dist/rpi-drivers/rpi5-driver.js +78 -0
  79. package/dist/rpi-drivers/rpi5-driver.js.map +1 -0
  80. package/dist/servo/index.d.ts +19 -0
  81. package/dist/servo/index.d.ts.map +1 -0
  82. package/dist/servo/index.js +19 -0
  83. package/dist/servo/index.js.map +1 -0
  84. package/dist/servo/servo-constants.d.ts +33 -0
  85. package/dist/servo/servo-constants.d.ts.map +1 -0
  86. package/dist/servo/servo-constants.js +34 -0
  87. package/dist/servo/servo-constants.js.map +1 -0
  88. package/dist/servo/servo-lgpio.d.ts +82 -0
  89. package/dist/servo/servo-lgpio.d.ts.map +1 -0
  90. package/dist/servo/servo-lgpio.js +178 -0
  91. package/dist/servo/servo-lgpio.js.map +1 -0
  92. package/dist/speaker/audio-player.d.ts +30 -0
  93. package/dist/speaker/audio-player.d.ts.map +1 -0
  94. package/dist/speaker/audio-player.js +68 -0
  95. package/dist/speaker/audio-player.js.map +1 -0
  96. package/dist/speaker/index.d.ts +18 -0
  97. package/dist/speaker/index.d.ts.map +1 -0
  98. package/dist/speaker/index.js +18 -0
  99. package/dist/speaker/index.js.map +1 -0
  100. package/dist/speaker/speaker.d.ts +53 -0
  101. package/dist/speaker/speaker.d.ts.map +1 -0
  102. package/dist/speaker/speaker.js +125 -0
  103. package/dist/speaker/speaker.js.map +1 -0
  104. package/dist/stt/backends/azure-stt.d.ts +32 -0
  105. package/dist/stt/backends/azure-stt.d.ts.map +1 -0
  106. package/dist/stt/backends/azure-stt.js +227 -0
  107. package/dist/stt/backends/azure-stt.js.map +1 -0
  108. package/dist/stt/backends/google-cloud-stt.d.ts +31 -0
  109. package/dist/stt/backends/google-cloud-stt.d.ts.map +1 -0
  110. package/dist/stt/backends/google-cloud-stt.js +371 -0
  111. package/dist/stt/backends/google-cloud-stt.js.map +1 -0
  112. package/dist/stt/backends/ibm-watson-stt.d.ts +32 -0
  113. package/dist/stt/backends/ibm-watson-stt.d.ts.map +1 -0
  114. package/dist/stt/backends/ibm-watson-stt.js +190 -0
  115. package/dist/stt/backends/ibm-watson-stt.js.map +1 -0
  116. package/dist/stt/backends/sherpa-onnx-stt.d.ts +117 -0
  117. package/dist/stt/backends/sherpa-onnx-stt.d.ts.map +1 -0
  118. package/dist/stt/backends/sherpa-onnx-stt.js +694 -0
  119. package/dist/stt/backends/sherpa-onnx-stt.js.map +1 -0
  120. package/dist/stt/index.d.ts +20 -0
  121. package/dist/stt/index.d.ts.map +1 -0
  122. package/dist/stt/index.js +21 -0
  123. package/dist/stt/index.js.map +1 -0
  124. package/dist/stt/stt-engine.d.ts +68 -0
  125. package/dist/stt/stt-engine.d.ts.map +1 -0
  126. package/dist/stt/stt-engine.js +99 -0
  127. package/dist/stt/stt-engine.js.map +1 -0
  128. package/dist/stt/stt-utils.d.ts +36 -0
  129. package/dist/stt/stt-utils.d.ts.map +1 -0
  130. package/dist/stt/stt-utils.js +112 -0
  131. package/dist/stt/stt-utils.js.map +1 -0
  132. package/dist/stt/stt.d.ts +52 -0
  133. package/dist/stt/stt.d.ts.map +1 -0
  134. package/dist/stt/stt.js +100 -0
  135. package/dist/stt/stt.js.map +1 -0
  136. package/dist/tjbot.d.ts +317 -0
  137. package/dist/tjbot.d.ts.map +1 -0
  138. package/dist/tjbot.js +736 -0
  139. package/dist/tjbot.js.map +1 -0
  140. package/dist/tts/backends/azure-tts.d.ts +30 -0
  141. package/dist/tts/backends/azure-tts.d.ts.map +1 -0
  142. package/dist/tts/backends/azure-tts.js +92 -0
  143. package/dist/tts/backends/azure-tts.js.map +1 -0
  144. package/dist/tts/backends/google-cloud-tts.d.ts +38 -0
  145. package/dist/tts/backends/google-cloud-tts.d.ts.map +1 -0
  146. package/dist/tts/backends/google-cloud-tts.js +116 -0
  147. package/dist/tts/backends/google-cloud-tts.js.map +1 -0
  148. package/dist/tts/backends/ibm-watson-tts.d.ts +42 -0
  149. package/dist/tts/backends/ibm-watson-tts.d.ts.map +1 -0
  150. package/dist/tts/backends/ibm-watson-tts.js +99 -0
  151. package/dist/tts/backends/ibm-watson-tts.js.map +1 -0
  152. package/dist/tts/backends/sherpa-onnx-tts.d.ts +80 -0
  153. package/dist/tts/backends/sherpa-onnx-tts.d.ts.map +1 -0
  154. package/dist/tts/backends/sherpa-onnx-tts.js +237 -0
  155. package/dist/tts/backends/sherpa-onnx-tts.js.map +1 -0
  156. package/dist/tts/index.d.ts +19 -0
  157. package/dist/tts/index.d.ts.map +1 -0
  158. package/dist/tts/index.js +20 -0
  159. package/dist/tts/index.js.map +1 -0
  160. package/dist/tts/tts-engine.d.ts +67 -0
  161. package/dist/tts/tts-engine.d.ts.map +1 -0
  162. package/dist/tts/tts-engine.js +109 -0
  163. package/dist/tts/tts-engine.js.map +1 -0
  164. package/dist/tts/tts.d.ts +47 -0
  165. package/dist/tts/tts.d.ts.map +1 -0
  166. package/dist/tts/tts.js +101 -0
  167. package/dist/tts/tts.js.map +1 -0
  168. package/dist/utils/colors.d.ts +39 -0
  169. package/dist/utils/colors.d.ts.map +1 -0
  170. package/dist/utils/colors.js +155 -0
  171. package/dist/utils/colors.js.map +1 -0
  172. package/dist/utils/constants.d.ts +41 -0
  173. package/dist/utils/constants.d.ts.map +1 -0
  174. package/dist/utils/constants.js +43 -0
  175. package/dist/utils/constants.js.map +1 -0
  176. package/dist/utils/credentials.d.ts +43 -0
  177. package/dist/utils/credentials.d.ts.map +1 -0
  178. package/dist/utils/credentials.js +121 -0
  179. package/dist/utils/credentials.js.map +1 -0
  180. package/dist/utils/errors.d.ts +26 -0
  181. package/dist/utils/errors.d.ts.map +1 -0
  182. package/dist/utils/errors.js +32 -0
  183. package/dist/utils/errors.js.map +1 -0
  184. package/dist/utils/index.d.ts +25 -0
  185. package/dist/utils/index.d.ts.map +1 -0
  186. package/dist/utils/index.js +23 -0
  187. package/dist/utils/index.js.map +1 -0
  188. package/dist/utils/logging.d.ts +44 -0
  189. package/dist/utils/logging.d.ts.map +1 -0
  190. package/dist/utils/logging.js +113 -0
  191. package/dist/utils/logging.js.map +1 -0
  192. package/dist/utils/model-registry.d.ts +142 -0
  193. package/dist/utils/model-registry.d.ts.map +1 -0
  194. package/dist/utils/model-registry.js +391 -0
  195. package/dist/utils/model-registry.js.map +1 -0
  196. package/dist/utils/utils.d.ts +33 -0
  197. package/dist/utils/utils.d.ts.map +1 -0
  198. package/dist/utils/utils.js +50 -0
  199. package/dist/utils/utils.js.map +1 -0
  200. package/dist/vision/backends/azure-vision.d.ts +33 -0
  201. package/dist/vision/backends/azure-vision.d.ts.map +1 -0
  202. package/dist/vision/backends/azure-vision.js +151 -0
  203. package/dist/vision/backends/azure-vision.js.map +1 -0
  204. package/dist/vision/backends/google-cloud-vision.d.ts +32 -0
  205. package/dist/vision/backends/google-cloud-vision.d.ts.map +1 -0
  206. package/dist/vision/backends/google-cloud-vision.js +193 -0
  207. package/dist/vision/backends/google-cloud-vision.js.map +1 -0
  208. package/dist/vision/backends/onnx.d.ts +116 -0
  209. package/dist/vision/backends/onnx.d.ts.map +1 -0
  210. package/dist/vision/backends/onnx.js +781 -0
  211. package/dist/vision/backends/onnx.js.map +1 -0
  212. package/dist/vision/index.d.ts +19 -0
  213. package/dist/vision/index.d.ts.map +1 -0
  214. package/dist/vision/index.js +20 -0
  215. package/dist/vision/index.js.map +1 -0
  216. package/dist/vision/vision-engine.d.ts +131 -0
  217. package/dist/vision/vision-engine.d.ts.map +1 -0
  218. package/dist/vision/vision-engine.js +97 -0
  219. package/dist/vision/vision-engine.js.map +1 -0
  220. package/dist/vision/vision.d.ts +48 -0
  221. package/dist/vision/vision.d.ts.map +1 -0
  222. package/dist/vision/vision.js +83 -0
  223. package/dist/vision/vision.js.map +1 -0
  224. package/package.json +124 -0
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Copyright 2025 IBM Corp. All Rights Reserved.
3
+ * Copyright 2026-present TJBot Contributors. All Rights Reserved.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ export type { HardwareConfig, LEDCommonAnodeConfig, LEDNeopixelConfig, ListenConfig, LogConfig, ModelEntryType, ModelEntry, ModelsConfig, NoneBackendConfig, SeeBackendAzureConfig, SeeBackendConfig, SeeBackendGoogleCloudConfig, SeeBackendLocalConfig, SeeBackendType, SeeConfig, ShineConfig, SpeakConfig, STTBackendConfig, STTBackendAzureConfig, STTBackendGoogleCloudConfig, STTBackendIBMWatsonConfig, STTBackendLocalConfig, STTBackendType, STTEngineConfig, TJBotConfigSchema, TTSBackendConfig, TTSBackendAzureConfig, TTSBackendGoogleCloudConfig, TTSBackendIBMWatsonConfig, TTSBackendLocalConfig, TTSBackendType, TTSEngineConfig, VADConfig, VisionEngineConfig, WaveConfig, LogLevel, } from './config-types.js';
18
+ export { getConfigSchema, getSTTBackendConfig, getTTSBackendConfig, getSeeBackendConfig, isSTTBackendType, isTTSBackendType, isSeeBackendType, seeBackendTypeSchema, sttBackendTypeSchema, tjbotConfigSchema, ttsBackendTypeSchema, validateTJBotConfig, } from './config-types.js';
19
+ export { TJBotConfig } from './tjbot-config.js';
20
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAEH,YAAY,EACR,cAAc,EACd,oBAAoB,EACpB,iBAAiB,EACjB,YAAY,EACZ,SAAS,EACT,cAAc,EACd,UAAU,EACV,YAAY,EACZ,iBAAiB,EACjB,qBAAqB,EACrB,gBAAgB,EAChB,2BAA2B,EAC3B,qBAAqB,EACrB,cAAc,EACd,SAAS,EACT,WAAW,EACX,WAAW,EACX,gBAAgB,EAChB,qBAAqB,EACrB,2BAA2B,EAC3B,yBAAyB,EACzB,qBAAqB,EACrB,cAAc,EACd,eAAe,EACf,iBAAiB,EACjB,gBAAgB,EAChB,qBAAqB,EACrB,2BAA2B,EAC3B,yBAAyB,EACzB,qBAAqB,EACrB,cAAc,EACd,eAAe,EACf,SAAS,EACT,kBAAkB,EAClB,UAAU,EACV,QAAQ,GACX,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EACH,eAAe,EACf,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACnB,gBAAgB,EAChB,gBAAgB,EAChB,gBAAgB,EAChB,oBAAoB,EACpB,oBAAoB,EACpB,iBAAiB,EACjB,oBAAoB,EACpB,mBAAmB,GACtB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC"}
@@ -0,0 +1,19 @@
1
+ /**
2
+ * Copyright 2025 IBM Corp. All Rights Reserved.
3
+ * Copyright 2026-present TJBot Contributors. All Rights Reserved.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ export { getConfigSchema, getSTTBackendConfig, getTTSBackendConfig, getSeeBackendConfig, isSTTBackendType, isTTSBackendType, isSeeBackendType, seeBackendTypeSchema, sttBackendTypeSchema, tjbotConfigSchema, ttsBackendTypeSchema, validateTJBotConfig, } from './config-types.js';
18
+ export { TJBotConfig } from './tjbot-config.js';
19
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"index.js","sourceRoot":"","sources":["../../src/config/index.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAyCH,OAAO,EACH,eAAe,EACf,mBAAmB,EACnB,mBAAmB,EACnB,mBAAmB,EACnB,gBAAgB,EAChB,gBAAgB,EAChB,gBAAgB,EAChB,oBAAoB,EACpB,oBAAoB,EACpB,iBAAiB,EACjB,oBAAoB,EACpB,mBAAmB,GACtB,MAAM,mBAAmB,CAAC;AAE3B,OAAO,EAAE,WAAW,EAAE,MAAM,mBAAmB,CAAC"}
@@ -0,0 +1,98 @@
1
+ /**
2
+ * Copyright 2025 IBM Corp. All Rights Reserved.
3
+ * Copyright 2026-present TJBot Contributors. All Rights Reserved.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ import { type TJBotConfigSchema, type LogConfig, type HardwareConfig, type ListenConfig, type SeeConfig, type ShineConfig, type SpeakConfig, type WaveConfig } from './config-types.js';
18
+ /**
19
+ * TJBotConfig manages loading and parsing TJBot configuration from TOML files.
20
+ * It provides access to configuration via structured interfaces.
21
+ */
22
+ export declare class TJBotConfig {
23
+ readonly config: TJBotConfigSchema;
24
+ readonly log: LogConfig;
25
+ readonly hardware: HardwareConfig;
26
+ readonly listen: ListenConfig;
27
+ readonly see: SeeConfig;
28
+ readonly shine: ShineConfig;
29
+ readonly speak: SpeakConfig;
30
+ readonly wave: WaveConfig;
31
+ readonly recipe: Record<string, unknown>;
32
+ private defaultConfigPath;
33
+ /**
34
+ * Creates a TJBotConfig instance.
35
+ * Loads configuration in the following order:
36
+ * 1. Default configuration from tjbot.default.toml
37
+ * 2. User configuration from ~/.tjbot/tjbot.toml (if it exists)
38
+ * 3. Override configuration (if provided)
39
+ * 4. Recipe-specific configuration from recipe.toml (if it exists)
40
+ * 5. Register user-defined models from [models] section
41
+ *
42
+ * @param overrideConfig Optional configuration object to overlay on top of loaded config
43
+ * @param recipeConfigPath Path to recipe configuration file (default: recipe.toml in current working directory)
44
+ */
45
+ constructor(overrideConfig?: Partial<TJBotConfigSchema>, recipeConfigPath?: string);
46
+ /**
47
+ * Load internal default TOML configuration
48
+ * @private
49
+ */
50
+ private loadInternalConfig;
51
+ /**
52
+ * Load user configuration from ~/.tjbot/tjbot.toml if it exists
53
+ * @private
54
+ */
55
+ private loadHomeConfig;
56
+ /**
57
+ * Load recipe-specific configuration from recipe.toml if it exists.
58
+ * The entire file content is treated as recipe configuration.
59
+ * @private
60
+ */
61
+ private loadRecipeConfig;
62
+ /**
63
+ * Deep merge multiple configuration objects.
64
+ * Later objects override earlier ones, but only at the leaf level.
65
+ * @private
66
+ */
67
+ private deepMerge;
68
+ /**
69
+ * Check if a value is a plain object (not null, not array, not Date, etc.)
70
+ * @private
71
+ */
72
+ private isPlainObject;
73
+ /**
74
+ * Clean configuration object to remove Symbol keys and non-string properties
75
+ * @private
76
+ */
77
+ private cleanConfig;
78
+ /**
79
+ * Get raw configuration value by path (for backward compatibility)
80
+ */
81
+ get(key: string): unknown;
82
+ /**
83
+ * Validate vision local backend models are properly configured
84
+ * @private
85
+ */
86
+ private validateVisionLocalModels;
87
+ /**
88
+ * Validate vision backend configuration for all backend types.
89
+ * @private
90
+ */
91
+ private validateVisionBackendConfig;
92
+ /**
93
+ * Validate confidence thresholds in a backend config object.
94
+ * @private
95
+ */
96
+ private validateVisionThresholds;
97
+ }
98
+ //# sourceMappingURL=tjbot-config.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tjbot-config.d.ts","sourceRoot":"","sources":["../../src/config/tjbot-config.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;;;;;GAeG;AAOH,OAAO,EAEH,KAAK,iBAAiB,EACtB,KAAK,SAAS,EACd,KAAK,cAAc,EACnB,KAAK,YAAY,EACjB,KAAK,SAAS,EACd,KAAK,WAAW,EAChB,KAAK,WAAW,EAChB,KAAK,UAAU,EAClB,MAAM,mBAAmB,CAAC;AAM3B;;;GAGG;AACH,qBAAa,WAAW;IACpB,QAAQ,CAAC,MAAM,EAAE,iBAAiB,CAAC;IACnC,QAAQ,CAAC,GAAG,EAAE,SAAS,CAAC;IACxB,QAAQ,CAAC,QAAQ,EAAE,cAAc,CAAC;IAClC,QAAQ,CAAC,MAAM,EAAE,YAAY,CAAC;IAC9B,QAAQ,CAAC,GAAG,EAAE,SAAS,CAAC;IACxB,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC;IAC5B,QAAQ,CAAC,KAAK,EAAE,WAAW,CAAC;IAC5B,QAAQ,CAAC,IAAI,EAAE,UAAU,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAEzC,OAAO,CAAC,iBAAiB,CAAyC;IAElE;;;;;;;;;;;OAWG;gBACS,cAAc,CAAC,EAAE,OAAO,CAAC,iBAAiB,CAAC,EAAE,gBAAgB,CAAC,EAAE,MAAM;IAkDlF;;;OAGG;IACH,OAAO,CAAC,kBAAkB;IAgB1B;;;OAGG;IACH,OAAO,CAAC,cAAc;IAoBtB;;;;OAIG;IACH,OAAO,CAAC,gBAAgB;IAsBxB;;;;OAIG;IACH,OAAO,CAAC,SAAS;IAmCjB;;;OAGG;IACH,OAAO,CAAC,aAAa;IASrB;;;OAGG;IACH,OAAO,CAAC,WAAW;IA6BnB;;OAEG;IACH,GAAG,CAAC,GAAG,EAAE,MAAM,GAAG,OAAO;IAIzB;;;OAGG;IACH,OAAO,CAAC,yBAAyB;IAgDjC;;;OAGG;IACH,OAAO,CAAC,2BAA2B;IA4BnC;;;OAGG;IACH,OAAO,CAAC,wBAAwB;CAQnC"}
@@ -0,0 +1,309 @@
1
+ /**
2
+ * Copyright 2025 IBM Corp. All Rights Reserved.
3
+ * Copyright 2026-present TJBot Contributors. All Rights Reserved.
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+ import fs from 'fs';
18
+ import path from 'path';
19
+ import os from 'os';
20
+ import TOML from '@iarna/toml';
21
+ import { resolve } from 'import-meta-resolve';
22
+ import { tjbotConfigSchema, } from './config-types.js';
23
+ import { TJBotError, ModelRegistry } from '../utils/index.js';
24
+ import { getLogger } from '../utils/logging.js';
25
+ const logger = getLogger(import.meta.url);
26
+ /**
27
+ * TJBotConfig manages loading and parsing TJBot configuration from TOML files.
28
+ * It provides access to configuration via structured interfaces.
29
+ */
30
+ export class TJBotConfig {
31
+ config;
32
+ log;
33
+ hardware;
34
+ listen;
35
+ see;
36
+ shine;
37
+ speak;
38
+ wave;
39
+ recipe;
40
+ defaultConfigPath = './vendor/tjbot.default.toml';
41
+ /**
42
+ * Creates a TJBotConfig instance.
43
+ * Loads configuration in the following order:
44
+ * 1. Default configuration from tjbot.default.toml
45
+ * 2. User configuration from ~/.tjbot/tjbot.toml (if it exists)
46
+ * 3. Override configuration (if provided)
47
+ * 4. Recipe-specific configuration from recipe.toml (if it exists)
48
+ * 5. Register user-defined models from [models] section
49
+ *
50
+ * @param overrideConfig Optional configuration object to overlay on top of loaded config
51
+ * @param recipeConfigPath Path to recipe configuration file (default: recipe.toml in current working directory)
52
+ */
53
+ constructor(overrideConfig, recipeConfigPath) {
54
+ // Load default config
55
+ const defaultConfig = this.loadInternalConfig(this.defaultConfigPath);
56
+ // Load user config from ~/.tjbot/tjbot.toml if it exists
57
+ const homeConfig = this.loadHomeConfig();
58
+ // Load recipe config from recipe.toml if it exists
59
+ const recipeConfig = this.loadRecipeConfig(recipeConfigPath ?? 'recipe.toml');
60
+ // Merge general configuration in cascade order: default -> home -> overrides
61
+ const mergedConfig = this.deepMerge(defaultConfig, homeConfig ?? {}, overrideConfig ?? {});
62
+ // Merge recipe config into the recipe section
63
+ if (recipeConfig) {
64
+ mergedConfig.recipe = this.deepMerge(mergedConfig.recipe ?? {}, recipeConfig);
65
+ }
66
+ try {
67
+ this.config = tjbotConfigSchema.parse(mergedConfig);
68
+ }
69
+ catch (err) {
70
+ throw new TJBotError('invalid TJBot configuration', { cause: err });
71
+ }
72
+ // Register user-defined models from [models] section
73
+ if (this.config.models && Array.isArray(this.config.models)) {
74
+ const registry = ModelRegistry.getInstance();
75
+ for (const model of this.config.models) {
76
+ registry.registerModel(model);
77
+ logger.verbose(`Registered custom ML model: ${model.key}`);
78
+ }
79
+ }
80
+ // Validate vision backend config when configured.
81
+ this.validateVisionBackendConfig();
82
+ this.log = this.config.log ?? {};
83
+ this.hardware = this.config.hardware ?? {};
84
+ this.listen = this.config.listen ?? {};
85
+ this.see = this.config.see ?? {};
86
+ this.shine = this.config.shine ?? {};
87
+ this.speak = this.config.speak ?? {};
88
+ this.wave = this.config.wave ?? {};
89
+ this.recipe = this.config.recipe ?? {};
90
+ logger.verbose('TJBot configuration loaded successfully');
91
+ logger.silly(`TJBot configuration:
92
+ ${JSON.stringify(this.config, null, 2)}`);
93
+ }
94
+ /**
95
+ * Load internal default TOML configuration
96
+ * @private
97
+ */
98
+ loadInternalConfig(configFile) {
99
+ const configPath = resolve(configFile, import.meta.url);
100
+ logger.debug(`loading default TJBot configuration TOML from ${configPath}`);
101
+ let config;
102
+ try {
103
+ const configData = fs.readFileSync(new URL(configPath), 'utf8');
104
+ // Clean up the config to remove any Symbol keys
105
+ config = this.cleanConfig(TOML.parse(configData));
106
+ }
107
+ catch (err) {
108
+ throw new TJBotError(`unable to read TOML from ${configFile}: ${err}`);
109
+ }
110
+ return config;
111
+ }
112
+ /**
113
+ * Load user configuration from ~/.tjbot/tjbot.toml if it exists
114
+ * @private
115
+ */
116
+ loadHomeConfig() {
117
+ const homeConfigPath = path.join(os.homedir(), '.tjbot', 'tjbot.toml');
118
+ try {
119
+ if (fs.existsSync(homeConfigPath) && fs.lstatSync(homeConfigPath).isFile()) {
120
+ logger.debug(`loading user TJBot configuration from ${homeConfigPath}`);
121
+ const configData = fs.readFileSync(homeConfigPath, 'utf8');
122
+ let config = TOML.parse(configData);
123
+ // Clean up the config to remove any Symbol keys
124
+ config = this.cleanConfig(config);
125
+ return config;
126
+ }
127
+ else {
128
+ logger.debug(`user configuration file ${homeConfigPath} not found, skipping`);
129
+ return null;
130
+ }
131
+ }
132
+ catch (err) {
133
+ throw new TJBotError(`unable to read user TJBot configuration from ${homeConfigPath}: ${err}`);
134
+ }
135
+ }
136
+ /**
137
+ * Load recipe-specific configuration from recipe.toml if it exists.
138
+ * The entire file content is treated as recipe configuration.
139
+ * @private
140
+ */
141
+ loadRecipeConfig(recipeConfigPath) {
142
+ const absoluteRecipeConfigPath = path.isAbsolute(recipeConfigPath)
143
+ ? recipeConfigPath
144
+ : path.join(process.cwd(), recipeConfigPath);
145
+ try {
146
+ if (fs.existsSync(absoluteRecipeConfigPath) && fs.lstatSync(absoluteRecipeConfigPath).isFile()) {
147
+ logger.debug(`loading recipe configuration from ${absoluteRecipeConfigPath}`);
148
+ const configData = fs.readFileSync(absoluteRecipeConfigPath, 'utf8');
149
+ let config = TOML.parse(configData);
150
+ // Clean up the config to remove any Symbol keys
151
+ config = this.cleanConfig(config);
152
+ return config;
153
+ }
154
+ else {
155
+ logger.debug(`recipe configuration file ${absoluteRecipeConfigPath} not found, skipping`);
156
+ return null;
157
+ }
158
+ }
159
+ catch (err) {
160
+ throw new TJBotError(`unable to read recipe configuration from ${absoluteRecipeConfigPath}: ${err}`);
161
+ }
162
+ }
163
+ /**
164
+ * Deep merge multiple configuration objects.
165
+ * Later objects override earlier ones, but only at the leaf level.
166
+ * @private
167
+ */
168
+ deepMerge(...sources) {
169
+ const result = {};
170
+ for (const source of sources) {
171
+ for (const key in source) {
172
+ if (!Object.prototype.hasOwnProperty.call(source, key)) {
173
+ continue;
174
+ }
175
+ const sourceValue = source[key];
176
+ const resultValue = result[key];
177
+ // If the value is an array, replace it entirely (no merging)
178
+ if (Array.isArray(sourceValue)) {
179
+ result[key] = sourceValue;
180
+ }
181
+ // If both values are plain objects, merge them recursively
182
+ else if (this.isPlainObject(sourceValue) && this.isPlainObject(resultValue)) {
183
+ result[key] = this.deepMerge(resultValue, sourceValue);
184
+ }
185
+ // Otherwise, replace the value
186
+ else {
187
+ result[key] = sourceValue;
188
+ }
189
+ }
190
+ }
191
+ return result;
192
+ }
193
+ /**
194
+ * Check if a value is a plain object (not null, not array, not Date, etc.)
195
+ * @private
196
+ */
197
+ isPlainObject(value) {
198
+ return (value !== null &&
199
+ typeof value === 'object' &&
200
+ !Array.isArray(value) &&
201
+ Object.prototype.toString.call(value) === '[object Object]');
202
+ }
203
+ /**
204
+ * Clean configuration object to remove Symbol keys and non-string properties
205
+ * @private
206
+ */
207
+ cleanConfig(obj) {
208
+ if (obj === null || obj === undefined) {
209
+ return obj;
210
+ }
211
+ if (Array.isArray(obj)) {
212
+ return obj.map((item) => this.cleanConfig(item));
213
+ }
214
+ if (typeof obj === 'object') {
215
+ const cleaned = {};
216
+ for (const key in obj) {
217
+ // Only include string keys
218
+ if (typeof key === 'string' && Object.prototype.hasOwnProperty.call(obj, key)) {
219
+ const value = obj[key];
220
+ cleaned[key] = this.cleanConfig(value);
221
+ }
222
+ else {
223
+ // Warn about non-string keys being removed
224
+ logger.warn(`Removing non-string configuration key from TOML: ${typeof key === 'symbol' ? 'Symbol' : typeof key}`);
225
+ }
226
+ }
227
+ return cleaned;
228
+ }
229
+ return obj;
230
+ }
231
+ /**
232
+ * Get raw configuration value by path (for backward compatibility)
233
+ */
234
+ get(key) {
235
+ return this.config[key];
236
+ }
237
+ /**
238
+ * Validate vision local backend models are properly configured
239
+ * @private
240
+ */
241
+ validateVisionLocalModels(localConfig) {
242
+ const { objectDetectionModel, imageClassificationModel, faceDetectionModel, objectDetectionConfidence, imageClassificationConfidence, faceDetectionConfidence, } = localConfig;
243
+ // Models are validated at runtime when engine initializes
244
+ // This is a basic validation that models are specified
245
+ const models = [
246
+ { field: 'objectDetectionModel', value: objectDetectionModel, expectedKind: 'detection' },
247
+ { field: 'imageClassificationModel', value: imageClassificationModel, expectedKind: 'classification' },
248
+ { field: 'faceDetectionModel', value: faceDetectionModel, expectedKind: 'face-detection' },
249
+ ];
250
+ for (const model of models) {
251
+ if (!model.value) {
252
+ throw new TJBotError(`Vision local backend: ${model.field} is required but not configured`);
253
+ }
254
+ }
255
+ // Validate confidence thresholds if provided
256
+ const confidenceThresholds = [
257
+ { field: 'objectDetectionConfidence', value: objectDetectionConfidence },
258
+ { field: 'imageClassificationConfidence', value: imageClassificationConfidence },
259
+ { field: 'faceDetectionConfidence', value: faceDetectionConfidence },
260
+ ];
261
+ for (const threshold of confidenceThresholds) {
262
+ if (threshold.value !== undefined &&
263
+ (typeof threshold.value !== 'number' || threshold.value < 0 || threshold.value > 1)) {
264
+ throw new TJBotError(`Vision local backend: ${threshold.field} must be a number between 0.0 and 1.0`);
265
+ }
266
+ }
267
+ }
268
+ /**
269
+ * Validate vision backend configuration for all backend types.
270
+ * @private
271
+ */
272
+ validateVisionBackendConfig() {
273
+ const backend = this.config.see?.backend;
274
+ if (!backend) {
275
+ return;
276
+ }
277
+ if (backend.type === 'local' && backend.local) {
278
+ this.validateVisionLocalModels(backend.local);
279
+ return;
280
+ }
281
+ if (backend.type === 'google-cloud-vision' && backend['google-cloud-vision']) {
282
+ this.validateVisionThresholds('google-cloud-vision', backend['google-cloud-vision'], [
283
+ 'objectDetectionConfidence',
284
+ 'imageClassificationConfidence',
285
+ 'faceDetectionConfidence',
286
+ ]);
287
+ return;
288
+ }
289
+ if (backend.type === 'azure-vision' && backend['azure-vision']) {
290
+ this.validateVisionThresholds('azure-vision', backend['azure-vision'], [
291
+ 'objectDetectionConfidence',
292
+ 'imageClassificationConfidence',
293
+ ]);
294
+ }
295
+ }
296
+ /**
297
+ * Validate confidence thresholds in a backend config object.
298
+ * @private
299
+ */
300
+ validateVisionThresholds(backendName, config, fields) {
301
+ for (const field of fields) {
302
+ const value = config[field];
303
+ if (value !== undefined && (typeof value !== 'number' || value < 0 || value > 1)) {
304
+ throw new TJBotError(`Vision ${backendName} backend: ${field} must be a number between 0.0 and 1.0`);
305
+ }
306
+ }
307
+ }
308
+ }
309
+ //# sourceMappingURL=tjbot-config.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"tjbot-config.js","sourceRoot":"","sources":["../../src/config/tjbot-config.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,61 @@
1
+ # Copyright 2026-present TJBot Contributors. All Rights Reserved.
2
+ #
3
+ # Licensed under the Apache License, Version 2.0 (the "License");
4
+ # you may not use this file except in compliance with the License.
5
+ # You may obtain a copy of the License at
6
+ #
7
+ # http://www.apache.org/licenses/LICENSE-2.0
8
+ #
9
+ # Unless required by applicable law or agreed to in writing, software
10
+ # distributed under the License is distributed on an "AS IS" BASIS,
11
+ # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12
+ # See the License for the specific language governing permissions and
13
+ # limitations under the License.
14
+
15
+ # Curated LED colors for TJBot
16
+ # Format: color_name: hex_value
17
+
18
+ red: "#FF0000"
19
+ orange: "#FF8000"
20
+ yellow: "#FFFF00"
21
+ green: "#008000"
22
+ blue: "#0000FF"
23
+ purple: "#800080"
24
+ pink: "#FFC0CB"
25
+ white: "#FFFFFF"
26
+ black: "#000000"
27
+ crimson: "#DC143C"
28
+ darkred: "#8B0000"
29
+ maroon: "#800000"
30
+ coral: "#FF7F50"
31
+ darkorange: "#FF8C00"
32
+ brown: "#A52A2A"
33
+ sienna: "#A0522D"
34
+ gold: "#FFD700"
35
+ khaki: "#F0E68C"
36
+ lime: "#00FF00"
37
+ darkgreen: "#006400"
38
+ olive: "#808000"
39
+ teal: "#008080"
40
+ forestgreen: "#228B22"
41
+ seagreen: "#2E8B57"
42
+ cyan: "#00FFFF"
43
+ aqua: "#00FFFF"
44
+ turquoise: "#40E0D0"
45
+ navy: "#000080"
46
+ darkblue: "#00008B"
47
+ royalblue: "#4169E1"
48
+ skyblue: "#87CEEB"
49
+ lightblue: "#ADD8E6"
50
+ indigo: "#4B0082"
51
+ violet: "#EE82EE"
52
+ magenta: "#FF00FF"
53
+ fuchsia: "#FF00FF"
54
+ orchid: "#DA70D6"
55
+ hotpink: "#FF69B4"
56
+ deeppink: "#FF1493"
57
+ lightpink: "#FFB6C1"
58
+ gray: "#808080"
59
+ silver: "#C0C0C0"
60
+ on: "#FFFFFF"
61
+ off: "#000000"