mindroot 9.3.0__py3-none-any.whl → 9.6.0__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.
Files changed (183) hide show
  1. mindroot/coreplugins/admin/__init__.py +3 -1
  2. mindroot/coreplugins/admin/agent_router.py +250 -7
  3. mindroot/coreplugins/admin/asset_manager.py +164 -0
  4. mindroot/coreplugins/admin/command_router.py +236 -1
  5. mindroot/coreplugins/admin/mcp_catalog_routes.py +156 -0
  6. mindroot/coreplugins/admin/mcp_publish_routes.py +450 -0
  7. mindroot/coreplugins/admin/mcp_registry_routes.py +495 -0
  8. mindroot/coreplugins/admin/mcp_routes.py +216 -0
  9. mindroot/coreplugins/admin/mod.py +62 -0
  10. mindroot/coreplugins/admin/oauth_callback_router.py +84 -0
  11. mindroot/coreplugins/admin/persona_handler.py +15 -6
  12. mindroot/coreplugins/admin/persona_router.py +158 -2
  13. mindroot/coreplugins/admin/plugin_manager.py +105 -9
  14. mindroot/coreplugins/admin/plugin_router_fixed.py +23 -0
  15. mindroot/coreplugins/admin/plugin_router_new_not_working.py +145 -0
  16. mindroot/coreplugins/admin/plugin_routes.py +114 -0
  17. mindroot/coreplugins/admin/registry_settings_routes.py +140 -0
  18. mindroot/coreplugins/admin/router.py +116 -15
  19. mindroot/coreplugins/admin/service_models.py +1 -1
  20. mindroot/coreplugins/admin/settings_router.py +1 -0
  21. mindroot/coreplugins/admin/static/css/admin-custom.css +357 -2
  22. mindroot/coreplugins/admin/static/css/dark.css +1 -0
  23. mindroot/coreplugins/admin/static/css/default.css +4 -0
  24. mindroot/coreplugins/admin/static/js/about-info.js +367 -0
  25. mindroot/coreplugins/admin/static/js/agent-form.js +83 -3
  26. mindroot/coreplugins/admin/static/js/api-key-script.js +307 -0
  27. mindroot/coreplugins/admin/static/js/mcp-manager.js +348 -0
  28. mindroot/coreplugins/admin/static/js/mcp-publisher.js +780 -0
  29. mindroot/coreplugins/admin/static/js/persona-editor.js +34 -5
  30. mindroot/coreplugins/admin/static/js/plugin-toggle.js +1 -1
  31. mindroot/coreplugins/admin/static/js/recommended-plugin-install.js +63 -0
  32. mindroot/coreplugins/admin/static/js/registry-auth-section.js +132 -0
  33. mindroot/coreplugins/admin/static/js/registry-manager-base.js +613 -0
  34. mindroot/coreplugins/admin/static/js/registry-manager-publish-old-delete.js +166 -0
  35. mindroot/coreplugins/admin/static/js/registry-manager.js +351 -0
  36. mindroot/coreplugins/admin/static/js/registry-publish-section.js +377 -0
  37. mindroot/coreplugins/admin/static/js/registry-search-section.js +400 -0
  38. mindroot/coreplugins/admin/static/js/registry-search-section.js.bak +3 -0
  39. mindroot/coreplugins/admin/static/js/registry-settings.js +69 -0
  40. mindroot/coreplugins/admin/static/js/registry-shared-services.js +903 -0
  41. mindroot/coreplugins/admin/static/js/registry-simple-sections.js +85 -0
  42. mindroot/coreplugins/admin/static/js/secure-widget-manager.js +438 -0
  43. mindroot/coreplugins/admin/static/logo.png +0 -0
  44. mindroot/coreplugins/admin/templates/admin.jinja2 +275 -110
  45. mindroot/coreplugins/agent/Assistant/agent.json +27 -11
  46. mindroot/coreplugins/agent/agent.py +2 -2
  47. mindroot/coreplugins/agent/command_parser.py +25 -10
  48. mindroot/coreplugins/agent/templates/system.jinja2 +0 -12
  49. mindroot/coreplugins/chat/__init__.py +4 -1
  50. mindroot/coreplugins/chat/router.py +132 -20
  51. mindroot/coreplugins/chat/router_dedup_patch.py +20 -0
  52. mindroot/coreplugins/chat/services.py +31 -1
  53. mindroot/coreplugins/chat/static/css/action-fix.css +32 -0
  54. mindroot/coreplugins/chat/static/css/admin-custom.css +5 -3
  55. mindroot/coreplugins/chat/static/css/dark.css +24 -3
  56. mindroot/coreplugins/chat/static/css/default.css +24 -3
  57. mindroot/coreplugins/chat/static/css/main.css +1 -0
  58. mindroot/coreplugins/chat/static/js/action.js +137 -60
  59. mindroot/coreplugins/chat/static/js/chat-history.js +3 -0
  60. mindroot/coreplugins/chat/static/js/chat.js +59 -16
  61. mindroot/coreplugins/chat/static/js/chat.js.diff +221 -0
  62. mindroot/coreplugins/chat/static/js/chatform.js +2 -2
  63. mindroot/coreplugins/chat/static/site.webmanifest +1 -1
  64. mindroot/coreplugins/chat/templates/chat.jinja2 +3 -3
  65. mindroot/coreplugins/chat/widget_manager.py +139 -0
  66. mindroot/coreplugins/chat/widget_routes.py +287 -0
  67. mindroot/coreplugins/check_list/inject/admin.jinja2 +1 -1
  68. mindroot/coreplugins/email/__init__.py +2 -0
  69. mindroot/coreplugins/email/email_provider.py +2 -2
  70. mindroot/coreplugins/email/mod.py +100 -0
  71. mindroot/coreplugins/email/services.py +5 -3
  72. mindroot/coreplugins/email/smtp_handler.py +9 -3
  73. mindroot/coreplugins/email/test_email_service.py +75 -0
  74. mindroot/coreplugins/env_manager/mod.py +61 -25
  75. mindroot/coreplugins/home/router.py +37 -2
  76. mindroot/coreplugins/home/static/imgs/logo.png +0 -0
  77. mindroot/coreplugins/home/static/imgs/logo.png.bak +0 -0
  78. mindroot/coreplugins/home/static/imgs/logo_teal.png +0 -0
  79. mindroot/coreplugins/home/static/imgs/logo_teal2.png +0 -0
  80. mindroot/coreplugins/home/static/imgs/logo_teal_detailed.png +0 -0
  81. mindroot/coreplugins/home/static/imgs/logo_teal_python.png +0 -0
  82. mindroot/coreplugins/home/templates/home.jinja2 +15 -6
  83. mindroot/coreplugins/index/indices/default/index.json +39 -6
  84. mindroot/coreplugins/jwt_auth/middleware.py +47 -2
  85. mindroot/coreplugins/jwt_auth/mod.py +40 -17
  86. mindroot/coreplugins/l8n/__init__.py +6 -0
  87. mindroot/coreplugins/l8n/debug_loader.py +85 -0
  88. mindroot/coreplugins/l8n/debug_middleware.py +74 -0
  89. mindroot/coreplugins/l8n/l8n_constants.py +19 -0
  90. mindroot/coreplugins/l8n/language_detection.py +183 -0
  91. mindroot/coreplugins/l8n/middleware.py +151 -0
  92. mindroot/coreplugins/l8n/mod.py +277 -0
  93. mindroot/coreplugins/l8n/monkey_patch_to_delete.py +186 -0
  94. mindroot/coreplugins/l8n/test_enhanced.py +298 -0
  95. mindroot/coreplugins/l8n/test_l8n.py +95 -0
  96. mindroot/coreplugins/l8n/test_l8n_standalone.py +251 -0
  97. mindroot/coreplugins/l8n/test_middleware.py +272 -0
  98. mindroot/coreplugins/l8n/utils.py +232 -0
  99. mindroot/coreplugins/mcp_/__init__.py +14 -0
  100. mindroot/coreplugins/mcp_/catalog_commands.py +328 -0
  101. mindroot/coreplugins/mcp_/catalog_manager.py +263 -0
  102. mindroot/coreplugins/mcp_/dynamic_commands.py +154 -0
  103. mindroot/coreplugins/mcp_/mcp_manager.py +1031 -0
  104. mindroot/coreplugins/mcp_/mod.py +367 -0
  105. mindroot/coreplugins/mcp_/oauth_storage.py +144 -0
  106. mindroot/coreplugins/mcp_/server_installer.py +79 -0
  107. mindroot/coreplugins/mcp_/setup.py +26 -0
  108. mindroot/coreplugins/mcp_/test_dynamic_commands.py +134 -0
  109. mindroot/coreplugins/mcp_/testmcpclient.py +92 -0
  110. mindroot/coreplugins/persona/mod.py +12 -7
  111. mindroot/coreplugins/signup/templates/signup.jinja2 +1 -1
  112. mindroot/coreplugins/subscriptions/__init__.py +1 -0
  113. mindroot/coreplugins/subscriptions/mod.py +14 -3
  114. mindroot/coreplugins/subscriptions/router.py +3 -0
  115. mindroot/coreplugins/user_service/__init__.py +1 -2
  116. mindroot/coreplugins/user_service/admin_init.py +1 -0
  117. mindroot/coreplugins/user_service/email_service.py +72 -17
  118. mindroot/coreplugins/user_service/mod.py +10 -2
  119. mindroot/coreplugins/user_service/router.py +2 -0
  120. mindroot/lib/auth/api_key.py +28 -0
  121. mindroot/lib/cli/plugins.py +94 -0
  122. mindroot/lib/plugins/default_plugin_manifest.json +20 -0
  123. mindroot/lib/plugins/installation.py +5 -5
  124. mindroot/lib/plugins/l8n_static_handler.py +225 -0
  125. mindroot/lib/plugins/loader.py +33 -3
  126. mindroot/lib/plugins/loader_with_l8n.py +281 -0
  127. mindroot/lib/plugins/manifest.py +236 -24
  128. mindroot/lib/providers/commands.py +3 -1
  129. mindroot/lib/route_decorators.py +5 -5
  130. mindroot/lib/templates.py +183 -11
  131. mindroot/lib/utils/merge_arrays.py +1 -1
  132. mindroot/migrate.py +39 -20
  133. mindroot/registry/data_access.py +1 -1
  134. mindroot/server.py +42 -13
  135. mindroot/server_missing_normal_args.py +197 -0
  136. mindroot/server_prev.py +173 -0
  137. {mindroot-9.3.0.dist-info → mindroot-9.6.0.dist-info}/METADATA +7 -2
  138. {mindroot-9.3.0.dist-info → mindroot-9.6.0.dist-info}/RECORD +143 -113
  139. mindroot/coreplugins/admin/plugin_manager_backup.py +0 -615
  140. mindroot/coreplugins/admin/static/favicon/about.txt +0 -6
  141. mindroot/coreplugins/admin/static/favicon/android-chrome-512x512.png +0 -0
  142. mindroot/coreplugins/admin/static/favicon/apple-touch-icon.png +0 -0
  143. mindroot/coreplugins/admin/static/favicon/favicon-16x16.png +0 -0
  144. mindroot/coreplugins/admin/static/favicon/favicon-32x32.png +0 -0
  145. mindroot/coreplugins/admin/static/favicon/favicon.ico +0 -0
  146. mindroot/coreplugins/admin/static/favicon/favicon_io (1)/about.txt +0 -6
  147. mindroot/coreplugins/admin/static/favicon/favicon_io (1)/android-chrome-192x192.png +0 -0
  148. mindroot/coreplugins/admin/static/favicon/favicon_io (1)/android-chrome-512x512.png +0 -0
  149. mindroot/coreplugins/admin/static/favicon/favicon_io (1)/apple-touch-icon.png +0 -0
  150. mindroot/coreplugins/admin/static/favicon/favicon_io (1)/favicon-16x16.png +0 -0
  151. mindroot/coreplugins/admin/static/favicon/favicon_io (1)/favicon-32x32.png +0 -0
  152. mindroot/coreplugins/admin/static/favicon/favicon_io (1)/favicon.ico +0 -0
  153. mindroot/coreplugins/admin/static/favicon/favicon_io (1)/site.webmanifest +0 -1
  154. mindroot/coreplugins/admin/static/favicon/logo.png +0 -0
  155. mindroot/coreplugins/admin/static/favicon/site.webmanifest +0 -1
  156. mindroot/coreplugins/admin/static/js/backup/agent-editor.js +0 -186
  157. mindroot/coreplugins/admin/static/js/backup/agent-form.js +0 -1133
  158. mindroot/coreplugins/admin/static/js/backup/agent-list.js +0 -94
  159. mindroot/coreplugins/chat/static/favicon/about.txt +0 -6
  160. mindroot/coreplugins/chat/static/favicon/android-chrome-192x192.png +0 -0
  161. mindroot/coreplugins/chat/static/favicon/android-chrome-512x512.png +0 -0
  162. mindroot/coreplugins/chat/static/favicon/apple-touch-icon.png +0 -0
  163. mindroot/coreplugins/chat/static/favicon/favicon-16x16.png +0 -0
  164. mindroot/coreplugins/chat/static/favicon/favicon-32x32.png +0 -0
  165. mindroot/coreplugins/chat/static/favicon/favicon.ico +0 -0
  166. mindroot/coreplugins/chat/static/favicon/favicon_io (1)/about.txt +0 -6
  167. mindroot/coreplugins/chat/static/favicon/favicon_io (1)/android-chrome-192x192.png +0 -0
  168. mindroot/coreplugins/chat/static/favicon/favicon_io (1)/android-chrome-512x512.png +0 -0
  169. mindroot/coreplugins/chat/static/favicon/favicon_io (1)/apple-touch-icon.png +0 -0
  170. mindroot/coreplugins/chat/static/favicon/favicon_io (1)/favicon-16x16.png +0 -0
  171. mindroot/coreplugins/chat/static/favicon/favicon_io (1)/favicon-32x32.png +0 -0
  172. mindroot/coreplugins/chat/static/favicon/favicon_io (1)/favicon.ico +0 -0
  173. mindroot/coreplugins/chat/static/favicon/favicon_io (1)/site.webmanifest +0 -1
  174. mindroot/coreplugins/chat/static/favicon/logo.png +0 -0
  175. mindroot/coreplugins/chat/static/favicon/site.webmanifest +0 -1
  176. mindroot/coreplugins/index/default.json +0 -76
  177. mindroot/coreplugins/user_service/file_trigger_service.py +0 -12
  178. mindroot/coreplugins/user_service/hooks.py +0 -23
  179. /mindroot/coreplugins/{admin/static/favicon/android-chrome-192x192.png → home/static/imgs/backuplogo.png} +0 -0
  180. {mindroot-9.3.0.dist-info → mindroot-9.6.0.dist-info}/WHEEL +0 -0
  181. {mindroot-9.3.0.dist-info → mindroot-9.6.0.dist-info}/entry_points.txt +0 -0
  182. {mindroot-9.3.0.dist-info → mindroot-9.6.0.dist-info}/licenses/LICENSE +0 -0
  183. {mindroot-9.3.0.dist-info → mindroot-9.6.0.dist-info}/top_level.txt +0 -0
