mindroot 9.3.0__py3-none-any.whl → 9.5.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.
- mindroot/coreplugins/admin/__init__.py +3 -1
- mindroot/coreplugins/admin/agent_router.py +250 -7
- mindroot/coreplugins/admin/asset_manager.py +164 -0
- mindroot/coreplugins/admin/command_router.py +236 -1
- mindroot/coreplugins/admin/mcp_catalog_routes.py +156 -0
- mindroot/coreplugins/admin/mcp_publish_routes.py +450 -0
- mindroot/coreplugins/admin/mcp_registry_routes.py +495 -0
- mindroot/coreplugins/admin/mcp_routes.py +216 -0
- mindroot/coreplugins/admin/mod.py +62 -0
- mindroot/coreplugins/admin/oauth_callback_router.py +84 -0
- mindroot/coreplugins/admin/persona_handler.py +15 -6
- mindroot/coreplugins/admin/persona_router.py +158 -2
- mindroot/coreplugins/admin/plugin_manager.py +63 -0
- mindroot/coreplugins/admin/plugin_router_fixed.py +23 -0
- mindroot/coreplugins/admin/plugin_router_new_not_working.py +145 -0
- mindroot/coreplugins/admin/plugin_routes.py +114 -0
- mindroot/coreplugins/admin/registry_settings_routes.py +140 -0
- mindroot/coreplugins/admin/router.py +116 -15
- mindroot/coreplugins/admin/service_models.py +1 -1
- mindroot/coreplugins/admin/settings_router.py +1 -0
- mindroot/coreplugins/admin/static/css/admin-custom.css +357 -2
- mindroot/coreplugins/admin/static/css/dark.css +1 -0
- mindroot/coreplugins/admin/static/css/default.css +4 -0
- mindroot/coreplugins/admin/static/js/about-info.js +367 -0
- mindroot/coreplugins/admin/static/js/agent-form.js +83 -3
- mindroot/coreplugins/admin/static/js/api-key-script.js +307 -0
- mindroot/coreplugins/admin/static/js/mcp-manager.js +348 -0
- mindroot/coreplugins/admin/static/js/mcp-publisher.js +780 -0
- mindroot/coreplugins/admin/static/js/persona-editor.js +34 -5
- mindroot/coreplugins/admin/static/js/plugin-toggle.js +1 -1
- mindroot/coreplugins/admin/static/js/recommended-plugin-install.js +63 -0
- mindroot/coreplugins/admin/static/js/registry-auth-section.js +132 -0
- mindroot/coreplugins/admin/static/js/registry-manager-base.js +613 -0
- mindroot/coreplugins/admin/static/js/registry-manager-old.js +385 -0
- mindroot/coreplugins/admin/static/js/registry-manager-publish-old-delete.js +166 -0
- mindroot/coreplugins/admin/static/js/registry-manager.js +351 -0
- mindroot/coreplugins/admin/static/js/registry-publish-section.js +377 -0
- mindroot/coreplugins/admin/static/js/registry-search-section.js +400 -0
- mindroot/coreplugins/admin/static/js/registry-search-section.js.bak +3 -0
- mindroot/coreplugins/admin/static/js/registry-settings.js +69 -0
- mindroot/coreplugins/admin/static/js/registry-shared-services.js +857 -0
- mindroot/coreplugins/admin/static/js/registry-simple-sections.js +85 -0
- mindroot/coreplugins/admin/static/js/secure-widget-manager.js +438 -0
- mindroot/coreplugins/admin/static/logo.png +0 -0
- mindroot/coreplugins/admin/templates/admin.jinja2 +275 -110
- mindroot/coreplugins/agent/Assistant/agent.json +27 -11
- mindroot/coreplugins/agent/agent.py +2 -2
- mindroot/coreplugins/agent/command_parser.py +25 -10
- mindroot/coreplugins/agent/templates/system.jinja2 +0 -12
- mindroot/coreplugins/chat/__init__.py +4 -1
- mindroot/coreplugins/chat/router.py +132 -20
- mindroot/coreplugins/chat/router_dedup_patch.py +20 -0
- mindroot/coreplugins/chat/services.py +31 -1
- mindroot/coreplugins/chat/static/css/action-fix.css +32 -0
- mindroot/coreplugins/chat/static/css/admin-custom.css +5 -3
- mindroot/coreplugins/chat/static/css/dark.css +24 -3
- mindroot/coreplugins/chat/static/css/default.css +24 -3
- mindroot/coreplugins/chat/static/css/main.css +1 -0
- mindroot/coreplugins/chat/static/js/action.js +137 -60
- mindroot/coreplugins/chat/static/js/chat-history.js +3 -0
- mindroot/coreplugins/chat/static/js/chat.js +59 -16
- mindroot/coreplugins/chat/static/js/chat.js.diff +221 -0
- mindroot/coreplugins/chat/static/js/chatform.js +2 -2
- mindroot/coreplugins/chat/static/site.webmanifest +1 -1
- mindroot/coreplugins/chat/templates/chat.jinja2 +3 -3
- mindroot/coreplugins/chat/widget_manager.py +139 -0
- mindroot/coreplugins/chat/widget_routes.py +287 -0
- mindroot/coreplugins/check_list/inject/admin.jinja2 +1 -1
- mindroot/coreplugins/email/__init__.py +2 -0
- mindroot/coreplugins/email/email_provider.py +2 -2
- mindroot/coreplugins/email/mod.py +100 -0
- mindroot/coreplugins/email/services.py +5 -3
- mindroot/coreplugins/email/smtp_handler.py +9 -3
- mindroot/coreplugins/email/test_email_service.py +75 -0
- mindroot/coreplugins/env_manager/mod.py +61 -25
- mindroot/coreplugins/home/router.py +37 -2
- mindroot/coreplugins/home/static/imgs/logo.png +0 -0
- mindroot/coreplugins/home/static/imgs/logo.png.bak +0 -0
- mindroot/coreplugins/home/static/imgs/logo_teal.png +0 -0
- mindroot/coreplugins/home/static/imgs/logo_teal2.png +0 -0
- mindroot/coreplugins/home/static/imgs/logo_teal_detailed.png +0 -0
- mindroot/coreplugins/home/static/imgs/logo_teal_python.png +0 -0
- mindroot/coreplugins/home/templates/home.jinja2 +15 -6
- mindroot/coreplugins/index/indices/default/index.json +6 -6
- mindroot/coreplugins/jwt_auth/middleware.py +47 -2
- mindroot/coreplugins/jwt_auth/mod.py +40 -17
- mindroot/coreplugins/l8n/__init__.py +6 -0
- mindroot/coreplugins/l8n/debug_loader.py +85 -0
- mindroot/coreplugins/l8n/debug_middleware.py +74 -0
- mindroot/coreplugins/l8n/l8n_constants.py +19 -0
- mindroot/coreplugins/l8n/language_detection.py +183 -0
- mindroot/coreplugins/l8n/middleware.py +151 -0
- mindroot/coreplugins/l8n/mod.py +277 -0
- mindroot/coreplugins/l8n/monkey_patch_to_delete.py +186 -0
- mindroot/coreplugins/l8n/test_enhanced.py +298 -0
- mindroot/coreplugins/l8n/test_l8n.py +95 -0
- mindroot/coreplugins/l8n/test_l8n_standalone.py +251 -0
- mindroot/coreplugins/l8n/test_middleware.py +272 -0
- mindroot/coreplugins/l8n/utils.py +232 -0
- mindroot/coreplugins/mcp_/__init__.py +14 -0
- mindroot/coreplugins/mcp_/catalog_commands.py +328 -0
- mindroot/coreplugins/mcp_/catalog_manager.py +263 -0
- mindroot/coreplugins/mcp_/dynamic_commands.py +154 -0
- mindroot/coreplugins/mcp_/mcp_manager.py +1031 -0
- mindroot/coreplugins/mcp_/mod.py +367 -0
- mindroot/coreplugins/mcp_/oauth_storage.py +144 -0
- mindroot/coreplugins/mcp_/server_installer.py +79 -0
- mindroot/coreplugins/mcp_/setup.py +26 -0
- mindroot/coreplugins/mcp_/test_dynamic_commands.py +134 -0
- mindroot/coreplugins/mcp_/testmcpclient.py +92 -0
- mindroot/coreplugins/persona/mod.py +12 -7
- mindroot/coreplugins/signup/templates/signup.jinja2 +1 -1
- mindroot/coreplugins/subscriptions/__init__.py +1 -0
- mindroot/coreplugins/subscriptions/mod.py +14 -3
- mindroot/coreplugins/subscriptions/router.py +3 -0
- mindroot/coreplugins/user_service/__init__.py +1 -2
- mindroot/coreplugins/user_service/admin_init.py +1 -0
- mindroot/coreplugins/user_service/email_service.py +72 -17
- mindroot/coreplugins/user_service/mod.py +10 -2
- mindroot/coreplugins/user_service/router.py +2 -0
- mindroot/lib/auth/api_key.py +28 -0
- mindroot/lib/cli/plugins.py +94 -0
- mindroot/lib/plugins/default_plugin_manifest.json +20 -0
- mindroot/lib/plugins/installation.py +5 -5
- mindroot/lib/plugins/l8n_static_handler.py +225 -0
- mindroot/lib/plugins/loader.py +33 -3
- mindroot/lib/plugins/loader_with_l8n.py +281 -0
- mindroot/lib/plugins/manifest.py +236 -24
- mindroot/lib/providers/commands.py +3 -1
- mindroot/lib/route_decorators.py +5 -5
- mindroot/lib/templates.py +183 -11
- mindroot/lib/utils/merge_arrays.py +1 -1
- mindroot/migrate.py +39 -20
- mindroot/registry/data_access.py +1 -1
- mindroot/server.py +42 -13
- mindroot/server_missing_normal_args.py +197 -0
- mindroot/server_prev.py +173 -0
- {mindroot-9.3.0.dist-info → mindroot-9.5.0.dist-info}/METADATA +7 -2
- {mindroot-9.3.0.dist-info → mindroot-9.5.0.dist-info}/RECORD +144 -112
- mindroot/coreplugins/admin/static/favicon/about.txt +0 -6
- mindroot/coreplugins/admin/static/favicon/android-chrome-512x512.png +0 -0
- mindroot/coreplugins/admin/static/favicon/apple-touch-icon.png +0 -0
- mindroot/coreplugins/admin/static/favicon/favicon-16x16.png +0 -0
- mindroot/coreplugins/admin/static/favicon/favicon-32x32.png +0 -0
- mindroot/coreplugins/admin/static/favicon/favicon.ico +0 -0
- mindroot/coreplugins/admin/static/favicon/favicon_io (1)/about.txt +0 -6
- mindroot/coreplugins/admin/static/favicon/favicon_io (1)/android-chrome-192x192.png +0 -0
- mindroot/coreplugins/admin/static/favicon/favicon_io (1)/android-chrome-512x512.png +0 -0
- mindroot/coreplugins/admin/static/favicon/favicon_io (1)/apple-touch-icon.png +0 -0
- mindroot/coreplugins/admin/static/favicon/favicon_io (1)/favicon-16x16.png +0 -0
- mindroot/coreplugins/admin/static/favicon/favicon_io (1)/favicon-32x32.png +0 -0
- mindroot/coreplugins/admin/static/favicon/favicon_io (1)/favicon.ico +0 -0
- mindroot/coreplugins/admin/static/favicon/favicon_io (1)/site.webmanifest +0 -1
- mindroot/coreplugins/admin/static/favicon/logo.png +0 -0
- mindroot/coreplugins/admin/static/favicon/site.webmanifest +0 -1
- mindroot/coreplugins/admin/static/js/backup/agent-editor.js +0 -186
- mindroot/coreplugins/admin/static/js/backup/agent-form.js +0 -1133
- mindroot/coreplugins/admin/static/js/backup/agent-list.js +0 -94
- mindroot/coreplugins/chat/static/favicon/about.txt +0 -6
- mindroot/coreplugins/chat/static/favicon/android-chrome-192x192.png +0 -0
- mindroot/coreplugins/chat/static/favicon/android-chrome-512x512.png +0 -0
- mindroot/coreplugins/chat/static/favicon/apple-touch-icon.png +0 -0
- mindroot/coreplugins/chat/static/favicon/favicon-16x16.png +0 -0
- mindroot/coreplugins/chat/static/favicon/favicon-32x32.png +0 -0
- mindroot/coreplugins/chat/static/favicon/favicon.ico +0 -0
- mindroot/coreplugins/chat/static/favicon/favicon_io (1)/about.txt +0 -6
- mindroot/coreplugins/chat/static/favicon/favicon_io (1)/android-chrome-192x192.png +0 -0
- mindroot/coreplugins/chat/static/favicon/favicon_io (1)/android-chrome-512x512.png +0 -0
- mindroot/coreplugins/chat/static/favicon/favicon_io (1)/apple-touch-icon.png +0 -0
- mindroot/coreplugins/chat/static/favicon/favicon_io (1)/favicon-16x16.png +0 -0
- mindroot/coreplugins/chat/static/favicon/favicon_io (1)/favicon-32x32.png +0 -0
- mindroot/coreplugins/chat/static/favicon/favicon_io (1)/favicon.ico +0 -0
- mindroot/coreplugins/chat/static/favicon/favicon_io (1)/site.webmanifest +0 -1
- mindroot/coreplugins/chat/static/favicon/logo.png +0 -0
- mindroot/coreplugins/chat/static/favicon/site.webmanifest +0 -1
- mindroot/coreplugins/index/default.json +0 -76
- mindroot/coreplugins/user_service/file_trigger_service.py +0 -12
- mindroot/coreplugins/user_service/hooks.py +0 -23
- /mindroot/coreplugins/{admin/static/favicon/android-chrome-192x192.png → home/static/imgs/backuplogo.png} +0 -0
- {mindroot-9.3.0.dist-info → mindroot-9.5.0.dist-info}/WHEEL +0 -0
- {mindroot-9.3.0.dist-info → mindroot-9.5.0.dist-info}/entry_points.txt +0 -0
- {mindroot-9.3.0.dist-info → mindroot-9.5.0.dist-info}/licenses/LICENSE +0 -0
- {mindroot-9.3.0.dist-info → mindroot-9.5.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
|