mindroot 7.7.0__py3-none-any.whl → 8.1.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.

Potentially problematic release.


This version of mindroot might be problematic. Click here for more details.

@@ -0,0 +1,380 @@
1
+ import { LitElement, html, css } from '/admin/static/js/lit-core.min.js';
2
+ import { BaseEl } from '/admin/static/js/base.js';
3
+
4
+ class EnvManager extends BaseEl {
5
+ static properties = {
6
+ pluginData: { type: Object },
7
+ loading: { type: Boolean },
8
+ editingVar: { type: String },
9
+ newVarName: { type: String },
10
+ newVarValue: { type: String },
11
+ showAddForm: { type: Boolean },
12
+ searchTerm: { type: String }
13
+ };
14
+
15
+ constructor() {
16
+ super();
17
+ this.pluginData = null;
18
+ this.loading = true;
19
+ this.editingVar = null;
20
+ this.newVarName = '';
21
+ this.newVarValue = '';
22
+ this.showAddForm = false;
23
+ this.searchTerm = '';
24
+ }
25
+
26
+ connectedCallback() {
27
+ super.connectedCallback();
28
+ this.fetchEnvVars();
29
+ }
30
+
31
+ async fetchEnvVars() {
32
+ this.loading = true;
33
+ try {
34
+ const response = await fetch('/env_vars/scan');
35
+ const result = await response.json();
36
+ if (result.success) {
37
+ this.pluginData = result.data;
38
+ } else {
39
+ console.error('Error fetching environment variables:', result.error);
40
+ }
41
+ } catch (error) {
42
+ console.error('Error fetching environment variables:', error);
43
+ } finally {
44
+ this.loading = false;
45
+ }
46
+ }
47
+
48
+ async updateEnvVar(varName, varValue) {
49
+ try {
50
+ const response = await fetch('/env_vars/update', {
51
+ method: 'POST',
52
+ headers: {
53
+ 'Content-Type': 'application/json',
54
+ },
55
+ body: JSON.stringify({
56
+ var_name: varName,
57
+ var_value: varValue
58
+ })
59
+ });
60
+
61
+ const result = await response.json();
62
+ if (result.success) {
63
+ // Refresh the data
64
+ await this.fetchEnvVars();
65
+ return true;
66
+ } else {
67
+ console.error('Error updating environment variable:', result.message);
68
+ return false;
69
+ }
70
+ } catch (error) {
71
+ console.error('Error updating environment variable:', error);
72
+ return false;
73
+ }
74
+ }
75
+
76
+ handleEditClick(varName) {
77
+ this.editingVar = varName;
78
+ }
79
+
80
+ async handleSaveEdit(varName) {
81
+ const inputEl = this.shadowRoot.querySelector(`#edit-${varName}`);
82
+ if (inputEl) {
83
+ const newValue = inputEl.value;
84
+ const success = await this.updateEnvVar(varName, newValue);
85
+ if (success) {
86
+ this.editingVar = null;
87
+ }
88
+ }
89
+ }
90
+
91
+ handleCancelEdit() {
92
+ this.editingVar = null;
93
+ }
94
+
95
+ toggleAddForm() {
96
+ this.showAddForm = !this.showAddForm;
97
+ if (!this.showAddForm) {
98
+ this.newVarName = '';
99
+ this.newVarValue = '';
100
+ }
101
+ }
102
+
103
+ async handleAddVar() {
104
+ if (this.newVarName && this.newVarValue) {
105
+ const success = await this.updateEnvVar(this.newVarName, this.newVarValue);
106
+ if (success) {
107
+ this.newVarName = '';
108
+ this.newVarValue = '';
109
+ this.showAddForm = false;
110
+ }
111
+ }
112
+ }
113
+
114
+ handleSearchInput(e) {
115
+ this.searchTerm = e.target.value;
116
+ }
117
+
118
+ renderEnvironmentVars() {
119
+ if (!this.pluginData || !this.pluginData.current_env) {
120
+ return html`<div class="empty-state">No environment variables found</div>`;
121
+ }
122
+
123
+ const currentEnv = this.pluginData.current_env;
124
+
125
+ // Create a mapping of variable names to the plugins that reference them
126
+ const varsByPlugin = {};
127
+ const pluginsByVar = {};
128
+
129
+ for (const [pluginName, pluginInfo] of Object.entries(this.pluginData)) {
130
+ if (pluginName === 'current_env') continue;
131
+
132
+ for (const varName of pluginInfo.env_vars) {
133
+ if (!varsByPlugin[pluginName]) {
134
+ varsByPlugin[pluginName] = [];
135
+ }
136
+ varsByPlugin[pluginName].push(varName);
137
+
138
+ if (!pluginsByVar[varName]) {
139
+ pluginsByVar[varName] = [];
140
+ }
141
+ pluginsByVar[varName].push(pluginName);
142
+ }
143
+ }
144
+
145
+ // Group variables by plugin
146
+ const groupedByPlugin = {};
147
+ const multiPluginVars = [];
148
+
149
+ // First, identify variables referenced by multiple plugins
150
+ for (const [varName, plugins] of Object.entries(pluginsByVar)) {
151
+ if (plugins.length > 1) {
152
+ multiPluginVars.push({
153
+ varName,
154
+ varValue: currentEnv[varName],
155
+ plugins
156
+ });
157
+ } else {
158
+ // Single plugin variables
159
+ const plugin = plugins[0];
160
+ if (!groupedByPlugin[plugin]) {
161
+ groupedByPlugin[plugin] = [];
162
+ }
163
+ groupedByPlugin[plugin].push({
164
+ varName,
165
+ varValue: currentEnv[varName]
166
+ });
167
+ }
168
+ }
169
+
170
+ // Sort plugins alphabetically
171
+ const sortedPlugins = Object.keys(groupedByPlugin).sort();
172
+
173
+ // Sort multi-plugin variables by name
174
+ multiPluginVars.sort((a, b) => a.varName.localeCompare(b.varName));
175
+
176
+ // Apply search filter if needed
177
+ let filteredPlugins = sortedPlugins;
178
+ let filteredMultiVars = multiPluginVars;
179
+
180
+ if (this.searchTerm) {
181
+ const searchTerm = this.searchTerm.toLowerCase();
182
+
183
+ // Filter plugins and their variables
184
+ filteredPlugins = sortedPlugins.filter(plugin => {
185
+ // Check if plugin name matches
186
+ if (plugin.toLowerCase().includes(searchTerm)) return true;
187
+
188
+ // Check if any variable name matches
189
+ return groupedByPlugin[plugin].some(v =>
190
+ v.varName.toLowerCase().includes(searchTerm) ||
191
+ (v.varValue && v.varValue.toLowerCase().includes(searchTerm))
192
+ );
193
+ });
194
+
195
+ // For each plugin, filter its variables
196
+ for (const plugin of filteredPlugins) {
197
+ groupedByPlugin[plugin] = groupedByPlugin[plugin].filter(v =>
198
+ v.varName.toLowerCase().includes(searchTerm) ||
199
+ plugin.toLowerCase().includes(searchTerm) ||
200
+ (v.varValue && v.varValue.toLowerCase().includes(searchTerm))
201
+ );
202
+ }
203
+
204
+ // Filter multi-plugin variables
205
+ filteredMultiVars = multiPluginVars.filter(v =>
206
+ v.varName.toLowerCase().includes(searchTerm) ||
207
+ v.plugins.some(p => p.toLowerCase().includes(searchTerm)) ||
208
+ (v.varValue && v.varValue.toLowerCase().includes(searchTerm))
209
+ );
210
+ }
211
+
212
+ // Check if we have any results after filtering
213
+ const hasResults = filteredPlugins.some(p => groupedByPlugin[p].length > 0) || filteredMultiVars.length > 0;
214
+
215
+ if (!hasResults) {
216
+ return html`<div class="empty-state">No matching environment variables found</div>`;
217
+ }
218
+
219
+ return html`
220
+ <table class="env-table">
221
+ <thead>
222
+ <tr>
223
+ <th>Variable Name</th>
224
+ <th>Value</th>
225
+ <th>Actions</th>
226
+ </tr>
227
+ </thead>
228
+ <tbody>
229
+ ${filteredPlugins.map(plugin => {
230
+ if (groupedByPlugin[plugin].length === 0) return '';
231
+
232
+ return html`
233
+ <tr class="plugin-header">
234
+ <td colspan="3" class="plugin-name">${plugin}</td>
235
+ </tr>
236
+ ${groupedByPlugin[plugin].map(v => {
237
+ const { varName, varValue } = v;
238
+ const isMasked = varValue === '********';
239
+
240
+ return html`
241
+ <tr class="plugin-var">
242
+ <td><span class="var-name" title="${varName}">${varName}</span></td>
243
+ <td>
244
+ ${this.editingVar === varName ?
245
+ html`
246
+ <div class="edit-form">
247
+ <input
248
+ id="edit-${varName}"
249
+ type="text"
250
+ value="${isMasked ? '' : varValue}"
251
+ placeholder="${isMasked ? 'Enter new value' : ''}">
252
+ </div>
253
+ ` :
254
+ html`<span class="var-value ${isMasked ? 'masked' : ''}">${varValue}</span>`
255
+ }
256
+ </td>
257
+ <td>
258
+ <div class="actions">
259
+ ${this.editingVar === varName ?
260
+ html`
261
+ <button class="small primary" @click=${() => this.handleSaveEdit(varName)}>Save</button>
262
+ <button class="small" @click=${this.handleCancelEdit}>Cancel</button>
263
+ ` :
264
+ html`<button class="small" @click=${() => this.handleEditClick(varName)}>Edit</button>`
265
+ }
266
+ </div>
267
+ </td>
268
+ </tr>
269
+ `;
270
+ })}
271
+ `;
272
+ })}
273
+
274
+ ${filteredMultiVars.length > 0 ? html`
275
+ <tr class="plugin-header">
276
+ <td colspan="3" class="plugin-name">Multiple Plugins</td>
277
+ </tr>
278
+ ${filteredMultiVars.map(v => {
279
+ const { varName, varValue, plugins } = v;
280
+ const isMasked = varValue === '********';
281
+
282
+ return html`
283
+ <tr class="plugin-var">
284
+ <td>
285
+ <span class="var-name" title="${varName}">${varName}</span>
286
+ <div class="plugin-refs">
287
+ ${plugins.map(p => html`<span class="plugin-tag">${p}</span>`)}
288
+ </div>
289
+ </td>
290
+ <td>
291
+ ${this.editingVar === varName ?
292
+ html`
293
+ <div class="edit-form">
294
+ <input
295
+ id="edit-${varName}"
296
+ type="text"
297
+ value="${isMasked ? '' : varValue}"
298
+ placeholder="${isMasked ? 'Enter new value' : ''}">
299
+ </div>
300
+ ` :
301
+ html`<span class="var-value ${isMasked ? 'masked' : ''}">${varValue}</span>`
302
+ }
303
+ </td>
304
+ <td>
305
+ <div class="actions">
306
+ ${this.editingVar === varName ?
307
+ html`
308
+ <button class="small primary" @click=${() => this.handleSaveEdit(varName)}>Save</button>
309
+ <button class="small" @click=${this.handleCancelEdit}>Cancel</button>
310
+ ` :
311
+ html`<button class="small" @click=${() => this.handleEditClick(varName)}>Edit</button>`
312
+ }
313
+ </div>
314
+ </td>
315
+ </tr>
316
+ `;
317
+ })}
318
+ ` : ''}
319
+ </tbody>
320
+ </table>
321
+ `;
322
+ }
323
+
324
+ _render() {
325
+ return html`
326
+ <link rel="stylesheet" href="/env_manager/static/css/env-manager.css">
327
+ <div class="env-manager">
328
+ <div class="section">
329
+ <h3>
330
+ Environment Variables
331
+ <div class="controls">
332
+ <input
333
+ type="text"
334
+ class="search-box"
335
+ placeholder="Search..."
336
+ @input=${this.handleSearchInput}
337
+ .value=${this.searchTerm}>
338
+ <button @click=${this.toggleAddForm}>
339
+ ${this.showAddForm ? 'Cancel' : 'Add Variable'}
340
+ </button>
341
+ </div>
342
+ </h3>
343
+
344
+ ${this.loading ?
345
+ html`<div class="loading">Loading environment variables...</div>` :
346
+ html`
347
+ ${this.showAddForm ?
348
+ html`
349
+ <div class="add-form">
350
+ <div class="form-row">
351
+ <input
352
+ type="text"
353
+ placeholder="Variable Name"
354
+ .value=${this.newVarName}
355
+ @input=${e => this.newVarName = e.target.value}>
356
+ </div>
357
+ <div class="form-row">
358
+ <input
359
+ type="text"
360
+ placeholder="Variable Value"
361
+ .value=${this.newVarValue}
362
+ @input=${e => this.newVarValue = e.target.value}>
363
+ </div>
364
+ <div class="form-actions">
365
+ <button class="primary" @click=${this.handleAddVar}>Add Variable</button>
366
+ </div>
367
+ </div>
368
+ ` : ''
369
+ }
370
+
371
+ ${this.renderEnvironmentVars()}
372
+ `
373
+ }
374
+ </div>
375
+ </div>
376
+ `;
377
+ }
378
+ }
379
+
380
+ customElements.define('env-manager', EnvManager);
mindroot/server.py CHANGED
@@ -13,7 +13,11 @@ from termcolor import colored
13
13
  import socket
