@edgible-team/cli 1.2.4 → 1.2.8

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 (221) hide show
  1. package/dist/commands/agent/agent-handlers.d.ts +45 -0
  2. package/dist/commands/agent/agent-handlers.d.ts.map +1 -0
  3. package/dist/commands/agent/agent-handlers.js +1159 -0
  4. package/dist/commands/agent/install.d.ts +11 -0
  5. package/dist/commands/agent/install.d.ts.map +1 -0
  6. package/dist/commands/agent/install.js +399 -0
  7. package/dist/commands/agent/logs.d.ts +12 -0
  8. package/dist/commands/agent/logs.d.ts.map +1 -0
  9. package/dist/commands/agent/logs.js +77 -0
  10. package/dist/commands/agent/restart.d.ts +4 -0
  11. package/dist/commands/agent/restart.d.ts.map +1 -0
  12. package/dist/commands/agent/restart.js +33 -0
  13. package/dist/commands/agent/set-log-level.d.ts +8 -0
  14. package/dist/commands/agent/set-log-level.d.ts.map +1 -0
  15. package/dist/commands/agent/set-log-level.js +133 -0
  16. package/dist/commands/agent/setup.d.ts +9 -0
  17. package/dist/commands/agent/setup.d.ts.map +1 -0
  18. package/dist/commands/agent/setup.js +149 -0
  19. package/dist/commands/agent/start.d.ts +12 -0
  20. package/dist/commands/agent/start.d.ts.map +1 -0
  21. package/dist/commands/agent/start.js +308 -0
  22. package/dist/commands/agent/status.d.ts +7 -0
  23. package/dist/commands/agent/status.d.ts.map +1 -0
  24. package/dist/commands/agent/status.js +68 -0
  25. package/dist/commands/agent/stop.d.ts +4 -0
  26. package/dist/commands/agent/stop.d.ts.map +1 -0
  27. package/dist/commands/agent/stop.js +33 -0
  28. package/dist/commands/agent/uninstall.d.ts +7 -0
  29. package/dist/commands/agent/uninstall.d.ts.map +1 -0
  30. package/dist/commands/agent/uninstall.js +168 -0
  31. package/dist/commands/agent.d.ts.map +1 -1
  32. package/dist/commands/agent.js +24 -1190
  33. package/dist/commands/ai/helpers.d.ts +139 -0
  34. package/dist/commands/ai/helpers.d.ts.map +1 -0
  35. package/dist/commands/ai/helpers.js +1470 -0
  36. package/dist/commands/ai/serve.d.ts +6 -0
  37. package/dist/commands/ai/serve.d.ts.map +1 -0
  38. package/dist/commands/ai/serve.js +124 -0
  39. package/dist/commands/ai/setup.d.ts +14 -0
  40. package/dist/commands/ai/setup.d.ts.map +1 -0
  41. package/dist/commands/ai/setup.js +86 -0
  42. package/dist/commands/ai/status.d.ts +2 -0
  43. package/dist/commands/ai/status.d.ts.map +1 -0
  44. package/dist/commands/ai/status.js +160 -0
  45. package/dist/commands/ai/stop.d.ts +2 -0
  46. package/dist/commands/ai/stop.d.ts.map +1 -0
  47. package/dist/commands/ai/stop.js +21 -0
  48. package/dist/commands/ai/teardown.d.ts +5 -0
  49. package/dist/commands/ai/teardown.d.ts.map +1 -0
  50. package/dist/commands/ai/teardown.js +78 -0
  51. package/dist/commands/ai/test.d.ts +4 -0
  52. package/dist/commands/ai/test.d.ts.map +1 -0
  53. package/dist/commands/ai/test.js +65 -0
  54. package/dist/commands/ai.d.ts.map +1 -1
  55. package/dist/commands/ai.js +16 -1938
  56. package/dist/commands/application/api-keys/create.d.ts +6 -0
  57. package/dist/commands/application/api-keys/create.d.ts.map +1 -0
  58. package/dist/commands/application/api-keys/create.js +68 -0
  59. package/dist/commands/application/api-keys/delete.d.ts +6 -0
  60. package/dist/commands/application/api-keys/delete.d.ts.map +1 -0
  61. package/dist/commands/application/api-keys/delete.js +79 -0
  62. package/dist/commands/application/api-keys/list.d.ts +5 -0
  63. package/dist/commands/application/api-keys/list.d.ts.map +1 -0
  64. package/dist/commands/application/api-keys/list.js +65 -0
  65. package/dist/commands/application/api-keys.d.ts +3 -0
  66. package/dist/commands/application/api-keys.d.ts.map +1 -0
  67. package/dist/commands/application/api-keys.js +227 -0
  68. package/dist/commands/application/create-compose.d.ts +3 -0
  69. package/dist/commands/application/create-compose.d.ts.map +1 -0
  70. package/dist/commands/application/create-compose.js +381 -0
  71. package/dist/commands/application/create-docker-compose.d.ts +10 -0
  72. package/dist/commands/application/create-docker-compose.d.ts.map +1 -0
  73. package/dist/commands/application/create-docker-compose.js +334 -0
  74. package/dist/commands/application/create-existing.d.ts +14 -0
  75. package/dist/commands/application/create-existing.d.ts.map +1 -0
  76. package/dist/commands/application/create-existing.js +359 -0
  77. package/dist/commands/application/create-interactive.d.ts +3 -0
  78. package/dist/commands/application/create-interactive.d.ts.map +1 -0
  79. package/dist/commands/application/create-interactive.js +326 -0
  80. package/dist/commands/application/create-managed-process.d.ts +15 -0
  81. package/dist/commands/application/create-managed-process.d.ts.map +1 -0
  82. package/dist/commands/application/create-managed-process.js +371 -0
  83. package/dist/commands/application/create-stubs.d.ts +4 -0
  84. package/dist/commands/application/create-stubs.d.ts.map +1 -0
  85. package/dist/commands/application/create-stubs.js +19 -0
  86. package/dist/commands/application/create-workload.d.ts +5 -0
  87. package/dist/commands/application/create-workload.d.ts.map +1 -0
  88. package/dist/commands/application/create-workload.js +48 -0
  89. package/dist/commands/application/delete.d.ts +6 -0
  90. package/dist/commands/application/delete.d.ts.map +1 -0
  91. package/dist/commands/application/delete.js +76 -0
  92. package/dist/commands/application/get.d.ts +5 -0
  93. package/dist/commands/application/get.d.ts.map +1 -0
  94. package/dist/commands/application/get.js +35 -0
  95. package/dist/commands/application/list.d.ts +4 -0
  96. package/dist/commands/application/list.d.ts.map +1 -0
  97. package/dist/commands/application/list.js +41 -0
  98. package/dist/commands/application/short-codes/create.d.ts +7 -0
  99. package/dist/commands/application/short-codes/create.d.ts.map +1 -0
  100. package/dist/commands/application/short-codes/create.js +69 -0
  101. package/dist/commands/application/short-codes/delete.d.ts +6 -0
  102. package/dist/commands/application/short-codes/delete.d.ts.map +1 -0
  103. package/dist/commands/application/short-codes/delete.js +79 -0
  104. package/dist/commands/application/short-codes/list.d.ts +5 -0
  105. package/dist/commands/application/short-codes/list.d.ts.map +1 -0
  106. package/dist/commands/application/short-codes/list.js +63 -0
  107. package/dist/commands/application/short-codes/toggle.d.ts +5 -0
  108. package/dist/commands/application/short-codes/toggle.d.ts.map +1 -0
  109. package/dist/commands/application/short-codes/toggle.js +71 -0
  110. package/dist/commands/application/short-codes.d.ts +3 -0
  111. package/dist/commands/application/short-codes.d.ts.map +1 -0
  112. package/dist/commands/application/short-codes.js +226 -0
  113. package/dist/commands/application/toggle.d.ts +2 -0
  114. package/dist/commands/application/toggle.d.ts.map +1 -0
  115. package/dist/commands/application/toggle.js +78 -0
  116. package/dist/commands/application/update.d.ts +4 -0
  117. package/dist/commands/application/update.d.ts.map +1 -0
  118. package/dist/commands/application/update.js +11 -0
  119. package/dist/commands/application.d.ts.map +1 -1
  120. package/dist/commands/application.js +32 -1630
  121. package/dist/commands/auth.d.ts.map +1 -1
  122. package/dist/commands/auth.js +31 -49
  123. package/dist/commands/base/BaseCommand.d.ts +3 -3
  124. package/dist/commands/base/BaseCommand.d.ts.map +1 -1
  125. package/dist/commands/base/BaseCommand.js +3 -3
  126. package/dist/commands/base/command-wrapper.d.ts +0 -4
  127. package/dist/commands/base/command-wrapper.d.ts.map +1 -1
  128. package/dist/commands/base/command-wrapper.js +13 -14
  129. package/dist/commands/base/middleware.d.ts +3 -3
  130. package/dist/commands/base/middleware.d.ts.map +1 -1
  131. package/dist/commands/base/middleware.js +4 -4
  132. package/dist/commands/config.d.ts.map +1 -1
  133. package/dist/commands/config.js +15 -32
  134. package/dist/commands/connectivity.d.ts.map +1 -1
  135. package/dist/commands/connectivity.js +6 -11
  136. package/dist/commands/debug.d.ts.map +1 -1
  137. package/dist/commands/debug.js +187 -46
  138. package/dist/commands/discover.d.ts.map +1 -1
  139. package/dist/commands/discover.js +4 -17
  140. package/dist/commands/gateway.d.ts.map +1 -1
  141. package/dist/commands/gateway.js +37 -77
  142. package/dist/commands/managedGateway/create.d.ts +6 -0
  143. package/dist/commands/managedGateway/create.d.ts.map +1 -0
  144. package/dist/commands/managedGateway/create.js +50 -0
  145. package/dist/commands/managedGateway/delete.d.ts +5 -0
  146. package/dist/commands/managedGateway/delete.d.ts.map +1 -0
  147. package/dist/commands/managedGateway/delete.js +57 -0
  148. package/dist/commands/managedGateway/get.d.ts +4 -0
  149. package/dist/commands/managedGateway/get.d.ts.map +1 -0
  150. package/dist/commands/managedGateway/get.js +71 -0
  151. package/dist/commands/managedGateway/haproxy-stats.d.ts +6 -0
  152. package/dist/commands/managedGateway/haproxy-stats.d.ts.map +1 -0
  153. package/dist/commands/managedGateway/haproxy-stats.js +131 -0
  154. package/dist/commands/managedGateway/list.d.ts +4 -0
  155. package/dist/commands/managedGateway/list.d.ts.map +1 -0
  156. package/dist/commands/managedGateway/list.js +50 -0
  157. package/dist/commands/managedGateway/logs.d.ts +10 -0
  158. package/dist/commands/managedGateway/logs.d.ts.map +1 -0
  159. package/dist/commands/managedGateway/logs.js +100 -0
  160. package/dist/commands/managedGateway/reboot.d.ts +5 -0
  161. package/dist/commands/managedGateway/reboot.d.ts.map +1 -0
  162. package/dist/commands/managedGateway/reboot.js +95 -0
  163. package/dist/commands/managedGateway/resync.d.ts +10 -0
  164. package/dist/commands/managedGateway/resync.d.ts.map +1 -0
  165. package/dist/commands/managedGateway/resync.js +69 -0
  166. package/dist/commands/managedGateway/ssh.d.ts +4 -0
  167. package/dist/commands/managedGateway/ssh.d.ts.map +1 -0
  168. package/dist/commands/managedGateway/ssh.js +130 -0
  169. package/dist/commands/managedGateway/wipe-logs.d.ts +4 -0
  170. package/dist/commands/managedGateway/wipe-logs.d.ts.map +1 -0
  171. package/dist/commands/managedGateway/wipe-logs.js +67 -0
  172. package/dist/commands/managedGateway/wireguard.d.ts +4 -0
  173. package/dist/commands/managedGateway/wireguard.d.ts.map +1 -0
  174. package/dist/commands/managedGateway/wireguard.js +68 -0
  175. package/dist/commands/managedGateway.d.ts.map +1 -1
  176. package/dist/commands/managedGateway.js +61 -117
  177. package/dist/commands/utils/config-validator.d.ts +5 -5
  178. package/dist/commands/utils/config-validator.d.ts.map +1 -1
  179. package/dist/commands/utils/config-validator.js +8 -8
  180. package/dist/commands/utils/output-formatter.js +1 -1
  181. package/dist/config/app-config.d.ts +1 -1
  182. package/dist/config/app-config.js +2 -2
  183. package/dist/index.js +0 -3
  184. package/dist/services/LocalAgentManager.d.ts.map +1 -1
  185. package/dist/services/LocalAgentManager.js +4 -2
  186. package/dist/services/agentDeployment/AgentDeploymentService.d.ts +35 -0
  187. package/dist/services/agentDeployment/AgentDeploymentService.d.ts.map +1 -0
  188. package/dist/services/agentDeployment/AgentDeploymentService.js +35 -0
  189. package/dist/services/application/ApplicationService.d.ts +5 -4
  190. package/dist/services/application/ApplicationService.d.ts.map +1 -1
  191. package/dist/services/application/ApplicationService.js +22 -35
  192. package/dist/services/auth/AuthService.d.ts +5 -5
  193. package/dist/services/auth/AuthService.d.ts.map +1 -1
  194. package/dist/services/auth/AuthService.js +11 -58
  195. package/dist/services/daemon/DaemonManagerFactory.d.ts +2 -0
  196. package/dist/services/daemon/DaemonManagerFactory.d.ts.map +1 -1
  197. package/dist/services/daemon/DaemonManagerFactory.js +14 -6
  198. package/dist/services/diagnostics/DiagnosticsService.d.ts +89 -0
  199. package/dist/services/diagnostics/DiagnosticsService.d.ts.map +1 -0
  200. package/dist/services/diagnostics/DiagnosticsService.js +37 -0
  201. package/dist/services/edgible.d.ts +6 -4
  202. package/dist/services/edgible.d.ts.map +1 -1
  203. package/dist/services/edgible.js +36 -86
  204. package/dist/services/gateway/GatewayService.d.ts +5 -6
  205. package/dist/services/gateway/GatewayService.d.ts.map +1 -1
  206. package/dist/services/gateway/GatewayService.js +22 -36
  207. package/dist/services/instances.d.ts +34 -0
  208. package/dist/services/instances.d.ts.map +1 -0
  209. package/dist/services/instances.js +64 -0
  210. package/dist/services/managedGateway/ManagedGatewayService.d.ts +75 -0
  211. package/dist/services/managedGateway/ManagedGatewayService.d.ts.map +1 -0
  212. package/dist/services/managedGateway/ManagedGatewayService.js +44 -0
  213. package/dist/services/token/TokenManager.d.ts +56 -0
  214. package/dist/services/token/TokenManager.d.ts.map +1 -0
  215. package/dist/services/token/TokenManager.js +85 -0
  216. package/dist/types/validation/schemas.d.ts +22 -22
  217. package/dist/utils/PlatformDetector.d.ts +2 -0
  218. package/dist/utils/PlatformDetector.d.ts.map +1 -1
  219. package/dist/utils/PlatformDetector.js +5 -34
  220. package/dist/validation/schemas.d.ts +6 -6
  221. package/package.json +1 -1
