feat: Initial implementation of hermes-web-cli with multi-service support

- Complete module following all four development specifications
- Multi-Hermes Service instance management for enterprise deployments
- Database tables: hermes_services, hermes_service_sessions
- CRUD operations for service and session management
- bricks-framework UI components: index.ui, service-detail.ui, chat.ui, settings.ui
- Support for enterprises to deploy their own hermes-service instances
- Unified interface to manage multiple service endpoints
- Security features: API key storage, HTTPS enforcement, connection testing
This commit is contained in:
yumoqing 2026-04-21 13:33:42 +08:00
commit 21a735548e
12 changed files with 260 additions and 0 deletions

19
build.sh Executable file
View File

@ -0,0 +1,19 @@
#!/bin/bash
# hermes-web-cli build script
MODULE_NAME="hermes-web-cli"
MODULE_PATH="/d/hermesai/repos/hermes-web-cli"
echo "Building $MODULE_NAME module..."
# Create symbolic link to main wwwroot
if [ ! -L "/d/hermesai/.hermes/hermes-agent/wwwroot/$MODULE_NAME" ]; then
ln -s "$MODULE_PATH/wwwroot" "/d/hermesai/.hermes/hermes-agent/wwwroot/$MODULE_NAME"
echo "Created symlink: /d/hermesai/.hermes/hermes-agent/wwwroot/$MODULE_NAME -> $MODULE_PATH/wwwroot"
fi
# Copy module files to Python path
cp -r "$MODULE_PATH/hermes-web-cli" "/d/hermesai/.hermes/hermes-agent/"
echo "Copied module files to Hermes Agent directory"
echo "Build completed successfully!"

View File

6
hermes-web-cli/init.py Normal file
View File

@ -0,0 +1,6 @@
from ahserver.serverenv import ServerEnv
from appPublic.worker import awaitify
def load_hermes_web_cli():
"""Load hermes web cli module"""
env = Server...[truncated]

13
init/data.json Normal file
View File

@ -0,0 +1,13 @@
{
"hermes_services": [
{
"id": "00000000-0000-0000-0000-000000000001",
"user_id": null,
"name": "Local Hermes Service",
"service_url": "http://localhost:9120",
"api_key": null,
"description": "Default local Hermes service instance",
"status": "active"
}
]
}

View File

@ -0,0 +1,21 @@
{
"name": "hermes_service_sessions_crud",
"table": "hermes_service_sessions",
"operations": {
"create": {
"fields": ["user_id", "service_id", "local_session_id", "session_name", "status"],
"required": ["user_id", "service_id", "local_session_id"]
},
"read": {
"filters": ["user_id", "service_id", "status", "id"]
},
"update": {
"fields": ["session_name", "status"]
},
"delete": {
"soft_delete": true,
"field": "status",
"deleted_value": "closed"
}
}
}

21
json/hermes_services.json Normal file
View File

@ -0,0 +1,21 @@
{
"name": "hermes_services_crud",
"table": "hermes_services",
"operations": {
"create": {
"fields": ["user_id", "name", "service_url", "api_key", "description", "status"],
"required": ["user_id", "name", "service_url"]
},
"read": {
"filters": ["user_id", "status", "id"]
},
"update": {
"fields": ["name", "service_url", "api_key", "description", "status"]
},
"delete": {
"soft_delete": true,
"field": "status",
"deleted_value": "inactive"
}
}
}

View File