14
14
  from fastapi.middleware.cors import CORSMiddleware
15
15
  from starlette.middleware.base import BaseHTTPMiddleware
16
+ from dotenv import load_dotenv
16
17
 
18
+ # Load environment variables from .env file at the start
19
+ # Set override=True to make .env variables override existing environment variables
20
+ load_dotenv(override=True)
17
21
 
18
22
  def parse_args():
19
23
  import argparse
@@ -48,10 +52,12 @@ def create_directories():
48
52
  create_directories()
49
53
 
50
54
  import mimetypes
51
- mimetypes.add_type("application/javascript", ".js", True)
55
+ mimetypes.add_type('application/javascript', '.js')
56
+ mimetypes.add_type('text/css', '.css')
52
57
 
53
- app = None
54
58
  templates = None
59
+ app = None
60
+ failed_plugins = []
55
61
 
56
62
  async def setup_app_internal(app_):
57
63
  global app, templates
@@ -84,32 +90,14 @@ class HeaderMiddleware(BaseHTTPMiddleware):
84
90
  async def dispatch(self, request: Request, call_next):
85
91
  # First get the response from other middleware and routes
86
92
  response = await call_next(request)
87
-
88
- if "Content-Security-Policy" in response.headers:
89
- del response.headers["Content-Security-Policy"]
90
-
91
- response.headers['Content-Security-Policy'] = "frame-ancestors *"
92
-
93
- if 'Access-Control-Allow-Origin' in response.headers:
94
- del response.headers['Access-Control-Allow-Origin']
95
- # Additional headers for better cross-origin support
96
- response.headers['Access-Control-Allow-Origin'] = '*' # Or your specific origin
97
-
98
- if 'Access-Control-Allow-Headers' in response.headers:
99
- del response.headers['Access-Control-Allow-Headers']
100
-
101
- response.headers['Access-Control-Allow-Credentials'] = 'true'
102
-
103
- # Remove the X-Frame-Options header if it exists
104
- if 'X-Frame-Options' in response.headers:
105
- del response.headers['X-Frame-Options']
106
-
107
93
 