@@ -0,0 +1,85 @@
1
+ /**
2
+ * Registry Simple Sections
3
+ *
4
+ * Handles the Stats and Settings sections for the registry manager.
5
+ * These are simpler sections with less complex logic.
6
+ */
7
+
8
+ import { html } from '/admin/static/js/lit-core.min.js';
9
+
10
+ class RegistrySimpleSections {
11
+ constructor(sharedState, mainComponent) {
12
+ this.state = sharedState;
13
+ this.main = mainComponent;
14
+ this.services = null; // Will be set by main component
15
+ }
16
+
17
+ setServices(services) {
18
+ this.services = services;
19
+ }
20
+
21
+ // === Event Handlers ===
22
+
23
+ async updateRegistryUrl() {
24
+ const newUrl = this.main.shadowRoot.querySelector('input[type="url"]').value;
25
+ await this.services.updateRegistryUrl(newUrl);
26
+ }
27
+
28
+ async testConnection() {
29
+ await this.services.testConnection();
30
+ }
31
+
32
+ // === Render Methods ===
33
+
34
+ renderStats() {
35
+ return html`
36
+ <div class="section">
37
+ <h3>Registry Statistics</h3>
38
+ <div class="stats-grid">
39
+ <div class="stat-card">
40
+ <div class="stat-number">${this.main.stats.total_plugins || 0}</div>
41
+ <div class="stat-label">Plugins</div>
42
+ </div>
43
+ <div class="stat-card">
44
+ <div class="stat-number">${this.main.stats.total_agents || 0}</div>
45
+ <div class="stat-label">Agents</div>
46
+ </div>
47
+ <div class="stat-card">
48
+ <div class="stat-number">${this.main.stats.total_users || 0}</div>
49
+ <div class="stat-label">Users</div>
50
+ </div>
51
+ <div class="stat-card">
52
+ <div class="stat-number">${this.main.stats.total_installs || 0}</div>
53
+ <div class="stat-label">Installs</div>
54
+ </div>
55
+ </div>
56
+ </div>
57
+ `;
58
+ }
59
+
60
+ renderSettings() {
61
+ return html`
62
+ <div class="section">
63
+ <h3>Registry Settings</h3>
64
+ <div class="registry-url-display">
65
+ Current registry: ${this.state.registryUrl}
66
+ </div>
67
+ <div class="form-row">
68
+ <label>Registry URL:</label>
69
+ <input type="url"
70
+ placeholder="https://registry.mindroot.io"
71
+ .value=${this.state.registryUrl}
72
+ @input=${(e) => this.state.registryUrl = e.target.value}>
73
+ <button @click=${() => this.updateRegistryUrl()}>Update</button>
74
+ <button @click=${() => this.testConnection()}>Test Connection</button>
75
+ </div>
76
+ ${this.main.error ? html`<div class="error">${this.main.error}</div>` : ''}
77
+ <div class="help-text">
78
+ Configure the MindRoot Registry URL. Default is https://registry.mindroot.io
79
+ </div>
80
+ </div>
81
+ `;
82
+ }
83
+ }
84
+
85
+ export { RegistrySimpleSections };
@@ -0,0 +1,438 @@
1
+ import { LitElement, html, css } from './lit-core.min.js';
2
+ import { BaseEl } from './base.js';
3
+ import showNotification from './notification.js';
4
+
5
+ class SecureWidgetManager extends BaseEl {
6
+ static properties = {
7
+ agents: { type: Array },
8
+ apiKeys: { type: Array },
9
+ widgets: { type: Array },
10
+ selectedAgent: { type: String },
11
+ selectedApiKey: { type: String },
12
+ domainName: { type: String },
13
+ description: { type: String },
14
+ loading: { type: Boolean },
15
+ showCreateForm: { type: Boolean }
16
+ };
17
+
18
+ static styles = css`
19
+ :host {
20
+ display: block;
21
+ width: 100%;
22
+ height: 100%;
23
+ }
24
+
25
+ .secure-widget-manager {
26
+ display: flex;
27
+ flex-direction: column;
28
+ width: 100%;
29
+ max-width: 1200px;
30
+ margin: 0 auto;
31
+ gap: 20px;
32
+ }
33
+
34
+ .section {
35
+ background: rgb(10, 10, 25);
36
+ border-radius: 8px;
37
+ padding: 1rem;
38
+ border: 1px solid rgba(255, 255, 255, 0.1);
39
+ }
40
+
41
+ .section h3 {
42
+ margin: 0 0 1rem 0;
43
+ color: #f0f0f0;
44
+ display: flex;
45
+ align-items: center;
46
+ gap: 0.5rem;
47
+ }
48
+
49
+ .form-group {
50
+ margin-bottom: 15px;
51
+ }
52
+
53
+ .form-group label {
54
+ display: block;
55
+ margin-bottom: 5px;
56
+ color: #f0f0f0;
57
+ font-weight: 500;
58
+ }
59
+
60
+ input[type="text"],
61
+ textarea,
62
+ select {
63
+ width: 100%;
64
+ padding: 8px 12px;
65
+ background: rgba(255, 255, 255, 0.05);
66
+ border: 1px solid rgba(255, 255, 255, 0.1);
67
+ border-radius: 6px;
68
+ color: #f0f0f0;
69
+ font-size: 0.95rem;
70
+ box-sizing: border-box;
71
+ }
72
+
73
+ textarea {
74
+ resize: vertical;
75
+ min-height: 60px;
76
+ }
77
+
78
+ button {
79
+ background: #2196F3;
80
+ color: #fff;
81
+ border: none;
82
+ padding: 0.75rem 1.5rem;
83
+ border-radius: 4px;
84
+ cursor: pointer;
85
+ transition: background 0.2s;
86
+ margin-right: 10px;
87
+ font-size: 0.9rem;
88
+ }
89
+
90
+ button:hover {
91
+ background: #1976D2;
92
+ }
93
+
94
+ button.secondary {
95
+ background: #2a2a40;
96
+ border: 1px solid rgba(255, 255, 255, 0.1);
97
+ }
98
+
99
+ button.secondary:hover {
100
+ background: #3a3a50;
101
+ }
102
+
103
+ button.danger {
104
+ background: #f44336;
105
+ }
106
+
107
+ button.danger:hover {
108
+ background: #d32f2f;
109
+ }
110
+
111
+ button:disabled {
112
+ opacity: 0.5;
113
+ cursor: not-allowed;
114
+ }
115
+
116
+ .button-group {
117
+ display: flex;
118
+ gap: 10px;
119
+ margin-top: 15px;
120
+ flex-wrap: wrap;
121
+ }
122
+
123
+ .widget-list {
124
+ width: 100%;
125
+ border-collapse: collapse;
126
+ margin-top: 1rem;
127
+ }
128
+
129
+ .widget-list th,
130
+ .widget-list td {
131
+ padding: 0.75rem;
132
+ text-align: left;
133
+ border-bottom: 1px solid rgba(255, 255, 255, 0.1);
134
+ color: #f0f0f0;
135
+ }
136
+
137
+ .widget-list th {
138
+ background: rgba(0, 0, 0, 0.2);
139
+ font-weight: 500;
140
+ }
141
+
142
+ .token-display {
143
+ font-family: monospace;
144
+ background: rgba(0, 0, 0, 0.2);
145
+ padding: 0.25rem 0.5rem;
146
+ border-radius: 4px;
147
+ font-size: 0.8rem;
148
+ }
149
+
150
+ .loading {
151
+ opacity: 0.6;
152
+ pointer-events: none;
153
+ }
154
+
155
+ .create-form {
156
+ border: 2px solid #2196F3;
157
+ border-radius: 8px;
158
+ padding: 1.5rem;
159
+ margin-bottom: 1rem;
160
+ }
161
+
162
+ .no-widgets {
163
+ text-align: center;
164
+ color: #888;
165
+ padding: 2rem;
166
+ font-style: italic;
167
+ }
168
+ `;
169
+
170
+ constructor() {
171
+ super();
172
+ this.agents = [];
173
+ this.apiKeys = [];
174
+ this.widgets = [];
175
+ this.selectedAgent = '';
176
+ this.selectedApiKey = '';
177
+ this.domainName = window.location.origin;
178
+ this.description = '';
179
+ this.loading = false;
180
+ this.showCreateForm = false;
181
+
182
+ this.fetchInitialData();
183
+ }
184
+
185
+ async fetchInitialData() {
186
+ this.loading = true;
187
+ await Promise.all([
188
+ this.fetchAgents(),
189
+ this.fetchApiKeys(),
190
+ this.fetchWidgets()
191
+ ]);
192
+ this.loading = false;
193
+ }
194
+
195
+ async fetchAgents() {
196
+ try {
197
+ const response = await fetch('/agents/local');
198
+ if (!response.ok) throw new Error('Failed to fetch agents');
199
+ this.agents = await response.json();
200
+ } catch (error) {
201
+ showNotification('error', `Error loading agents: ${error.message}`);
202
+ }
203
+ }
204
+
205
+ async fetchApiKeys() {
206
+ try {
207
+ const response = await fetch('/api_keys/list');
208
+ if (!response.ok) throw new Error('Failed to fetch API keys');
209
+ const result = await response.json();
210
+ this.apiKeys = result.data || [];
211
+ } catch (error) {
212
+ showNotification('error', `Error loading API keys: ${error.message}`);
213
+ }
214
+ }
215
+
216
+ async fetchWidgets() {
217
+ try {
218
+ const response = await fetch('/widgets/list');
219
+ if (!response.ok) throw new Error('Failed to fetch widgets');
220
+ const result = await response.json();
221
+ this.widgets = result.data || [];
222
+ } catch (error) {
223
+ showNotification('error', `Error loading widgets: ${error.message}`);
224
+ }
225
+ }
226
+
227
+ handleInputChange(event) {
228
+ const { name, value } = event.target;
229
+ this[name] = value;
230
+ }
231
+
232
+ toggleCreateForm() {
233
+ this.showCreateForm = !this.showCreateForm;
234
+ if (!this.showCreateForm) {
235
+ this.selectedAgent = '';
236
+ this.selectedApiKey = '';
237
+ this.description = '';
238
+ }
239
+ }
240
+
241
+ async handleCreateWidget() {
242
+ if (!this.selectedAgent || !this.selectedApiKey) {
243
+ showNotification('error', 'Please select both an agent and API key');
244
+ return;
245
+ }
246
+
247
+ this.loading = true;
248
+ try {
249
+ const response = await fetch('/widgets/create', {
250
+ method: 'POST',
251
+ headers: {
252
+ 'Content-Type': 'application/json',
253
+ },
254
+ body: JSON.stringify({
255
+ api_key: this.selectedApiKey,
256
+ agent_name: this.selectedAgent,
257
+ base_url: this.domainName,
258
+ description: this.description
259
+ })
260
+ });
261
+
262
+ const result = await response.json();
263
+ if (result.success) {
264
+ showNotification('success', 'Widget token created successfully!');
265
+ await this.fetchWidgets();
266
+ this.toggleCreateForm();
267
+ } else {
268
+ throw new Error(result.message || 'Failed to create widget token');
269
+ }
270
+ } catch (error) {
271
+ showNotification('error', `Error creating widget: ${error.message}`);
272
+ } finally {
273
+ this.loading = false;
274
+ }
275
+ }
276
+
277
+ async handleDeleteWidget(token) {
278
+ if (!confirm('Are you sure you want to delete this widget token?')) {
279
+ return;
280
+ }
281
+
282
+ this.loading = true;
283
+ try {
284
+ const response = await fetch(`/widgets/delete/${token}`, {
285
+ method: 'DELETE'
286
+ });
287
+
288
+ const result = await response.json();
289
+ if (result.success) {
290
+ showNotification('success', 'Widget token deleted successfully');
291
+ await this.fetchWidgets();
292
+ } else {
293
+ throw new Error(result.message || 'Failed to delete widget token');
294
+ }
295
+ } catch (error) {
296
+ showNotification('error', `Error deleting widget: ${error.message}`);
297
+ } finally {
298
+ this.loading = false;
299
+ }
300
+ }
301
+
302
+ copyEmbedCode(token) {
303
+ const embedCode = `<script src="${this.domainName}/chat/embed/${token}"></script>`;
304
+ navigator.clipboard.writeText(embedCode).then(() => {
305
+ showNotification('success', 'Embed code copied to clipboard!');
306
+ }).catch(() => {
307
+ showNotification('error', 'Failed to copy embed code');
308
+ });
309
+ }
310
+
311
+ _render() {
312
+ return html`
313
+ <div class="secure-widget-manager ${this.loading ? 'loading' : ''}">
314
+ <div class="section">
315
+ <h3>
316
+ <span class="material-icons">security</span>
317
+ Secure Chat Widget Manager
318
+ </h3>
319
+ <p>Create secure widget tokens for embedding chat on external websites. API keys are never exposed to the frontend.</p>
320
+
321
+ <div class="button-group">
322
+ <button @click=${this.toggleCreateForm}>
323
+ ${this.showCreateForm ? 'Cancel' : 'Create New Widget Token'}
324
+ </button>
325
+ <button class="secondary" @click=${this.fetchWidgets}>
326
+ Refresh List
327
+ </button>
328
+ </div>
329
+ </div>
330
+
331
+ ${this.showCreateForm ? this.renderCreateForm() : ''}
332
+ ${this.renderWidgetList()}
333
+ </div>
334
+ `;
335
+ }
336
+
337
+ renderCreateForm() {
338
+ return html`
339
+ <div class="section create-form">
340
+ <h3>
341
+ <span class="material-icons">add</span>
342
+ Create Widget Token
343
+ </h3>
344
+
345
+ <div class="form-group">
346
+ <label>Select Agent:</label>
347
+ <select name="selectedAgent" @change=${this.handleInputChange} .value=${this.selectedAgent}>
348
+ <option value="">Choose an agent...</option>
349
+ ${this.agents.map(agent => html`<option value="${agent.name}">${agent.name}</option>`)}
350
+ </select>
351
+ </div>
352
+
353
+ <div class="form-group">
354
+ <label>Select API Key:</label>
355
+ <select name="selectedApiKey" @change=${this.handleInputChange} .value=${this.selectedApiKey}>
356
+ <option value="">Choose an API key...</option>
357
+ ${this.apiKeys.map(key => html`
358
+ <option value="${key.key}">
359
+ ${key.description || key.key.substring(0, 8) + '...'}
360
+ </option>
361
+ `)}
362
+ </select>
363
+ </div>
364
+
365
+ <div class="form-group">
366
+ <label>Domain Name:</label>
367
+ <input type="text" name="domainName" .value=${this.domainName} @input=${this.handleInputChange}
368
+ placeholder="https://your-domain.com">
369
+ </div>
370
+
371
+ <div class="form-group">
372
+ <label>Description (Optional):</label>
373
+ <textarea name="description" .value=${this.description} @input=${this.handleInputChange}
374
+ placeholder="e.g., Widget for company website"></textarea>
375
+ </div>
376
+
377
+ <div class="button-group">
378
+ <button @click=${this.handleCreateWidget} ?disabled=${!this.selectedAgent || !this.selectedApiKey}>
379
+ Create Widget Token
380
+ </button>
381
+ <button class="secondary" @click=${this.toggleCreateForm}>
382
+ Cancel
383
+ </button>
384
+ </div>
385
+ </div>
386
+ `;
387
+ }
388
+
389
+ renderWidgetList() {
390
+ return html`
391
+ <div class="section">
392
+ <h3>
393
+ <span class="material-icons">widgets</span>
394
+ Your Widget Tokens
395
+ </h3>
396
+
397
+ ${this.widgets.length === 0 ? html`
398
+ <div class="no-widgets">
399
+ <p>No widget tokens created yet.</p>
400
+ <p>Create your first widget token to get started with secure chat embedding.</p>
401
+ </div>
402
+ ` : html`
403
+ <table class="widget-list">
404
+ <thead>
405
+ <tr>
406
+ <th>Token</th>
407
+ <th>Agent</th>
408
+ <th>Description</th>
409
+ <th>Created</th>
410
+ <th>Actions</th>
411
+ </tr>
412
+ </thead>
413
+ <tbody>
414
+ ${this.widgets.map(widget => html`
415
+ <tr>
416
+ <td><span class="token-display">${widget.token}</span></td>
417
+ <td>${widget.agent_name}</td>
418
+ <td>${widget.description || 'No description'}</td>
419
+ <td>${new Date(widget.created_at).toLocaleDateString()}</td>
420
+ <td>
421
+ <button class="secondary" @click=${() => this.copyEmbedCode(widget.token)}>
422
+ Copy Embed Code
423
+ </button>
424
+ <button class="danger" @click=${() => this.handleDeleteWidget(widget.token)}>
425
+ Delete
426
+ </button>
427
+ </td>
428
+ </tr>
429
+ `)}
430
+ </tbody>
431
+ </table>
432
+ `}
433
+ </div>
434
+ `;
435
+ }
436
+ }
437
+
438
+ customElements.define('secure-widget-manager', SecureWidgetManager);
Binary file