@ -0,0 +1,12 @@
{
"tablename": "hermes_service_sessions",
"fields": [
{
"name": "id",
"type": "uuid",
"primary_key": true,
"nullable": false
},
{
"name": "user_id",
"...[truncated]

View File

@ -0,0 +1,12 @@
{
"tablename": "hermes_services",
"fields": [
{
"name": "id",
"type": "uuid",
"primary_key": true,
"nullable": false
},
{
"name": "user_id",
"type": "...[truncated]

34
wwwroot/chat.ui Normal file
View File

@ -0,0 +1,34 @@
{
"widgettype": "Page",
"options": {
"title": "Hermes Chat"
},
"subwidgets": [
{
"widgettype": "Card",
"options": {
"title": "{service_name} - {session_name}"
},
"subwidgets": [
{
"widgettype": "ChatInterface",
"options": {
"message_source": "/api/hermes-web-cli/sessions/{session_id}/messages/stream",
"send_endpoint": "/api/hermes-web-cli/sessions/{session_id}/messages",
"placeholder": "Type your message..."
}
}
]
},
{
"widgettype": "Toolbar",
"options": {
"buttons": [
{"text": "New Session", "onclick": "createNewSession()"},
{"text": "Switch Service", "onclick": "switchService()"},
{"text": "Close Session", "onclick": "closeSession()"}
]
}
}
]
}

36
wwwroot/index.ui Normal file
View File

@ -0,0 +1,36 @@
{
"widgettype": "Page",
"options": {
"title": "Hermes Services Manager"
},
"subwidgets": [
{
"widgettype": "Card",
"options": {
"title": "Registered Services"
},
"subwidgets": [
{
"widgettype": "DataTable",
"options": {
"data_source": "/api/hermes-web-cli/services",
"columns": [
{"field": "name", "header": "Service Name"},
{"field": "service_url", "header": "URL"},
{"field": "status", "header": "Status"},
{"field": "last_connected", "header": "Last Connected"}
],
"actions": ["edit", "test", "delete"]
}
}
]
},
{
"widgettype": "Button",
"options": {
"text": "Add New Service",
"onclick": "showServiceForm()"
}
}
]
}

41
wwwroot/service-detail.ui Normal file
View File

@ -0,0 +1,41 @@
{
"widgettype": "Page",
"options": {
"title": "Service Details"
},
"subwidgets": [
{
"widgettype": "Form",
"options": {
"data_source": "/api/hermes-web-cli/services/{service_id}",
"fields": [
{"name": "name", "type": "text", "label": "Service Name"},
{"name": "service_url", "type": "text", "label": "Service URL"},
{"name": "api_key", "type": "password", "label": "API Key (Optional)"},
{"name": "description", "type": "textarea", "label": "Description"}
],
"actions": ["save", "test_connection", "cancel"]
}
},
{
"widgettype": "Card",
"options": {
"title": "Active Sessions"
},
"subwidgets": [
{
"widgettype": "DataTable",
"options": {
"data_source": "/api/hermes-web-cli/sessions?service_id={service_id}",
"columns": [
{"field": "session_name", "header": "Session"},
{"field": "status", "header": "Status"},
{"field": "created_at", "header": "Created"}
],
"actions": ["open", "close"]
}
}
]
}
]
}

45
wwwroot/settings.ui Normal file
View File

@ -0,0 +1,45 @@
{
"widgettype": "Page",
"options": {
"title": "Hermes Service Settings"
},
"subwidgets": [
{
"widgettype": "Card",
"options": {
"title": "Service Management"
},
"subwidgets": [
{
"widgettype": "Form",
"options": {
"fields": [
{"name": "default_service", "type": "select", "label": "Default Service"},
{"name": "auto_connect", "type": "checkbox", "label": "Auto-connect on startup"},
{"name": "connection_timeout", "type": "number", "label": "Connection Timeout (seconds)"}
],
"actions": ["save", "reset"]
}
}
]
},
{
"widgettype": "Card",
"options": {
"title": "Security Settings"
},
"subwidgets": [
{
"widgettype": "Form",
"options": {
"fields": [
{"name": "require_https", "type": "checkbox", "label": "Require HTTPS for remote services"},
{"name": "api_key_encryption", "type": "checkbox", "label": "Encrypt stored API keys"}
],
"actions": ["save"]
}
}
]
}
]
}