108
- print(dict(response.headers))
94
+ # Add security headers
95
+ response.headers["X-Content-Type-Options"] = "nosniff"
96
+ response.headers["X-Frame-Options"] = "SAMEORIGIN"
97
+ response.headers["X-XSS-Protection"] = "1; mode=block"
109
98
 
110
99
  return response
111
100
 
112
-
113
101
  def main():
114
102
  global app
115
103
 
@@ -166,4 +154,3 @@ def main():
166
154
 
167
155
  if __name__ == "__main__":
168
156
  main()
169
-
@@ -0,0 +1,15 @@
1
+ Metadata-Version: 2.4
2
+ Name: mindroot
3
+ Version: 8.1.0
4
+ Summary: MindRoot AI Agent Framework
5
+ Requires-Python: >=3.9
6
+ License-File: LICENSE
7
+ Requires-Dist: fastapi
8
+ Requires-Dist: uvicorn
9
+ Requires-Dist: jinja2
10
+ Requires-Dist: python-multipart
11
+ Requires-Dist: aiofiles
12
+ Requires-Dist: termcolor
13
+ Requires-Dist: nanoid
14
+ Requires-Dist: python-dotenv
15
+ Dynamic: license-file
@@ -1,5 +1,5 @@
1
1
  mindroot/__init__.py,sha256=OrFRGt_fdSYjolLXUzjSX2CIn1cOAm6l47ENNAkwmgQ,83