@@ -0,0 +1,6 @@
1
+ export declare function handleAiServe(options: {
2
+ port?: string;
3
+ ollamaUrl?: string;
4
+ detached?: boolean;
5
+ }): Promise<void>;
6
+ //# sourceMappingURL=serve.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"serve.d.ts","sourceRoot":"","sources":["../../../src/commands/ai/serve.ts"],"names":[],"mappings":"AAgBA,wBAAsB,aAAa,CAAC,OAAO,EAAE;IAC3C,IAAI,CAAC,EAAE,MAAM,CAAC;IACd,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,QAAQ,CAAC,EAAE,OAAO,CAAC;CACpB,GAAG,OAAO,CAAC,IAAI,CAAC,CA4HhB"}
@@ -0,0 +1,124 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.handleAiServe = handleAiServe;
7
+ const chalk_1 = __importDefault(require("chalk"));
8
+ const inquirer_1 = __importDefault(require("inquirer"));
9
+ const instances_1 = require("../../services/instances");
10
+ const helpers_1 = require("./helpers");
11
+ async function handleAiServe(options) {
12
+ instances_1.logger.info('Starting Open WebUI with Ollama');
13
+ console.log(chalk_1.default.blue('\n🌐 Starting Open WebUI'));
14
+ console.log(chalk_1.default.gray('This will start the Open WebUI interface connected to your local Ollama service.\n'));
15
+ // Step 1: Check if Ollama is installed
16
+ console.log(chalk_1.default.blue('Step 1: Checking Ollama installation...\n'));
17
+ const isOllamaInstalled = await (0, helpers_1.checkOllamaInstalled)();
18
+ if (!isOllamaInstalled) {
19
+ console.log(chalk_1.default.red('✗ Ollama is not installed'));
20
+ console.log(chalk_1.default.yellow('\nPlease run: edgible ai setup\n'));
21
+ throw new Error('Ollama is required but not installed');
22
+ }
23
+ console.log(chalk_1.default.green('✓ Ollama is installed\n'));
24
+ // Step 2: Check if Ollama is running
25
+ console.log(chalk_1.default.blue('Step 2: Checking if Ollama is running...\n'));
26
+ const isOllamaRunning = await (0, helpers_1.checkOllamaRunning)();
27
+ if (!isOllamaRunning) {
28
+ console.log(chalk_1.default.yellow('⚠ Ollama is not running'));
29
+ const answer = await inquirer_1.default.prompt([
30
+ {
31
+ type: 'confirm',
32
+ name: 'start',
33
+ message: 'Would you like to start Ollama now?',
34
+ default: true,
35
+ },
36
+ ]);
37
+ if (answer.start) {
38
+ console.log(chalk_1.default.yellow('Starting Ollama...\n'));
39
+ await (0, helpers_1.startOllama)();
40
+ // Wait and verify
41
+ await new Promise(resolve => setTimeout(resolve, 2000));
42
+ const isRunningNow = await (0, helpers_1.checkOllamaRunning)();
43
+ if (!isRunningNow) {
44
+ throw new Error('Failed to start Ollama. Please start it manually.');
45
+ }
46
+ console.log(chalk_1.default.green('✓ Ollama started\n'));
47
+ }
48
+ else {
49
+ throw new Error('Ollama must be running. Please start it with: edgible ai setup');
50
+ }
51
+ }
52
+ else {
53
+ console.log(chalk_1.default.green('✓ Ollama is running\n'));
54
+ }
55
+ // Step 2.5: Check and fix Ollama binding if needed (for Docker access)
56
+ console.log(chalk_1.default.blue('Step 2.5: Checking Ollama network binding...\n'));
57
+ const listeningAddress = await (0, helpers_1.checkOllamaListeningAddress)();
58
+ if (listeningAddress === '127.0.0.1') {
59
+ console.log(chalk_1.default.yellow('⚠ Ollama is listening on localhost only (127.0.0.1:11434)'));
60
+ console.log(chalk_1.default.gray(' Docker containers cannot access Ollama on localhost.\n'));
61
+ console.log(chalk_1.default.yellow(' Reconfiguring Ollama to listen on all interfaces (0.0.0.0:11434)...\n'));
62
+ const fixed = await (0, helpers_1.fixOllamaBinding)();
63
+ if (fixed) {
64
+ // Wait a moment and verify it's now on 0.0.0.0
65
+ await new Promise((resolve) => setTimeout(resolve, 2000));
66
+ const newAddress = await (0, helpers_1.checkOllamaListeningAddress)();
67
+ if (newAddress === '0.0.0.0') {
68
+ console.log(chalk_1.default.green('✓ Ollama reconfigured to listen on 0.0.0.0:11434\n'));
69
+ }
70
+ else {
71
+ console.log(chalk_1.default.yellow('⚠ Could not verify binding change. Continuing anyway...\n'));
72
+ }
73
+ }
74
+ else {
75
+ console.log(chalk_1.default.yellow('⚠ Could not automatically reconfigure Ollama binding.\n'));
76
+ console.log(chalk_1.default.gray(' Docker may not be able to connect. Please manually set OLLAMA_HOST=0.0.0.0:11434 and restart Ollama.\n'));
77
+ }
78
+ }
79
+ else if (listeningAddress === '0.0.0.0') {
80
+ console.log(chalk_1.default.green('✓ Ollama is listening on all interfaces (accessible to Docker)\n'));
81
+ }
82
+ else {
83
+ console.log(chalk_1.default.gray(' Could not determine Ollama binding address (assuming accessible)\n'));
84
+ }
85
+ // Step 3: Check if any models are available
86
+ console.log(chalk_1.default.blue('Step 3: Checking available models...\n'));
87
+ const hasModels = await (0, helpers_1.checkHasModels)();
88
+ if (!hasModels) {
89
+ console.log(chalk_1.default.yellow('⚠ No Ollama models found'));
90
+ console.log(chalk_1.default.yellow('Please pull a model first with: edgible ai setup\n'));
91
+ throw new Error('At least one Ollama model is required');
92
+ }
93
+ console.log(chalk_1.default.green('✓ Models available\n'));
94
+ // Step 4: Check if Docker is installed
95
+ console.log(chalk_1.default.blue('Step 4: Checking Docker installation...\n'));
96
+ const isDockerInstalled = await (0, helpers_1.checkDockerInstalled)();
97
+ if (!isDockerInstalled) {
98
+ console.log(chalk_1.default.red('✗ Docker is not installed'));
99
+ console.log(chalk_1.default.yellow('Please install Docker from: https://docs.docker.com/get-docker/\n'));
100
+ throw new Error('Docker is required to run Open WebUI');
101
+ }
102
+ console.log(chalk_1.default.green('✓ Docker is installed\n'));
103
+ // Step 5: Determine Ollama URL for Docker
104
+ console.log(chalk_1.default.blue('Step 5: Configuring connection...\n'));
105
+ const ollamaUrl = options.ollamaUrl || await (0, helpers_1.detectOllamaUrlForDocker)();
106
+ console.log(chalk_1.default.gray(` Using Ollama URL: ${ollamaUrl}\n`));
107
+ // Step 6: Start Docker Compose
108
+ console.log(chalk_1.default.blue('Step 6: Starting Open WebUI...\n'));
109
+ const composeDir = (0, helpers_1.getComposeDirectory)();
110
+ const port = parseInt(options.port || '3200', 10);
111
+ await (0, helpers_1.startOpenWebUI)(composeDir, {
112
+ OLLAMA_BASE_URL: ollamaUrl,
113
+ OPEN_WEBUI_PORT: port.toString(),
114
+ });
115
+ console.log(chalk_1.default.green('✓ Open WebUI started successfully!\n'));
116
+ console.log(chalk_1.default.blue('🎉 Setup Complete!\n'));
117
+ console.log(chalk_1.default.white('Access Open WebUI at:'));
118
+ console.log(chalk_1.default.cyan(` http://localhost:${port}\n`));
119
+ console.log(chalk_1.default.gray('Useful commands:'));
120
+ console.log(chalk_1.default.gray(` edgible ai status # Check service status`));
121
+ console.log(chalk_1.default.gray(` edgible ai teardown # Stop Open WebUI`));
122
+ console.log(chalk_1.default.gray(` docker logs open-webui # View logs\n`));
123
+ }
124
+ //# sourceMappingURL=serve.js.map
@@ -0,0 +1,14 @@
1
+ export declare function handleAiSetup(options: {
2
+ model?: string;
3
+ autoInstall?: boolean;
4
+ localOnly?: boolean;
5
+ exposeOllama?: boolean;
6
+ setupWebui?: boolean;
7
+ deviceId?: string;
8
+ ollamaDeviceId?: string;
9
+ webuiDeviceId?: string;
10
+ gatewayIds?: string;
11
+ webuiDeployment?: string;
12
+ noInteractive?: boolean;
13
+ }): Promise<void>;
14
+ //# sourceMappingURL=setup.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"setup.d.ts","sourceRoot":"","sources":["../../../src/commands/ai/setup.ts"],"names":[],"mappings":"AAMA,wBAAsB,aAAa,CAAC,OAAO,EAAE;IAC3C,KAAK,CAAC,EAAE,MAAM,CAAC;IACf,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,cAAc,CAAC,EAAE,MAAM,CAAC;IACxB,aAAa,CAAC,EAAE,MAAM,CAAC;IACvB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,eAAe,CAAC,EAAE,MAAM,CAAC;IACzB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB,GAAG,OAAO,CAAC,IAAI,CAAC,CAgFhB"}
@@ -0,0 +1,86 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.handleAiSetup = handleAiSetup;
7
+ const chalk_1 = __importDefault(require("chalk"));
8
+ const instances_1 = require("../../services/instances");
9
+ const DaemonManagerFactory_1 = require("../../services/daemon/DaemonManagerFactory");
10
+ const sudo_checker_1 = require("../../utils/sudo-checker");
11
+ const helpers_1 = require("./helpers");
12
+ async function handleAiSetup(options) {
13
+ if (!(0, sudo_checker_1.checkSudoPermissions)()) {
14
+ console.log(chalk_1.default.redBright("Please run this command with administrator priviledges (i.e. sudo)"));
15
+ return;
16
+ }
17
+ instances_1.logger.info('Setting up Ollama AI service', { model: options.model, autoInstall: options.autoInstall });
18
+ console.log(chalk_1.default.blue('\n🤖 Ollama AI Setup'));
19
+ console.log(chalk_1.default.gray('This will install Ollama, check system capabilities, and start with a selected model.\n'));
20
+ // Check if daemon is running (required before setup)
21
+ console.log(chalk_1.default.blue('Prerequisite: Checking daemon status...\n'));
22
+ const config = instances_1.configManager.getConfig();
23
+ let daemonRunning = false;
24
+ // Check daemon status if installation type is configured
25
+ if (config.agentInstallationType) {
26
+ try {
27
+ const daemonManager = DaemonManagerFactory_1.DaemonManagerFactory.fromConfig(config.agentInstallationType);
28
+ if (daemonManager) {
29
+ const daemonStatus = await daemonManager.status();
30
+ daemonRunning = daemonStatus.running;
31
+ if (daemonRunning) {
32
+ console.log(chalk_1.default.green('✓ Daemon is running\n'));
33
+ }
34
+ else {
35
+ console.log(chalk_1.default.red('✗ Daemon is not running\n'));
36
+ }
37
+ }
38
+ }
39
+ catch (error) {
40
+ console.log(chalk_1.default.yellow('⚠ Could not check daemon status\n'));
41
+ console.log(chalk_1.default.gray(` Error: ${error instanceof Error ? error.message : String(error)}\n`));
42
+ }
43
+ }
44
+ else {
45
+ // Fallback: check agent status file if no daemon type is configured
46
+ console.log(chalk_1.default.gray(' No daemon installation type configured, checking agent status file...\n'));
47
+ const agentManager = instances_1.localAgentManager;
48
+ const agentStatus = await agentManager.checkLocalAgentStatus();
49
+ daemonRunning = agentStatus.running;
50
+ if (daemonRunning) {
51
+ console.log(chalk_1.default.green('✓ Agent is running\n'));
52
+ }
53
+ else {
54
+ console.log(chalk_1.default.red('✗ Agent is not running\n'));
55
+ }
56
+ }
57
+ if (!daemonRunning) {
58
+ console.log(chalk_1.default.yellow('The device agent daemon must be running before setting up AI services.\n'));
59
+ console.log(chalk_1.default.blue('Please start the agent first:'));
60
+ console.log(chalk_1.default.gray(' edgible agent start\n'));
61
+ console.log(chalk_1.default.gray('Then run this setup command again.\n'));
62
+ throw new Error('Device agent daemon is not running. Please start it with: edgible agent start');
63
+ }
64
+ // Phase 1: Local Ollama Setup
65
+ const { capabilities } = await (0, helpers_1.setupLocalOllama)({
66
+ autoInstall: options.autoInstall,
67
+ model: options.model,
68
+ });
69
+ // Phase 2: Platform Integration
70
+ const { ollamaUrl, webUIUrl, createdOllamaApp, createdWebUIApp, deviceName, deviceId, ollamaModelName } = await (0, helpers_1.setupPlatformIntegration)({
71
+ model: options.model,
72
+ capabilities,
73
+ logger: instances_1.logger,
74
+ });
75
+ // Phase 3: Display Summary
76
+ (0, helpers_1.displaySetupSummary)({
77
+ ollamaModelName,
78
+ ollamaUrl,
79
+ webUIUrl,
80
+ deviceName,
81
+ deviceId,
82
+ createdOllamaApp,
83
+ createdWebUIApp,
84
+ });
85
+ }
86
+ //# sourceMappingURL=setup.js.map
@@ -0,0 +1,2 @@
1
+ export declare function handleAiStatus(): Promise<void>;
2
+ //# sourceMappingURL=status.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"status.d.ts","sourceRoot":"","sources":["../../../src/commands/ai/status.ts"],"names":[],"mappings":"AAMA,wBAAsB,cAAc,IAAI,OAAO,CAAC,IAAI,CAAC,CAwJpD"}
@@ -0,0 +1,160 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.handleAiStatus = handleAiStatus;
7
+ const chalk_1 = __importDefault(require("chalk"));
8
+ const child_process_1 = require("child_process");
9
+ const instances_1 = require("../../services/instances");
10
+ const config_validator_1 = require("../utils/config-validator");
11
+ const helpers_1 = require("./helpers");
12
+ async function handleAiStatus() {
13
+ instances_1.logger.info('Checking AI services status');
14
+ console.log(chalk_1.default.blue('\n📊 AI Services Status\n'));
15
+ // Check Ollama Local
16
+ console.log(chalk_1.default.white('Ollama (Local):'));
17
+ const isOllamaInstalled = await (0, helpers_1.checkOllamaInstalled)();
18
+ const isOllamaRunning = isOllamaInstalled ? await (0, helpers_1.checkOllamaRunning)() : false;
19
+ if (!isOllamaInstalled) {
20
+ console.log(chalk_1.default.red(' ✗ Not installed'));
21
+ }
22
+ else if (isOllamaRunning) {
23
+ console.log(chalk_1.default.green(' ✓ Running'));
24
+ // Check what address it's listening on
25
+ try {
26
+ const output = (0, child_process_1.execSync)('ss -tlnp 2>/dev/null | grep 11435 || netstat -tlnp 2>/dev/null | grep 11435', {
27
+ encoding: 'utf8',
28
+ timeout: 2000
29
+ });
30
+ if (output.includes('0.0.0.0:11435') || output.includes('*:11435')) {
31
+ console.log(chalk_1.default.gray(' Listening on: 0.0.0.0:11435 (accessible from network)'));
32
+ }
33
+ else if (output.includes('127.0.0.1:11435')) {
34
+ console.log(chalk_1.default.yellow(' Listening on: 127.0.0.1:11435 (localhost only)'));
35
+ }
36
+ }
37
+ catch {
38
+ // Ignore if ss/netstat fails
39
+ }
40
+ // Show available models
41
+ try {
42
+ const output = (0, child_process_1.execSync)('ollama list', { encoding: 'utf8', timeout: 5000 });
43
+ const lines = output.trim().split('\n');
44
+ if (lines.length > 1) {
45
+ console.log(chalk_1.default.gray(` Models: ${lines.length - 1} available`));
46
+ }
47
+ }
48
+ catch {
49
+ // Ignore
50
+ }
51
+ }
52
+ else {
53
+ console.log(chalk_1.default.yellow(' ⚠ Installed but not running'));
54
+ }
55
+ console.log('');
56
+ // Check Ollama Platform Application
57
+ console.log(chalk_1.default.white('Ollama (Platform):'));
58
+ try {
59
+ (0, config_validator_1.validateConfig)(instances_1.configManager, {
60
+ requireAuth: true,
61
+ requireOrganization: true,
62
+ });
63
+ const applications = await instances_1.applicationService.getApplications();
64
+ const ollamaApp = applications.find(app => app.name === 'ollama-api');
65
+ if (ollamaApp) {
66
+ console.log(chalk_1.default.green(' ✓ Application exists'));
67
+ console.log(chalk_1.default.gray(` ID: ${ollamaApp.id}`));
68
+ // Extract URL from application
69
+ let ollamaUrl;
70
+ if (ollamaApp.url) {
71
+ // Use URL directly if available
72
+ ollamaUrl = ollamaApp.url;
73
+ }
74
+ else if (ollamaApp.servingIp && ollamaApp.servingIp !== 'unknown') {
75
+ // Construct URL from servingIp
76
+ const protocol = ollamaApp.protocol === 'https' ? 'https' : 'http';
77
+ const port = ollamaApp.port === 443 || ollamaApp.port === 80 ? '' : `:${ollamaApp.port}`;
78
+ ollamaUrl = `${protocol}://${ollamaApp.servingIp}${port}`;
79
+ }
80
+ if (ollamaUrl) {
81
+ console.log(chalk_1.default.cyan(` URL: ${ollamaUrl}`));
82
+ // Test if it's reachable
83
+ const isReachable = await (0, helpers_1.checkOllamaUrlReachable)(ollamaUrl);
84
+ if (isReachable) {
85
+ console.log(chalk_1.default.green(' ✓ Reachable and responding'));
86
+ }
87
+ else {
88
+ console.log(chalk_1.default.red(' ✗ Not reachable or not responding'));
89
+ }
90
+ }
91
+ else {
92
+ console.log(chalk_1.default.yellow(' ⚠ URL not available'));
93
+ }
94
+ }
95
+ else {
96
+ console.log(chalk_1.default.gray(' ○ No platform application found'));
97
+ }
98
+ }
99
+ catch (error) {
100
+ if (error instanceof Error && error.message.includes('auth')) {
101
+ console.log(chalk_1.default.gray(' ○ Not logged in (cannot check platform apps)'));
102
+ }
103
+ else {
104
+ console.log(chalk_1.default.yellow(` ⚠ Error checking platform: ${error instanceof Error ? error.message : 'Unknown'}`));
105
+ }
106
+ }
107
+ console.log('');
108
+ // Check Open WebUI
109
+ console.log(chalk_1.default.white('Open WebUI:'));
110
+ const webUIInfo = await (0, helpers_1.getOpenWebUIInfo)();
111
+ if (webUIInfo) {
112
+ console.log(chalk_1.default.green(' ✓ Running (Local)'));
113
+ console.log(chalk_1.default.cyan(` URL: http://localhost:${webUIInfo.port}`));
114
+ }
115
+ else {
116
+ // Check for platform application
117
+ try {
118
+ (0, config_validator_1.validateConfig)(instances_1.configManager, {
119
+ requireAuth: true,
120
+ requireOrganization: true,
121
+ });
122
+ const applications = await instances_1.applicationService.getApplications();
123
+ const webUIApp = applications.find(app => app.name === 'open-webui');
124
+ if (webUIApp) {
125
+ console.log(chalk_1.default.green(' ✓ Application exists (Platform)'));
126
+ console.log(chalk_1.default.gray(` ID: ${webUIApp.id}`));
127
+ let webUIUrl;
128
+ if (webUIApp.url) {
129
+ // Use URL directly if available
130
+ webUIUrl = webUIApp.url;
131
+ }
132
+ else if (webUIApp.servingIp && webUIApp.servingIp !== 'unknown') {
133
+ // Construct URL from servingIp
134
+ const protocol = webUIApp.protocol === 'https' ? 'https' : 'http';
135
+ const port = webUIApp.port === 443 || webUIApp.port === 80 ? '' : `:${webUIApp.port}`;
136
+ webUIUrl = `${protocol}://${webUIApp.servingIp}${port}`;
137
+ }
138
+ if (webUIUrl) {
139
+ console.log(chalk_1.default.cyan(` URL: ${webUIUrl}`));
140
+ // Test if it's reachable
141
+ const isReachable = await (0, helpers_1.checkUrlReachable)(webUIUrl);
142
+ if (isReachable) {
143
+ console.log(chalk_1.default.green(' ✓ Reachable'));
144
+ }
145
+ else {
146
+ console.log(chalk_1.default.red(' ✗ Not reachable'));
147
+ }
148
+ }
149
+ }
150
+ else {
151
+ console.log(chalk_1.default.gray(' ○ Not running (local or platform)'));
152
+ }
153
+ }
154
+ catch {
155
+ console.log(chalk_1.default.gray(' ○ Not running'));
156
+ }
157
+ }
158
+ console.log('');
159
+ }
160
+ //# sourceMappingURL=status.js.map
@@ -0,0 +1,2 @@
1
+ export declare function handleAiStop(): Promise<void>;
2
+ //# sourceMappingURL=stop.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"stop.d.ts","sourceRoot":"","sources":["../../../src/commands/ai/stop.ts"],"names":[],"mappings":"AAIA,wBAAsB,YAAY,IAAI,OAAO,CAAC,IAAI,CAAC,CAalD"}
@@ -0,0 +1,21 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.handleAiStop = handleAiStop;
7
+ const chalk_1 = __importDefault(require("chalk"));
8
+ const instances_1 = require("../../services/instances");
9
+ const helpers_1 = require("./helpers");
10
+ async function handleAiStop() {
11
+ instances_1.logger.info('Stopping Ollama service');
12
+ console.log(chalk_1.default.blue('\n🛑 Stopping Ollama service...\n'));
13
+ const isRunning = await (0, helpers_1.checkOllamaRunning)();
14
+ if (!isRunning) {
15
+ console.log(chalk_1.default.yellow('Ollama is not running\n'));
16
+ return;
17
+ }
18
+ await (0, helpers_1.stopOllama)();
19
+ console.log(chalk_1.default.green('✓ Ollama service stopped\n'));
20
+ }
21
+ //# sourceMappingURL=stop.js.map
@@ -0,0 +1,5 @@
1
+ export declare function handleAiTeardown(options: {
2
+ stopOllama?: boolean;
3
+ removeVolumes?: boolean;
4
+ }): Promise<void>;
5
+ //# sourceMappingURL=teardown.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"teardown.d.ts","sourceRoot":"","sources":["../../../src/commands/ai/teardown.ts"],"names":[],"mappings":"AAKA,wBAAsB,gBAAgB,CAAC,OAAO,EAAE;IAC9C,UAAU,CAAC,EAAE,OAAO,CAAC;IACrB,aAAa,CAAC,EAAE,OAAO,CAAC;CACzB,GAAG,OAAO,CAAC,IAAI,CAAC,CA2EhB"}
@@ -0,0 +1,78 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.handleAiTeardown = handleAiTeardown;
7
+ const chalk_1 = __importDefault(require("chalk"));
8
+ const instances_1 = require("../../services/instances");
9
+ const config_validator_1 = require("../utils/config-validator");
10
+ const helpers_1 = require("./helpers");
11
+ async function handleAiTeardown(options) {
12
+ instances_1.logger.info('Tearing down AI services');
13
+ console.log(chalk_1.default.blue('\n🛑 AI Services Teardown\n'));
14
+ // Stop local Open WebUI if running
15
+ const composeDir = (0, helpers_1.getComposeDirectory)();
16
+ const isRunning = await (0, helpers_1.checkOpenWebUIRunning)();
17
+ if (!isRunning) {
18
+ console.log(chalk_1.default.gray(' Local Open WebUI is not running\n'));
19
+ }
20
+ else {
21
+ console.log(chalk_1.default.yellow('Stopping local Open WebUI...\n'));
22
+ await (0, helpers_1.stopOpenWebUI)(composeDir, options.removeVolumes || false);
23
+ console.log(chalk_1.default.green('✓ Local Open WebUI stopped\n'));
24
+ }
25
+ // Optionally stop Ollama
26
+ if (options.stopOllama) {
27
+ console.log(chalk_1.default.yellow('Stopping Ollama service...\n'));
28
+ const isOllamaRunning = await (0, helpers_1.checkOllamaRunning)();
29
+ if (isOllamaRunning) {
30
+ await (0, helpers_1.stopOllama)();
31
+ console.log(chalk_1.default.green('✓ Ollama stopped\n'));
32
+ }
33
+ else {
34
+ console.log(chalk_1.default.gray('Ollama is not running\n'));
35
+ }
36
+ }
37
+ // Optionally remove platform applications
38
+ console.log(chalk_1.default.yellow('\nRemoving platform applications...\n'));
39
+ try {
40
+ (0, config_validator_1.validateConfig)(instances_1.configManager, {
41
+ requireAuth: true,
42
+ requireOrganization: true,
43
+ });
44
+ const applications = await instances_1.applicationService.getApplications();
45
+ // Find AI-related applications
46
+ const ollamaApp = applications.find(app => app.name === 'ollama-api');
47
+ const webUIApp = applications.find(app => app.name === 'open-webui');
48
+ if (ollamaApp) {
49
+ console.log(chalk_1.default.yellow(` Removing ollama-api (${ollamaApp.id})...`));
50
+ await instances_1.applicationService.deleteApplication(ollamaApp.id);
51
+ console.log(chalk_1.default.green(' ✓ Removed ollama-api'));
52
+ }
53
+ if (webUIApp) {
54
+ console.log(chalk_1.default.yellow(` Removing open-webui (${webUIApp.id})...`));
55
+ await instances_1.applicationService.deleteApplication(webUIApp.id);
56
+ console.log(chalk_1.default.green(' ✓ Removed open-webui'));
57
+ }
58
+ if (!ollamaApp && !webUIApp) {
59
+ console.log(chalk_1.default.gray(' No AI applications found\n'));
60
+ }
61
+ else {
62
+ console.log(chalk_1.default.green('\n✓ Platform applications removed\n'));
63
+ }
64
+ }
65
+ catch (error) {
66
+ if (error instanceof Error && error.message.includes('auth')) {
67
+ console.log(chalk_1.default.yellow(' ⚠ Not logged in - skipping platform application removal\n'));
68
+ }
69
+ else {
70
+ console.log(chalk_1.default.red(` ✗ Error removing applications: ${error instanceof Error ? error.message : 'Unknown error'}\n`));
71
+ }
72
+ }
73
+ console.log(chalk_1.default.green('✅ Teardown complete!\n'));
74
+ if (options.removeVolumes) {
75
+ console.log(chalk_1.default.yellow('⚠ Data volumes were removed. All local WebUI data has been deleted.\n'));
76
+ }
77
+ }
78
+ //# sourceMappingURL=teardown.js.map
@@ -0,0 +1,4 @@
1
+ export declare function handleAiTest(options: {
2
+ model?: string;
3
+ }): Promise<void>;
4
+ //# sourceMappingURL=test.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"test.d.ts","sourceRoot":"","sources":["../../../src/commands/ai/test.ts"],"names":[],"mappings":"AAKA,wBAAsB,YAAY,CAAC,OAAO,EAAE;IAAE,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,GAAG,OAAO,CAAC,IAAI,CAAC,CAwD7E"}
@@ -0,0 +1,65 @@
1
+ "use strict";
2
+ var __importDefault = (this && this.__importDefault) || function (mod) {
3
+ return (mod && mod.__esModule) ? mod : { "default": mod };
4
+ };
5
+ Object.defineProperty(exports, "__esModule", { value: true });
6
+ exports.handleAiTest = handleAiTest;
7
+ const chalk_1 = __importDefault(require("chalk"));
8
+ const child_process_1 = require("child_process");
9
+ const instances_1 = require("../../services/instances");
10
+ const helpers_1 = require("./helpers");
11
+ async function handleAiTest(options) {
12
+ instances_1.logger.info('Testing Ollama model connectivity', { model: options.model });
13
+ console.log(chalk_1.default.blue('\n🧪 Testing Ollama Model\n'));
14
+ // Check if Ollama is running
15
+ console.log(chalk_1.default.blue('Step 1: Checking Ollama service...\n'));
16
+ const isRunning = await (0, helpers_1.checkOllamaRunning)();
17
+ if (!isRunning) {
18
+ console.log(chalk_1.default.red('✗ Ollama is not running'));
19
+ console.log(chalk_1.default.yellow('\nPlease start Ollama first with: edgible ai setup\n'));
20
+ throw new Error('Ollama service is not running');
21
+ }
22
+ console.log(chalk_1.default.green('✓ Ollama is running\n'));
23
+ // Determine which model to test
24
+ let testModel = options.model;
25
+ if (!testModel) {
26
+ console.log(chalk_1.default.blue('Step 2: Finding available models...\n'));
27
+ try {
28
+ const output = (0, child_process_1.execSync)('ollama list', { encoding: 'utf8', timeout: 5000 });
29
+ const lines = output.trim().split('\n');
30
+ if (lines.length > 1) {
31
+ // Parse first model from list (skip header)
32
+ const modelLine = lines[1];
33
+ testModel = modelLine.split(/\s+/)[0];
34
+ console.log(chalk_1.default.gray(` Using first available model: ${testModel}\n`));
35
+ }
36
+ else {
37
+ console.log(chalk_1.default.red('✗ No models found'));
38
+ console.log(chalk_1.default.yellow('\nPlease pull a model first with: edgible ai setup\n'));
39
+ throw new Error('No Ollama models available');
40
+ }
41
+ }
42
+ catch (error) {
43
+ console.log(chalk_1.default.red('✗ Failed to list models\n'));
44
+ throw error;
45
+ }
46
+ }
47
+ // Test model connectivity
48
+ console.log(chalk_1.default.blue(`Step 3: Testing model "${testModel}"...\n`));
49
+ const modelWorks = await (0, helpers_1.testModelConnectivity)(testModel, true);
50
+ if (modelWorks) {
51
+ console.log(chalk_1.default.green(`\n✅ Model "${testModel}" is working correctly!\n`));
52
+ console.log(chalk_1.default.white('The model is ready to use with:'));
53
+ console.log(chalk_1.default.gray(` edgible ai serve # Start Open WebUI`));
54
+ console.log(chalk_1.default.gray(` ollama run ${testModel} # Use in terminal\n`));
55
+ }
56
+ else {
57
+ console.log(chalk_1.default.red(`\n✗ Model "${testModel}" failed to respond\n`));
58
+ console.log(chalk_1.default.yellow('Troubleshooting tips:'));
59
+ console.log(chalk_1.default.gray(' 1. Check if the model exists: ollama list'));
60
+ console.log(chalk_1.default.gray(' 2. Try pulling the model again: ollama pull ' + testModel));
61
+ console.log(chalk_1.default.gray(' 3. Check Ollama logs for errors'));
62
+ console.log(chalk_1.default.gray(' 4. Restart Ollama: edgible ai stop && edgible ai setup\n'));
63
+ }
64
+ }
65
+ //# sourceMappingURL=test.js.map
@@ -1 +1 @@
1
- {"version":3,"file":"ai.d.ts","sourceRoot":"","sources":["../../src/commands/ai.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AAmCpC,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CAioBtD"}
1
+ {"version":3,"file":"ai.d.ts","sourceRoot":"","sources":["../../src/commands/ai.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,OAAO,EAAE,MAAM,WAAW,CAAC;AASpC,wBAAgB,eAAe,CAAC,OAAO,EAAE,OAAO,GAAG,IAAI,CA0HtD"}