2
- mindroot/server.py,sha256=_qoCVqdnbrVsateaAIPLGAQzfpuBnlrdy3qj_qts8Zs,5231
2
+ mindroot/server.py,sha256=akguygtkh_-EOJas4FfZkNEl0Lzm9URew5Y41xiXo88,4811
3
3
  mindroot/coreplugins/admin/__init__.py,sha256=388n_hMskU0TnZ4xT10US_kFkya-EPBjWcv7AZf_HOk,74
4
4
  mindroot/coreplugins/admin/agent_importer.py,sha256=8hQLO64iKtPA5gv9-mLUfUCcnRp3IH9-sTfgkPsrmqo,6376
5
5
  mindroot/coreplugins/admin/agent_router.py,sha256=mstYUURNRb9MpfNwqMYC7WY3FOQJ-5H0TNNz4mDSjFM,9220
@@ -8,7 +8,7 @@ mindroot/coreplugins/admin/persona_handler.py,sha256=eRYmmOmupLJuiujWN35SS2nwRgo
8
8
  mindroot/coreplugins/admin/persona_router.py,sha256=tyPxBe-pRnntHo_xyazvnwKZxHmvEI5_Fsu0YkZbrXA,6036
9
9
  mindroot/coreplugins/admin/plugin_manager.py,sha256=Veu6LJKD9Q8w0nTO24svh1ODxBk71hmDVG8qR1vfEJM,8537
10
10
  mindroot/coreplugins/admin/plugin_router.py,sha256=EEDIM0MMPhqeej8Lu8cazYgzaXH1sKZLy_6kBOwrUgY,1020
11
- mindroot/coreplugins/admin/router.py,sha256=sm0-XoM4JVcXgyoL_rbecpjL6osQzORlaM30tiNVyXU,1423
11
+ mindroot/coreplugins/admin/router.py,sha256=Wzeri92Rv39YKTYflMZ3E1pnYy959KHWRjS8D4Xgaao,1580
12
12
  mindroot/coreplugins/admin/server_router.py,sha256=ojVZPOomiadyw6rD8LQPaOw_d-hbbZn0u7t0z77Pk_M,4385
13
13
  mindroot/coreplugins/admin/service_models.py,sha256=ccYdLjWlEbbkIq9y9T5TL8NGSO6m1LLiJb9J2wkbenY,3354
14
14
  mindroot/coreplugins/admin/settings_router.py,sha256=s5LWB6BiMXhnxduxwi6bQUVtYs3vrNCrUe0Qm8DOo6s,5451
@@ -907,6 +907,12 @@ mindroot/coreplugins/email/smtp_handler.py,sha256=KP-64SF_foMJ-NVKsZvSiwQc9Akugc
907
907
  mindroot/coreplugins/email/test_batch.py,sha256=gCe_E02K0sCrOWi4meEELx0rckeCRXaFJeJ40o9bhmQ,3788
908
908
  mindroot/coreplugins/email/test_email.py,sha256=SrG6Luts0r9YbDqSsBT8I45gIKZi3s3Q5d_dPNxj1Q0,5328
909
909
  mindroot/coreplugins/email/backup/mod.py,sha256=6vvFGpOzCCfEDYlaJBEixRgNRIfvp-mcD6siCwvtxcI,2118
910
+ mindroot/coreplugins/env_manager/__init__.py,sha256=zcQypdwauAdtsj1Be-QZcPeLU_T3LiYaoWKWmIRKsnY,100
911
+ mindroot/coreplugins/env_manager/mod.py,sha256=_wSNZHhDgdM2oBp3NTLd3O-Eribbm7nBsyztvRj9ZhA,6968
912
+ mindroot/coreplugins/env_manager/router.py,sha256=f0d3BoeuwdUXBVJ4Kco8PURIWue5g_xI-5PGi6_6pF8,1185
913
+ mindroot/coreplugins/env_manager/inject/admin.jinja2,sha256=BLGzp3Osc1aKo5-4rOwM3Gy4-FdoJQh7oYcTMrkaW-s,462
914
+ mindroot/coreplugins/env_manager/static/css/env-manager.css,sha256=Y-538HHrkYtiyX-l15sYUJ6mmspbJVJZniHQKz6sL9g,4288
915
+ mindroot/coreplugins/env_manager/static/js/env-manager.js,sha256=bdg7m3AL_keAcx1l1DBeXosgbTMtYRUUEWGtXTT-bt8,12411
910
916
  mindroot/coreplugins/events/__init__.py,sha256=qw8b_7YoN67q1kEdXYXmQkXycF1NaYb3dMbjP-6FsUs,19
911
917
  mindroot/coreplugins/events/mod.py,sha256=MsSFjiLMLJZ7QhUPpVBWKiyDnCzryquRyr329NoCACI,2
912
918
  mindroot/coreplugins/events/router.py,sha256=a-77306_fQPNHPXP5aYtbpfC0gbqMBNRu04aYOh75L4,3587
@@ -1805,9 +1811,9 @@ mindroot/protocols/services/stream_chat.py,sha256=fMnPfwaB5fdNMBLTEg8BXKAGvrELKH
1805
1811
  mindroot/registry/__init__.py,sha256=40Xy9bmPHsgdIrOzbtBGzf4XMqXVi9P8oZTJhn0r654,151
1806
1812
  mindroot/registry/component_manager.py,sha256=WZFNPg4SNvpqsM5NFiC2DpgmrJQCyR9cNhrCBpp30Qk,995
1807
1813
  mindroot/registry/data_access.py,sha256=NgNMamxIjaKeYxzxnVaQz1Y-Rm0AI51si3788_JHUTM,5316
1808
- mindroot-7.7.0.dist-info/licenses/LICENSE,sha256=8plAmZh8y9ccuuqFFz4kp7G-cO_qsPgAOoHNvabSB4U,1070
1809
- mindroot-7.7.0.dist-info/METADATA,sha256=vRdkPJxrK_JO_X0BQ86va9qic9AmL_JREgaVMd_6F_I,10564
1810
- mindroot-7.7.0.dist-info/WHEEL,sha256=DnLRTWE75wApRYVsjgc6wsVswC54sMSJhAEd4xhDpBk,91
1811
- mindroot-7.7.0.dist-info/entry_points.txt,sha256=0bpyjMccLttx6VcjDp6zfJPN0Kk0rffor6IdIbP0j4c,50
1812
- mindroot-7.7.0.dist-info/top_level.txt,sha256=gwKm7DmNjhdrCJTYCrxa9Szne4lLpCtrEBltfsX-Mm8,9
1813
- mindroot-7.7.0.dist-info/RECORD,,
1814
+ mindroot-8.1.0.dist-info/licenses/LICENSE,sha256=8plAmZh8y9ccuuqFFz4kp7G-cO_qsPgAOoHNvabSB4U,1070
1815
+ mindroot-8.1.0.dist-info/METADATA,sha256=UH2WFiqi8-vyY7bpDOU9JnM1bbqnjz3YKSdUD590vXU,356
1816
+ mindroot-8.1.0.dist-info/WHEEL,sha256=Nw36Djuh_5VDukK0H78QzOX-_FQEo6V37m3nkm96gtU,91
1817
+ mindroot-8.1.0.dist-info/entry_points.txt,sha256=0bpyjMccLttx6VcjDp6zfJPN0Kk0rffor6IdIbP0j4c,50
1818
+ mindroot-8.1.0.dist-info/top_level.txt,sha256=gwKm7DmNjhdrCJTYCrxa9Szne4lLpCtrEBltfsX-Mm8,9
1819
+ mindroot-8.1.0.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (80.4.0)
2
+ Generator: setuptools (80.7.1)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5