add design style
This commit is contained in:
parent
f5c6f6927e
commit
434ac73465
44
build.sh
44
build.sh
@ -1,24 +1,52 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
# harnessed_agent build script
|
# harnessed_agent build script
|
||||||
|
# Follows module-development-spec: processes models/, json/, and wwwroot/
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
echo "Building Hermes Agent module..."
|
|
||||||
|
|
||||||
# Create symbolic links for wwwroot files
|
|
||||||
MODULE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
MODULE_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
|
||||||
MAIN_WWWROOT="$MODULE_DIR/../wwwroot"
|
MODULE_NAME="harnessed_agent"
|
||||||
|
|
||||||
# Ensure main wwwroot exists
|
echo "Building ${MODULE_NAME} module..."
|
||||||
|
|
||||||
|
# Step 1: Generate DDL from model JSON files
|
||||||
|
if [ -d "$MODULE_DIR/models" ] && ls "$MODULE_DIR/models"/*.json 1>/dev/null 2>&1; then
|
||||||
|
echo "Generating DDL from model definitions..."
|
||||||
|
cd "$MODULE_DIR/models"
|
||||||
|
if command -v json2ddl &>/dev/null; then
|
||||||
|
json2ddl mysql . > mysql.ddl.sql
|
||||||
|
echo "Generated mysql.ddl.sql from models/"
|
||||||
|
else
|
||||||
|
echo "Warning: json2ddl not found, skipping DDL generation"
|
||||||
|
fi
|
||||||
|
cd "$MODULE_DIR"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Step 2: Generate CRUD UI from JSON definitions
|
||||||
|
if [ -d "$MODULE_DIR/json" ] && ls "$MODULE_DIR/json"/*.json 1>/dev/null 2>&1; then
|
||||||
|
echo "Generating CRUD UI files from JSON definitions..."
|
||||||
|
cd "$MODULE_DIR/json"
|
||||||
|
if command -v xls2ui &>/dev/null; then
|
||||||
|
for f in *.json; do
|
||||||
|
xls2ui -m ../models -o ../wwwroot "${MODULE_NAME}" "$f" 2>/dev/null || true
|
||||||
|
done
|
||||||
|
echo "Generated CRUD UI files in wwwroot/"
|
||||||
|
else
|
||||||
|
echo "Warning: xls2ui not found, skipping UI generation"
|
||||||
|
fi
|
||||||
|
cd "$MODULE_DIR"
|
||||||
|
fi
|
||||||
|
|
||||||
|
# Step 3: Link wwwroot files to main application wwwroot
|
||||||
|
MAIN_WWWROOT="$MODULE_DIR/../wwwroot"
|
||||||
mkdir -p "$MAIN_WWWROOT"
|
mkdir -p "$MAIN_WWWROOT"
|
||||||
|
|
||||||
# Link module wwwroot files to main application wwwroot
|
|
||||||
for file in "$MODULE_DIR"/wwwroot/*; do
|
for file in "$MODULE_DIR"/wwwroot/*; do
|
||||||
if [ -f "$file" ]; then
|
if [ -f "$file" ]; then
|
||||||
filename=$(basename "$file")
|
filename=$(basename "$file")
|
||||||
ln -sf "$file" "$MAIN_WWWROOT/harnessed_agent_$filename"
|
ln -sf "$file" "$MAIN_WWWROOT/${MODULE_NAME}_${filename}"
|
||||||
echo "Linked $filename to main wwwroot"
|
echo "Linked $filename to main wwwroot"
|
||||||
fi
|
fi
|
||||||
done
|
done
|
||||||
|
|
||||||
echo "Hermes Agent module build completed successfully!"
|
echo "${MODULE_NAME} module build completed successfully!"
|
||||||
|
|||||||
248
crud.json
248
crud.json
@ -1,248 +0,0 @@
|
|||||||
{
|
|
||||||
"hermes_memory_crud": {
|
|
||||||
"summary": "CRUD operations for enhanced memory with intelligent filtering",
|
|
||||||
"create": {
|
|
||||||
"description": "Add new memory entry with intelligent priority classification",
|
|
||||||
"parameters": {
|
|
||||||
"action": {"type": "string", "required": true, "enum": ["add"], "description": "Action must be 'add'"},
|
|
||||||
"target": {"type": "string", "required": true, "enum": ["memory", "user"], "description": "Memory target type"},
|
|
||||||
"content": {"type": "string", "required": true, "description": "Memory content to store"},
|
|
||||||
"priority": {"type": "integer", "required": false, "minimum": 0, "maximum": 100, "description": "Optional priority override (0-100)"}
|
|
||||||
},
|
|
||||||
"function": "hermes_manage_memory"
|
|
||||||
},
|
|
||||||
"read": {
|
|
||||||
"description": "Get intelligent memory context optimized for current task",
|
|
||||||
"parameters": {
|
|
||||||
"current_task": {"type": "string", "required": false, "description": "Current task description for relevance filtering"},
|
|
||||||
"max_tokens": {"type": "integer", "required": false, "description": "Maximum tokens allowed for memory context"}
|
|
||||||
},
|
|
||||||
"function": "hermes_get_intelligent_memory_context"
|
|
||||||
},
|
|
||||||
"update": {
|
|
||||||
"description": "Replace existing memory entry with optional priority override",
|
|
||||||
"parameters": {
|
|
||||||
"action": {"type": "string", "required": true, "enum": ["replace"], "description": "Action must be 'replace'"},
|
|
||||||
"target": {"type": "string", "required": true, "enum": ["memory", "user"], "description": "Memory target type"},
|
|
||||||
"content": {"type": "string", "required": true, "description": "New memory content"},
|
|
||||||
"old_text": {"type": "string", "required": true, "description": "Existing memory content to identify entry"},
|
|
||||||
"priority": {"type": "integer", "required": false, "minimum": 0, "maximum": 100, "description": "Optional priority override (0-100)"}
|
|
||||||
},
|
|
||||||
"function": "hermes_manage_memory"
|
|
||||||
},
|
|
||||||
"delete": {
|
|
||||||
"description": "Remove memory entry by content",
|
|
||||||
"parameters": {
|
|
||||||
"action": {"type": "string", "required": true, "enum": ["remove"], "description": "Action must be 'remove'"},
|
|
||||||
"target": {"type": "string", "required": true, "enum": ["memory", "user"], "description": "Memory target type"},
|
|
||||||
"old_text": {"type": "string", "required": true, "description": "Memory content to identify entry for removal"}
|
|
||||||
},
|
|
||||||
"function": "hermes_manage_memory"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"hermes_skills_crud": {
|
|
||||||
"summary": "CRUD operations for user-isolated skills management",
|
|
||||||
"create": {
|
|
||||||
"description": "Create new skill with user isolation",
|
|
||||||
"parameters": {
|
|
||||||
"action": {"type": "string", "required": true, "enum": ["create"], "description": "Action must be 'create'"},
|
|
||||||
"name": {"type": "string", "required": true, "description": "Skill name"},
|
|
||||||
"content": {"type": "string", "required": true, "description": "Skill content in SKILL.md format"},
|
|
||||||
"description": {"type": "string", "required": false, "description": "Skill description"},
|
|
||||||
"category": {"type": "string", "required": false, "description": "Skill category"},
|
|
||||||
"version": {"type": "string", "required": false, "description": "Skill version"}
|
|
||||||
},
|
|
||||||
"function": "hermes_manage_skills"
|
|
||||||
},
|
|
||||||
"read": {
|
|
||||||
"description": "View existing skill by name",
|
|
||||||
"parameters": {
|
|
||||||
"action": {"type": "string", "required": true, "enum": ["view"], "description": "Action must be 'view'"},
|
|
||||||
"name": {"type": "string", "required": true, "description": "Skill name to view"}
|
|
||||||
},
|
|
||||||
"function": "hermes_manage_skills"
|
|
||||||
},
|
|
||||||
"update": {
|
|
||||||
"description": "Update existing skill with user isolation",
|
|
||||||
"parameters": {
|
|
||||||
"action": {"type": "string", "required": true, "enum": ["update"], "description": "Action must be 'update'"},
|
|
||||||
"name": {"type": "string", "required": true, "description": "Skill name to update"},
|
|
||||||
"content": {"type": "string", "required": false, "description": "Updated skill content"},
|
|
||||||
"description": {"type": "string", "required": false, "description": "Updated skill description"},
|
|
||||||
"category": {"type": "string", "required": false, "description": "Updated skill category"},
|
|
||||||
"version": {"type": "string", "required": false, "description": "Updated skill version"}
|
|
||||||
},
|
|
||||||
"function": "hermes_manage_skills"
|
|
||||||
},
|
|
||||||
"delete": {
|
|
||||||
"description": "Delete skill by name with user isolation",
|
|
||||||
"parameters": {
|
|
||||||
"action": {"type": "string", "required": true, "enum": ["delete"], "description": "Action must be 'delete'"},
|
|
||||||
"name": {"type": "string", "required": true, "description": "Skill name to delete"}
|
|
||||||
},
|
|
||||||
"function": "hermes_manage_skills"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"hermes_sessions_crud": {
|
|
||||||
"summary": "CRUD operations for session search and metadata",
|
|
||||||
"read": {
|
|
||||||
"description": "Search sessions with optional query",
|
|
||||||
"parameters": {
|
|
||||||
"query": {"type": "string", "required": false, "description": "Search query (empty for recent sessions)"},
|
|
||||||
"limit": {"type": "integer", "required": false, "default": 3, "description": "Maximum number of sessions to return"}
|
|
||||||
},
|
|
||||||
"function": "hermes_search_sessions"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"hermes_remote_skills_crud": {
|
|
||||||
"summary": "CRUD operations for SSH remote skills with deployment capabilities",
|
|
||||||
"create": {
|
|
||||||
"description": "Create new remote skill configuration",
|
|
||||||
"parameters": {
|
|
||||||
"action": {"type": "string", "required": true, "enum": ["create"], "description": "Action must be 'create'"},
|
|
||||||
"name": {"type": "string", "required": true, "description": "Remote skill name"},
|
|
||||||
"host": {"type": "string", "required": true, "description": "SSH host address"},
|
|
||||||
"username": {"type": "string", "required": true, "description": "SSH username"},
|
|
||||||
"port": {"type": "integer", "required": false, "default": 22, "description": "SSH port"},
|
|
||||||
"remote_path": {"type": "string", "required": false, "default": "~/.skills", "description": "Remote skills directory path"},
|
|
||||||
"auth_method": {"type": "string", "required": false, "default": "key", "enum": ["key", "password"], "description": "Authentication method"},
|
|
||||||
"ssh_key_path": {"type": "string", "required": false, "description": "Path to SSH private key file"},
|
|
||||||
"description": {"type": "string", "required": false, "description": "Remote skill description"},
|
|
||||||
"category": {"type": "string", "required": false, "description": "Remote skill category"},
|
|
||||||
"version": {"type": "string", "required": false, "default": "1.0.0", "description": "Remote skill version"},
|
|
||||||
"enabled": {"type": "boolean", "required": false, "default": true, "description": "Whether the remote skill is enabled"}
|
|
||||||
},
|
|
||||||
"function": "hermes_manage_remote_skills"
|
|
||||||
},
|
|
||||||
"read": {
|
|
||||||
"description": "Read remote skill configuration by ID",
|
|
||||||
"parameters": {
|
|
||||||
"action": {"type": "string", "required": true, "enum": ["read"], "description": "Action must be 'read'"},
|
|
||||||
"skill_id": {"type": "string", "required": true, "description": "Remote skill ID"}
|
|
||||||
},
|
|
||||||
"function": "hermes_manage_remote_skills"
|
|
||||||
},
|
|
||||||
"update": {
|
|
||||||
"description": "Update remote skill configuration",
|
|
||||||
"parameters": {
|
|
||||||
"action": {"type": "string", "required": true, "enum": ["update"], "description": "Action must be 'update'"},
|
|
||||||
"skill_id": {"type": "string", "required": true, "description": "Remote skill ID"},
|
|
||||||
"name": {"type": "string", "required": false, "description": "Updated remote skill name"},
|
|
||||||
"host": {"type": "string", "required": false, "description": "Updated SSH host address"},
|
|
||||||
"username": {"type": "string", "required": false, "description": "Updated SSH username"},
|
|
||||||
"port": {"type": "integer", "required": false, "description": "Updated SSH port"},
|
|
||||||
"remote_path": {"type": "string", "required": false, "description": "Updated remote skills directory path"},
|
|
||||||
"auth_method": {"type": "string", "required": false, "enum": ["key", "password"], "description": "Updated authentication method"},
|
|
||||||
"ssh_key_path": {"type": "string", "required": false, "description": "Updated SSH private key path"},
|
|
||||||
"description": {"type": "string", "required": false, "description": "Updated remote skill description"},
|
|
||||||
"category": {"type": "string", "required": false, "description": "Updated remote skill category"},
|
|
||||||
"version": {"type": "string", "required": false, "description": "Updated remote skill version"},
|
|
||||||
"enabled": {"type": "boolean", "required": false, "description": "Updated enabled status"}
|
|
||||||
},
|
|
||||||
"function": "hermes_manage_remote_skills"
|
|
||||||
},
|
|
||||||
"delete": {
|
|
||||||
"description": "Delete remote skill configuration",
|
|
||||||
"parameters": {
|
|
||||||
"action": {"type": "string", "required": true, "enum": ["delete"], "description": "Action must be 'delete'"},
|
|
||||||
"skill_id": {"type": "string", "required": true, "description": "Remote skill ID"}
|
|
||||||
},
|
|
||||||
"function": "hermes_manage_remote_skills"
|
|
||||||
},
|
|
||||||
"list": {
|
|
||||||
"description": "List remote skills with optional filters",
|
|
||||||
"parameters": {
|
|
||||||
"action": {"type": "string", "required": true, "enum": ["list"], "description": "Action must be 'list'"},
|
|
||||||
"name": {"type": "string", "required": false, "description": "Filter by name"},
|
|
||||||
"host": {"type": "string", "required": false, "description": "Filter by host"},
|
|
||||||
"enabled": {"type": "boolean", "required": false, "description": "Filter by enabled status"}
|
|
||||||
},
|
|
||||||
"function": "hermes_manage_remote_skills"
|
|
||||||
},
|
|
||||||
"deploy": {
|
|
||||||
"description": "Deploy skill to remote host",
|
|
||||||
"parameters": {
|
|
||||||
"action": {"type": "string", "required": true, "enum": ["deploy"], "description": "Action must be 'deploy'"},
|
|
||||||
"skill_id": {"type": "string", "required": true, "description": "Remote skill ID"},
|
|
||||||
"skill_content": {"type": "string", "required": true, "description": "Skill content to deploy"}
|
|
||||||
},
|
|
||||||
"function": "hermes_manage_remote_skills"
|
|
||||||
},
|
|
||||||
"execute": {
|
|
||||||
"description": "Execute remote skill",
|
|
||||||
"parameters": {
|
|
||||||
"action": {"type": "string", "required": true, "enum": ["execute"], "description": "Action must be 'execute'"},
|
|
||||||
"skill_id": {"type": "string", "required": true, "description": "Remote skill ID"},
|
|
||||||
"parameters": {"type": "object", "required": false, "description": "Parameters for skill execution"}
|
|
||||||
},
|
|
||||||
"function": "hermes_manage_remote_skills"
|
|
||||||
},
|
|
||||||
"list_remote": {
|
|
||||||
"description": "List available skills on remote host",
|
|
||||||
"parameters": {
|
|
||||||
"action": {"type": "string", "required": true, "enum": ["list_remote"], "description": "Action must be 'list_remote'"},
|
|
||||||
"skill_id": {"type": "string", "required": true, "description": "Remote skill ID"}
|
|
||||||
},
|
|
||||||
"function": "hermes_manage_remote_skills"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"hermes_workflows_crud": {
|
|
||||||
"summary": "CRUD operations for workflow orchestration",
|
|
||||||
"create": {
|
|
||||||
"description": "Create new workflow definition",
|
|
||||||
"parameters": {
|
|
||||||
"name": {"type": "string", "required": true, "description": "Workflow name"},
|
|
||||||
"description": {"type": "string", "required": false, "description": "Workflow description"},
|
|
||||||
"workflow_type": {"type": "string", "required": false, "default": "sequential", "enum": ["sequential", "parallel", "hybrid"], "description": "Workflow type"},
|
|
||||||
"max_concurrent_tasks": {"type": "integer", "required": false, "default": 3, "description": "Maximum concurrent tasks"},
|
|
||||||
"timeout_seconds": {"type": "integer", "required": false, "default": 1800, "description": "Workflow timeout in seconds"},
|
|
||||||
"retry_count": {"type": "integer", "required": false, "default": 2, "description": "Default retry count"}
|
|
||||||
},
|
|
||||||
"function": "hermes_create_workflow"
|
|
||||||
},
|
|
||||||
"read": {
|
|
||||||
"description": "List workflows for current user",
|
|
||||||
"parameters": {},
|
|
||||||
"function": "hermes_list_workflows"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"hermes_tasks_workflow": {
|
|
||||||
"summary": "Task management within workflows",
|
|
||||||
"create": {
|
|
||||||
"description": "Add task to existing workflow",
|
|
||||||
"parameters": {
|
|
||||||
"workflow_id": {"type": "string", "required": true, "description": "Workflow ID"},
|
|
||||||
"task_name": {"type": "string", "required": true, "description": "Task name"},
|
|
||||||
"task_type": {"type": "string", "required": true, "enum": ["skill", "tool", "memory", "session_search", "custom"], "description": "Task type"},
|
|
||||||
"skill_name": {"type": "string", "required": false, "description": "Skill name (for skill tasks)"},
|
|
||||||
"tool_name": {"type": "string", "required": false, "description": "Tool name (for tool tasks)"},
|
|
||||||
"parameters": {"type": "object", "required": false, "description": "Task parameters"},
|
|
||||||
"depends_on": {"type": "string", "required": false, "description": "Dependency task ID"},
|
|
||||||
"parallel_group": {"type": "string", "required": false, "description": "Parallel group identifier"},
|
|
||||||
"timeout_seconds": {"type": "integer", "required": false, "default": 300, "description": "Task timeout in seconds"},
|
|
||||||
"retry_count": {"type": "integer", "required": false, "default": 2, "description": "Task retry count"},
|
|
||||||
"order_index": {"type": "integer", "required": false, "default": 0, "description": "Execution order index"}
|
|
||||||
},
|
|
||||||
"function": "hermes_add_task_to_workflow"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"hermes_executions_task": {
|
|
||||||
"summary": "Workflow execution and monitoring",
|
|
||||||
"create": {
|
|
||||||
"description": "Execute workflow",
|
|
||||||
"parameters": {
|
|
||||||
"workflow_id": {"type": "string", "required": true, "description": "Workflow ID to execute"}
|
|
||||||
},
|
|
||||||
"function": "hermes_execute_workflow"
|
|
||||||
},
|
|
||||||
"read": {
|
|
||||||
"description": "List executions with optional workflow filter",
|
|
||||||
"parameters": {
|
|
||||||
"workflow_id": {"type": "string", "required": false, "description": "Filter by workflow ID"},
|
|
||||||
"limit": {"type": "integer", "required": false, "default": 100, "description": "Maximum number of executions"},
|
|
||||||
"offset": {"type": "integer", "required": false, "default": 0, "description": "Pagination offset"}
|
|
||||||
},
|
|
||||||
"function": "hermes_list_executions"
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
166
database.json
166
database.json
@ -1,166 +0,0 @@
|
|||||||
{
|
|
||||||
"hermes_memory": {
|
|
||||||
"summary": "Enhanced memory storage with intelligent filtering and user isolation",
|
|
||||||
"fields": {
|
|
||||||
"id": {"type": "string", "primary_key": true, "description": "Unique memory identifier"},
|
|
||||||
"user_id": {"type": "string", "required": true, "description": "User ID for multi-user isolation"},
|
|
||||||
"target": {"type": "string", "required": true, "description": "Memory target: 'memory' or 'user'"},
|
|
||||||
"content": {"type": "text", "required": true, "description": "Memory content"},
|
|
||||||
"priority": {"type": "integer", "default": 50, "description": "Priority score (0-100) for intelligent filtering"},
|
|
||||||
"access_count": {"type": "integer", "default": 0, "description": "Number of times this memory has been accessed"},
|
|
||||||
"last_accessed": {"type": "datetime", "nullable": true, "description": "Last access timestamp for relevance ranking"},
|
|
||||||
"created_at": {"type": "datetime", "required": true, "description": "Creation timestamp"},
|
|
||||||
"updated_at": {"type": "datetime", "required": true, "description": "Last update timestamp"}
|
|
||||||
},
|
|
||||||
"indexes": [
|
|
||||||
["user_id", "target"],
|
|
||||||
["user_id", "priority", "last_accessed"],
|
|
||||||
["user_id", "created_at"]
|
|
||||||
],
|
|
||||||
"codes": {}
|
|
||||||
},
|
|
||||||
"hermes_skills": {
|
|
||||||
"summary": "User-isolated skills storage with full CRUD operations",
|
|
||||||
"fields": {
|
|
||||||
"id": {"type": "string", "primary_key": true, "description": "Unique skill identifier"},
|
|
||||||
"user_id": {"type": "string", "required": true, "description": "User ID for multi-user isolation"},
|
|
||||||
"name": {"type": "string", "required": true, "description": "Skill name"},
|
|
||||||
"description": {"type": "text", "nullable": true, "description": "Skill description"},
|
|
||||||
"category": {"type": "string", "nullable": true, "description": "Skill category"},
|
|
||||||
"version": {"type": "string", "default": "1.0.0", "description": "Skill version"},
|
|
||||||
"content": {"type": "text", "required": true, "description": "Skill content (SKILL.md format)"},
|
|
||||||
"created_at": {"type": "datetime", "required": true, "description": "Creation timestamp"},
|
|
||||||
"updated_at": {"type": "datetime", "required": true, "description": "Last update timestamp"}
|
|
||||||
},
|
|
||||||
"indexes": [
|
|
||||||
["user_id", "name"],
|
|
||||||
["user_id", "category"],
|
|
||||||
["user_id", "created_at"]
|
|
||||||
],
|
|
||||||
"codes": {}
|
|
||||||
},
|
|
||||||
"hermes_sessions": {
|
|
||||||
"summary": "Session metadata with user isolation for conversation history",
|
|
||||||
"fields": {
|
|
||||||
"id": {"type": "string", "primary_key": true, "description": "Unique session identifier"},
|
|
||||||
"user_id": {"type": "string", "required": true, "description": "User ID for multi-user isolation"},
|
|
||||||
"title": {"type": "string", "nullable": true, "description": "Session title"},
|
|
||||||
"preview": {"type": "text", "nullable": true, "description": "Session preview text"},
|
|
||||||
"tags": {"type": "string", "nullable": true, "description": "Comma-separated session tags"},
|
|
||||||
"started_at": {"type": "datetime", "required": true, "description": "Session start timestamp"},
|
|
||||||
"ended_at": {"type": "datetime", "nullable": true, "description": "Session end timestamp"},
|
|
||||||
"duration_seconds": {"type": "integer", "nullable": true, "description": "Session duration in seconds"}
|
|
||||||
},
|
|
||||||
"indexes": [
|
|
||||||
["user_id", "started_at"],
|
|
||||||
["user_id", "title"],
|
|
||||||
["user_id", "tags"]
|
|
||||||
],
|
|
||||||
"codes": {}
|
|
||||||
},
|
|
||||||
"hermes_remote_skills": {
|
|
||||||
"summary": "SSH remote skills configuration with deployment tracking",
|
|
||||||
"fields": {
|
|
||||||
"id": {"type": "string", "primary_key": true, "description": "Unique remote skill identifier"},
|
|
||||||
"user_id": {"type": "string", "required": true, "description": "User ID for multi-user isolation"},
|
|
||||||
"name": {"type": "string", "required": true, "description": "Remote skill name"},
|
|
||||||
"host": {"type": "string", "required": true, "description": "SSH host address"},
|
|
||||||
"port": {"type": "integer", "default": 22, "description": "SSH port"},
|
|
||||||
"username": {"type": "string", "required": true, "description": "SSH username"},
|
|
||||||
"remote_path": {"type": "string", "default": "~/.skills", "description": "Remote skills directory path"},
|
|
||||||
"auth_method": {"type": "string", "default": "key", "description": "Authentication method: 'key' or 'password'"},
|
|
||||||
"ssh_key_path": {"type": "string", "nullable": true, "description": "Path to SSH private key file"},
|
|
||||||
"description": {"type": "text", "nullable": true, "description": "Remote skill description"},
|
|
||||||
"category": {"type": "string", "nullable": true, "description": "Remote skill category"},
|
|
||||||
"version": {"type": "string", "default": "1.0.0", "description": "Remote skill version"},
|
|
||||||
"enabled": {"type": "boolean", "default": true, "description": "Whether the remote skill is enabled"},
|
|
||||||
"last_deployed": {"type": "datetime", "nullable": true, "description": "Last deployment timestamp"},
|
|
||||||
"last_executed": {"type": "datetime", "nullable": true, "description": "Last execution timestamp"},
|
|
||||||
"created_at": {"type": "datetime", "required": true, "description": "Creation timestamp"},
|
|
||||||
"updated_at": {"type": "datetime", "required": true, "description": "Last update timestamp"}
|
|
||||||
},
|
|
||||||
"indexes": [
|
|
||||||
["user_id", "name"],
|
|
||||||
["user_id", "host", "username"],
|
|
||||||
["user_id", "enabled"],
|
|
||||||
["user_id", "created_at"]
|
|
||||||
],
|
|
||||||
"codes": {}
|
|
||||||
},
|
|
||||||
"hermes_workflows": {
|
|
||||||
"summary": "Workflow definitions with orchestration parameters",
|
|
||||||
"fields": {
|
|
||||||
"id": {"type": "string", "primary_key": true, "description": "Unique workflow identifier"},
|
|
||||||
"user_id": {"type": "string", "required": true, "description": "User ID for multi-user isolation"},
|
|
||||||
"name": {"type": "string", "required": true, "description": "Workflow name"},
|
|
||||||
"description": {"type": "text", "nullable": true, "description": "Workflow description"},
|
|
||||||
"workflow_type": {"type": "string", "default": "sequential", "description": "Workflow type: sequential, parallel, or hybrid"},
|
|
||||||
"max_concurrent_tasks": {"type": "integer", "default": 3, "description": "Maximum concurrent tasks for parallel workflows"},
|
|
||||||
"timeout_seconds": {"type": "integer", "default": 1800, "description": "Workflow timeout in seconds"},
|
|
||||||
"retry_count": {"type": "integer", "default": 2, "description": "Default retry count for tasks"},
|
|
||||||
"status": {"type": "string", "default": "active", "description": "Workflow status: active, inactive, archived"},
|
|
||||||
"created_at": {"type": "datetime", "required": true, "description": "Creation timestamp"},
|
|
||||||
"updated_at": {"type": "datetime", "required": true, "description": "Last update timestamp"}
|
|
||||||
},
|
|
||||||
"indexes": [
|
|
||||||
["user_id", "name"],
|
|
||||||
["user_id", "workflow_type"],
|
|
||||||
["user_id", "status"],
|
|
||||||
["user_id", "created_at"]
|
|
||||||
],
|
|
||||||
"codes": {}
|
|
||||||
},
|
|
||||||
"hermes_tasks": {
|
|
||||||
"summary": "Task definitions with dependencies and execution parameters",
|
|
||||||
"fields": {
|
|
||||||
"id": {"type": "string", "primary_key": true, "description": "Unique task identifier"},
|
|
||||||
"user_id": {"type": "string", "required": true, "description": "User ID for multi-user isolation"},
|
|
||||||
"workflow_id": {"type": "string", "required": true, "description": "Associated workflow ID"},
|
|
||||||
"task_name": {"type": "string", "required": true, "description": "Task name"},
|
|
||||||
"task_type": {"type": "string", "required": true, "description": "Task type: skill, tool, memory, session_search, custom"},
|
|
||||||
"skill_name": {"type": "string", "nullable": true, "description": "Skill name (for skill tasks)"},
|
|
||||||
"tool_name": {"type": "string", "nullable": true, "description": "Tool name (for tool tasks)"},
|
|
||||||
"parameters_json": {"type": "text", "nullable": true, "description": "JSON-encoded task parameters"},
|
|
||||||
"depends_on": {"type": "string", "nullable": true, "description": "ID of task this depends on"},
|
|
||||||
"parallel_group": {"type": "string", "nullable": true, "description": "Parallel group identifier for hybrid workflows"},
|
|
||||||
"timeout_seconds": {"type": "integer", "default": 300, "description": "Task timeout in seconds"},
|
|
||||||
"retry_count": {"type": "integer", "default": 2, "description": "Task-specific retry count"},
|
|
||||||
"order_index": {"type": "integer", "default": 0, "description": "Execution order index"},
|
|
||||||
"created_at": {"type": "datetime", "required": true, "description": "Creation timestamp"},
|
|
||||||
"updated_at": {"type": "datetime", "required": true, "description": "Last update timestamp"}
|
|
||||||
},
|
|
||||||
"indexes": [
|
|
||||||
["user_id", "workflow_id"],
|
|
||||||
["user_id", "task_type"],
|
|
||||||
["user_id", "parallel_group"],
|
|
||||||
["user_id", "order_index"],
|
|
||||||
["depends_on"]
|
|
||||||
],
|
|
||||||
"codes": {}
|
|
||||||
},
|
|
||||||
"hermes_executions": {
|
|
||||||
"summary": "Execution records with status tracking and results",
|
|
||||||
"fields": {
|
|
||||||
"id": {"type": "string", "primary_key": true, "description": "Unique execution identifier"},
|
|
||||||
"user_id": {"type": "string", "required": true, "description": "User ID for multi-user isolation"},
|
|
||||||
"workflow_id": {"type": "string", "required": true, "description": "Associated workflow ID"},
|
|
||||||
"task_id": {"type": "string", "nullable": true, "description": "Associated task ID (null for workflow executions)"},
|
|
||||||
"execution_status": {"type": "string", "default": "pending", "description": "Execution status: pending, running, completed, failed, cancelled"},
|
|
||||||
"start_time": {"type": "datetime", "nullable": true, "description": "Execution start timestamp"},
|
|
||||||
"end_time": {"type": "datetime", "nullable": true, "description": "Execution end timestamp"},
|
|
||||||
"duration_seconds": {"type": "integer", "nullable": true, "description": "Execution duration in seconds"},
|
|
||||||
"result_json": {"type": "text", "nullable": true, "description": "JSON-encoded execution result"},
|
|
||||||
"error_message": {"type": "text", "nullable": true, "description": "Error message if execution failed"},
|
|
||||||
"retry_count": {"type": "integer", "default": 0, "description": "Number of retries attempted"},
|
|
||||||
"created_at": {"type": "datetime", "required": true, "description": "Creation timestamp"},
|
|
||||||
"updated_at": {"type": "datetime", "required": true, "description": "Last update timestamp"}
|
|
||||||
},
|
|
||||||
"indexes": [
|
|
||||||
["user_id", "workflow_id"],
|
|
||||||
["user_id", "execution_status"],
|
|
||||||
["user_id", "start_time"],
|
|
||||||
["user_id", "created_at"]
|
|
||||||
],
|
|
||||||
"codes": {}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -16,6 +16,10 @@ from .core import (
|
|||||||
harnessed_list_workflows,
|
harnessed_list_workflows,
|
||||||
harnessed_list_executions
|
harnessed_list_executions
|
||||||
)
|
)
|
||||||
|
from .config_functions import (
|
||||||
|
harnessed_get_agent_config,
|
||||||
|
harnessed_save_agent_config
|
||||||
|
)
|
||||||
|
|
||||||
def load_harnessed_agent():
|
def load_harnessed_agent():
|
||||||
env = ServerEnv()
|
env = ServerEnv()
|
||||||
@ -35,3 +39,7 @@ def load_harnessed_agent():
|
|||||||
env.harnessed_execute_workflow = harnessed_execute_workflow
|
env.harnessed_execute_workflow = harnessed_execute_workflow
|
||||||
env.harnessed_list_workflows = harnessed_list_workflows
|
env.harnessed_list_workflows = harnessed_list_workflows
|
||||||
env.harnessed_list_executions = harnessed_list_executions
|
env.harnessed_list_executions = harnessed_list_executions
|
||||||
|
|
||||||
|
# Configuration management functions
|
||||||
|
env.harnessed_get_agent_config = harnessed_get_agent_config
|
||||||
|
env.harnessed_save_agent_config = harnessed_save_agent_config
|
||||||
@ -56,5 +56,35 @@
|
|||||||
"created_at": "2026-04-15 21:06:00",
|
"created_at": "2026-04-15 21:06:00",
|
||||||
"updated_at": "2026-04-15 21:06:00"
|
"updated_at": "2026-04-15 21:06:00"
|
||||||
}
|
}
|
||||||
|
],
|
||||||
|
"harnessed_agent_config": [
|
||||||
|
{
|
||||||
|
"id": "default_agent_config_user_1",
|
||||||
|
"user_id": "user_1",
|
||||||
|
"work_dir": "./hermes_work",
|
||||||
|
"skills_path": "~/.hermes/skills",
|
||||||
|
"max_memory_tokens": 2000,
|
||||||
|
"default_priority": 50,
|
||||||
|
"high_priority_threshold": 70,
|
||||||
|
"low_priority_threshold": 30,
|
||||||
|
"auto_cleanup_enabled": "1",
|
||||||
|
"min_retention_days": 30,
|
||||||
|
"created_at": "2026-04-20 10:48:00",
|
||||||
|
"updated_at": "2026-04-20 10:48:00"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"id": "default_agent_config_user_2",
|
||||||
|
"user_id": "user_2",
|
||||||
|
"work_dir": "./hermes_work",
|
||||||
|
"skills_path": "~/.hermes/skills",
|
||||||
|
"max_memory_tokens": 2000,
|
||||||
|
"default_priority": 50,
|
||||||
|
"high_priority_threshold": 70,
|
||||||
|
"low_priority_threshold": 30,
|
||||||
|
"auto_cleanup_enabled": "1",
|
||||||
|
"min_retention_days": 30,
|
||||||
|
"created_at": "2026-04-20 10:48:00",
|
||||||
|
"updated_at": "2026-04-20 10:48:00"
|
||||||
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@ -1,92 +0,0 @@
|
|||||||
#!/bin/bash
|
|
||||||
# Build script for harnessed_agent module
|
|
||||||
|
|
||||||
set -e
|
|
||||||
|
|
||||||
echo "Building Hermes Agent module..."
|
|
||||||
|
|
||||||
# Create database tables if they don't exist
|
|
||||||
echo "Creating database tables..."
|
|
||||||
python3 -c "
|
|
||||||
import sys
|
|
||||||
sys.path.insert(0, '.')
|
|
||||||
from sqlor.dbpools import DBPools
|
|
||||||
from sqlor.sqlor import SQLor
|
|
||||||
|
|
||||||
# Initialize database pools
|
|
||||||
dbpools = DBPools()
|
|
||||||
db = dbpools.get('default')
|
|
||||||
|
|
||||||
# Create harnessed_agent table
|
|
||||||
try:
|
|
||||||
db.execute('''
|
|
||||||
CREATE TABLE IF NOT EXISTS harnessed_agent (
|
|
||||||
id VARCHAR(64) PRIMARY KEY,
|
|
||||||
name VARCHAR(255) NOT NULL,
|
|
||||||
description TEXT,
|
|
||||||
config JSON,
|
|
||||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
|
|
||||||
)
|
|
||||||
''')
|
|
||||||
print('harnessed_agent table created')
|
|
||||||
except Exception as e:
|
|
||||||
print(f'Error creating harnessed_agent table: {e}')
|
|
||||||
|
|
||||||
# Create sessions table
|
|
||||||
try:
|
|
||||||
db.execute('''
|
|
||||||
CREATE TABLE IF NOT EXISTS sessions (
|
|
||||||
id VARCHAR(64) PRIMARY KEY,
|
|
||||||
user_id VARCHAR(64) NOT NULL,
|
|
||||||
context JSON,
|
|
||||||
metadata JSON,
|
|
||||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
INDEX idx_user_id (user_id),
|
|
||||||
INDEX idx_created_at (created_at)
|
|
||||||
)
|
|
||||||
''')
|
|
||||||
print('sessions table created')
|
|
||||||
except Exception as e:
|
|
||||||
print(f'Error creating sessions table: {e}')
|
|
||||||
|
|
||||||
# Create skills table
|
|
||||||
try:
|
|
||||||
db.execute('''
|
|
||||||
CREATE TABLE IF NOT EXISTS skills (
|
|
||||||
id VARCHAR(64) PRIMARY KEY,
|
|
||||||
name VARCHAR(255) NOT NULL UNIQUE,
|
|
||||||
description TEXT,
|
|
||||||
definition JSON,
|
|
||||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
INDEX idx_name (name)
|
|
||||||
)
|
|
||||||
''')
|
|
||||||
print('skills table created')
|
|
||||||
except Exception as e:
|
|
||||||
print(f'Error creating skills table: {e}')
|
|
||||||
|
|
||||||
# Create memory table
|
|
||||||
try:
|
|
||||||
db.execute('''
|
|
||||||
CREATE TABLE IF NOT EXISTS memory (
|
|
||||||
id VARCHAR(64) PRIMARY KEY,
|
|
||||||
user_id VARCHAR(64),
|
|
||||||
key VARCHAR(255) NOT NULL,
|
|
||||||
value JSON,
|
|
||||||
memory_type ENUM('user', 'system') NOT NULL,
|
|
||||||
created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
|
|
||||||
INDEX idx_user_key (user_id, key),
|
|
||||||
INDEX idx_system_key (key),
|
|
||||||
INDEX idx_memory_type (memory_type)
|
|
||||||
)
|
|
||||||
''')
|
|
||||||
print('memory table created')
|
|
||||||
except Exception as e:
|
|
||||||
print(f'Error creating memory table: {e}')
|
|
||||||
"
|
|
||||||
|
|
||||||
echo "Hermes Agent module build completed successfully!"
|
|
||||||
@ -1,25 +0,0 @@
|
|||||||
{
|
|
||||||
"tblname": "task_dependencies",
|
|
||||||
"alias": "dependencies_by_dependency",
|
|
||||||
"title": "Task Dependencies (Dependency)",
|
|
||||||
"params": {
|
|
||||||
"sortby": ["created_at desc"],
|
|
||||||
"logined_userorgid": "user_id",
|
|
||||||
"confidential_fields": [],
|
|
||||||
"browserfields": {
|
|
||||||
"exclouded": ["id", "user_id", "workflow_id", "dependency_task_id"],
|
|
||||||
"alters": {
|
|
||||||
"dependency_type": {
|
|
||||||
"uitype": "code",
|
|
||||||
"data": [
|
|
||||||
{"value": "completion", "text": "Completion"},
|
|
||||||
{"value": "success", "text": "Success"},
|
|
||||||
{"value": "failure", "text": "Failure"},
|
|
||||||
{"value": "data_available", "text": "Data Available"}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"editexclouded": ["id", "user_id", "workflow_id", "dependency_task_id", "created_at", "updated_at"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,25 +0,0 @@
|
|||||||
{
|
|
||||||
"tblname": "task_dependencies",
|
|
||||||
"alias": "dependencies_by_dependent",
|
|
||||||
"title": "Task Dependencies (Dependent)",
|
|
||||||
"params": {
|
|
||||||
"sortby": ["created_at desc"],
|
|
||||||
"logined_userorgid": "user_id",
|
|
||||||
"confidential_fields": [],
|
|
||||||
"browserfields": {
|
|
||||||
"exclouded": ["id", "user_id", "workflow_id", "dependent_task_id"],
|
|
||||||
"alters": {
|
|
||||||
"dependency_type": {
|
|
||||||
"uitype": "code",
|
|
||||||
"data": [
|
|
||||||
{"value": "completion", "text": "Completion"},
|
|
||||||
{"value": "success", "text": "Success"},
|
|
||||||
{"value": "failure", "text": "Failure"},
|
|
||||||
{"value": "data_available", "text": "Data Available"}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"editexclouded": ["id", "user_id", "workflow_id", "dependent_task_id", "created_at", "updated_at"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,26 +0,0 @@
|
|||||||
{
|
|
||||||
"tblname": "executions",
|
|
||||||
"title": "Execution Monitoring",
|
|
||||||
"params": {
|
|
||||||
"sortby": ["created_at desc"],
|
|
||||||
"logined_userorgid": "user_id",
|
|
||||||
"confidential_fields": ["input_parameters", "output_results"],
|
|
||||||
"browserfields": {
|
|
||||||
"exclouded": ["id", "user_id", "workflow_id", "parent_execution_id", "input_parameters", "output_results"],
|
|
||||||
"alters": {
|
|
||||||
"status": {
|
|
||||||
"uitype": "code",
|
|
||||||
"data": [
|
|
||||||
{"value": "pending", "text": "Pending"},
|
|
||||||
{"value": "running", "text": "Running"},
|
|
||||||
{"value": "completed", "text": "Completed"},
|
|
||||||
{"value": "failed", "text": "Failed"},
|
|
||||||
{"value": "cancelled", "text": "Cancelled"},
|
|
||||||
{"value": "timeout", "text": "Timeout"}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"editexclouded": ["id", "user_id", "workflow_id", "parent_execution_id", "created_at", "updated_at"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,27 +1,26 @@
|
|||||||
{
|
{
|
||||||
"tblname": "executions",
|
"tblname": "hermes_executions",
|
||||||
"alias": "executions_by_workflow",
|
"alias": "executions_by_workflow",
|
||||||
"title": "Workflow Executions",
|
"title": "Workflow Executions",
|
||||||
"params": {
|
"params": {
|
||||||
"sortby": ["created_at desc"],
|
"sortby": ["created_at desc"],
|
||||||
"logined_userorgid": "user_id",
|
"logined_userid": "user_id",
|
||||||
"confidential_fields": ["input_parameters", "output_results"],
|
"confidential_fields": ["result_json", "error_message"],
|
||||||
"browserfields": {
|
"browserfields": {
|
||||||
"exclouded": ["id", "user_id", "workflow_id", "parent_execution_id", "input_parameters", "output_results"],
|
"exclouded": ["id", "user_id", "result_json", "error_message", "created_at", "updated_at"],
|
||||||
"alters": {
|
"alters": {
|
||||||
"status": {
|
"execution_status": {
|
||||||
"uitype": "code",
|
"uitype": "code",
|
||||||
"data": [
|
"data": [
|
||||||
{"value": "pending", "text": "Pending"},
|
{"value": "pending", "text": "Pending"},
|
||||||
{"value": "running", "text": "Running"},
|
{"value": "running", "text": "Running"},
|
||||||
{"value": "completed", "text": "Completed"},
|
{"value": "completed", "text": "Completed"},
|
||||||
{"value": "failed", "text": "Failed"},
|
{"value": "failed", "text": "Failed"},
|
||||||
{"value": "cancelled", "text": "Cancelled"},
|
{"value": "cancelled", "text": "Cancelled"}
|
||||||
{"value": "timeout", "text": "Timeout"}
|
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"editexclouded": ["id", "user_id", "workflow_id", "parent_execution_id", "created_at", "updated_at"]
|
"editexclouded": ["id", "user_id", "created_at", "updated_at"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,13 +0,0 @@
|
|||||||
{
|
|
||||||
"tblname":"harnessed_agent",
|
|
||||||
"params":{
|
|
||||||
"title":"Hermes Agent",
|
|
||||||
"description":"Hermes Agent核心配置",
|
|
||||||
"sortby":"name",
|
|
||||||
"browserfields":{
|
|
||||||
"exclouded":["id"],
|
|
||||||
"alters":{}
|
|
||||||
},
|
|
||||||
"editexclouded":["id"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,52 +1,25 @@
|
|||||||
{
|
{
|
||||||
"name": "hermes_executions_crud",
|
"tblname": "hermes_executions",
|
||||||
"table": "hermes_executions",
|
"title": "Execution Monitoring",
|
||||||
"operations": {
|
"params": {
|
||||||
"create": {
|
"sortby": ["created_at desc"],
|
||||||
"method": "POST",
|
"logined_userid": "user_id",
|
||||||
"url": "/api/hermes/executions",
|
"confidential_fields": ["result_json", "error_message"],
|
||||||
"description": "Create a new execution record for current user"
|
"browserfields": {
|
||||||
},
|
"exclouded": ["id", "user_id", "workflow_id", "task_id", "result_json", "error_message", "created_at", "updated_at"],
|
||||||
"read": {
|
"alters": {
|
||||||
"method": "GET",
|
"execution_status": {
|
||||||
"url": "/api/hermes/executions/{id}",
|
"uitype": "code",
|
||||||
"description": "Read an execution by ID (user-isolated)"
|
"data": [
|
||||||
},
|
{"value": "pending", "text": "Pending"},
|
||||||
"update": {
|
{"value": "running", "text": "Running"},
|
||||||
"method": "PUT",
|
{"value": "completed", "text": "Completed"},
|
||||||
"url": "/api/hermes/executions/{id}",
|
{"value": "failed", "text": "Failed"},
|
||||||
"description": "Update an execution record (user-isolated)"
|
{"value": "cancelled", "text": "Cancelled"}
|
||||||
},
|
]
|
||||||
"delete": {
|
}
|
||||||
"method": "DELETE",
|
}
|
||||||
"url": "/api/hermes/executions/{id}",
|
},
|
||||||
"description": "Delete an execution record (user-isolated)"
|
"editexclouded": ["id", "user_id", "workflow_id", "task_id", "created_at", "updated_at"]
|
||||||
},
|
|
||||||
"list": {
|
|
||||||
"method": "GET",
|
|
||||||
"url": "/api/hermes/executions",
|
|
||||||
"description": "List all executions for current user with optional filtering"
|
|
||||||
},
|
|
||||||
"search": {
|
|
||||||
"method": "GET",
|
|
||||||
"url": "/api/hermes/executions/search",
|
|
||||||
"description": "Search executions by status or workflow (user-isolated)"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"fields": {
|
|
||||||
"id": {"type": "str", "required": true},
|
|
||||||
"user_id": {"type": "str", "required": true, "auto": "current_user_id"},
|
|
||||||
"workflow_id": {"type": "str", "required": true},
|
|
||||||
"task_id": {"type": "str", "required": false},
|
|
||||||
"execution_status": {"type": "str", "required": false, "default": "pending"},
|
|
||||||
"start_time": {"type": "datetime", "required": false},
|
|
||||||
"end_time": {"type": "datetime", "required": false},
|
|
||||||
"duration_seconds": {"type": "int", "required": false},
|
|
||||||
"result_json": {"type": "text", "required": false},
|
|
||||||
"error_message": {"type": "text", "required": false},
|
|
||||||
"retry_count": {"type": "int", "required": false, "default": 0}
|
|
||||||
},
|
|
||||||
"filters": {
|
|
||||||
"user_id": {"auto": "current_user_id"}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,56 +0,0 @@
|
|||||||
{
|
|
||||||
"tblname": "hermes_memory",
|
|
||||||
"title": "Hermes Agent Intelligent Memory",
|
|
||||||
"params": {
|
|
||||||
"sortby": ["priority desc", "last_accessed desc"],
|
|
||||||
"logined_userid": "user_id",
|
|
||||||
"confidential_fields": [],
|
|
||||||
"editor": {
|
|
||||||
"binds": [
|
|
||||||
{
|
|
||||||
"wid": "target",
|
|
||||||
"event": "changed",
|
|
||||||
"actiontype": "script",
|
|
||||||
"target": "priority",
|
|
||||||
"script": "if (source.value === 'user') { target.value = 80; } else { target.value = 50; }"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"browserfields": {
|
|
||||||
"exclouded": ["id", "access_count", "last_accessed", "created_at", "updated_at"],
|
|
||||||
"alters": {
|
|
||||||
"target": {
|
|
||||||
"uitype": "code",
|
|
||||||
"data": [
|
|
||||||
{
|
|
||||||
"value": "memory",
|
|
||||||
"text": "System Memory"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"value": "user",
|
|
||||||
"text": "User Preferences"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"priority": {
|
|
||||||
"uitype": "code",
|
|
||||||
"data": [
|
|
||||||
{
|
|
||||||
"value": "0",
|
|
||||||
"text": "Low (0-29)"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"value": "30",
|
|
||||||
"text": "Medium (30-69)"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"value": "70",
|
|
||||||
"text": "High (70-100)"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"editexclouded": ["id", "user_id", "access_count", "last_accessed", "created_at", "updated_at"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,48 +1,41 @@
|
|||||||
{
|
{
|
||||||
"name": "hermes_memory_crud",
|
"tblname": "hermes_memory",
|
||||||
"table": "hermes_memory",
|
"title": "Hermes Agent Intelligent Memory",
|
||||||
"operations": {
|
"params": {
|
||||||
"create": {
|
"sortby": ["priority desc", "last_accessed desc"],
|
||||||
"method": "POST",
|
"logined_userid": "user_id",
|
||||||
"url": "/api/hermes/memory",
|
"confidential_fields": [],
|
||||||
"description": "Create a new memory entry for current user with intelligent filtering"
|
"editor": {
|
||||||
},
|
"binds": [
|
||||||
"read": {
|
{
|
||||||
"method": "GET",
|
"wid": "target",
|
||||||
"url": "/api/hermes/memory/{id}",
|
"event": "changed",
|
||||||
"description": "Read a memory entry by ID (user-isolated)"
|
"actiontype": "script",
|
||||||
},
|
"target": "priority",
|
||||||
"update": {
|
"script": "if (source.value === 'user') { target.value = 80; } else { target.value = 50; }"
|
||||||
"method": "PUT",
|
|
||||||
"url": "/api/hermes/memory/{id}",
|
|
||||||
"description": "Update a memory entry (user-isolated)"
|
|
||||||
},
|
|
||||||
"delete": {
|
|
||||||
"method": "DELETE",
|
|
||||||
"url": "/api/hermes/memory/{id}",
|
|
||||||
"description": "Delete a memory entry (user-isolated)"
|
|
||||||
},
|
|
||||||
"list": {
|
|
||||||
"method": "GET",
|
|
||||||
"url": "/api/hermes/memory",
|
|
||||||
"description": "List all memory entries for current user with optional filtering and priority sorting"
|
|
||||||
},
|
|
||||||
"search": {
|
|
||||||
"method": "GET",
|
|
||||||
"url": "/api/hermes/memory/search",
|
|
||||||
"description": "Search memory entries by content or target (user-isolated)"
|
|
||||||
}
|
}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"fields": {
|
"browserfields": {
|
||||||
"id": {"type": "str", "required": true},
|
"exclouded": ["id", "access_count", "last_accessed", "created_at", "updated_at"],
|
||||||
"user_id": {"type": "str", "required": true, "auto": "current_user_id"},
|
"alters": {
|
||||||
"target": {"type": "str", "required": true},
|
"target": {
|
||||||
"content": {"type": "text", "required": true},
|
"uitype": "code",
|
||||||
"priority": {"type": "int", "required": false, "default": 50},
|
"data": [
|
||||||
"access_count": {"type": "int", "required": false, "default": 0},
|
{"value": "memory", "text": "System Memory"},
|
||||||
"last_accessed": {"type": "datetime", "required": false}
|
{"value": "user", "text": "User Preferences"}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"filters": {
|
"priority": {
|
||||||
"user_id": {"auto": "current_user_id"}
|
"uitype": "code",
|
||||||
|
"data": [
|
||||||
|
{"value": "0", "text": "Low (0-29)"},
|
||||||
|
{"value": "30", "text": "Medium (30-69)"},
|
||||||
|
{"value": "70", "text": "High (70-100)"}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"editexclouded": ["id", "user_id", "access_count", "last_accessed", "created_at", "updated_at"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,105 +1,29 @@
|
|||||||
{
|
{
|
||||||
"name": "harnessed_remote_skills_crud",
|
"tblname": "harnessed_remote_skills",
|
||||||
"description": "CRUD operations for remote skills with SSH deployment support",
|
"title": "Remote Skills Management",
|
||||||
"operations": {
|
"params": {
|
||||||
"create": {
|
"sortby": ["name"],
|
||||||
"url": "/harnessed_agent/remote_skills",
|
"logined_userid": "user_id",
|
||||||
"method": "POST",
|
"confidential_fields": ["ssh_key_path"],
|
||||||
"fields": {
|
"browserfields": {
|
||||||
"id": {"type": "str", "required": true, "auto": "uuid"},
|
"exclouded": ["id", "user_id", "ssh_key_path", "last_deployed", "last_executed", "last_connected", "created_at", "updated_at"],
|
||||||
"user_id": {"type": "str", "required": true, "auto": "current_user_id"},
|
"alters": {
|
||||||
"name": {"type": "str", "required": true},
|
"enabled": {
|
||||||
"host": {"type": "str", "required": true},
|
"uitype": "code",
|
||||||
"port": {"type": "int", "required": false, "default": 22},
|
"data": [
|
||||||
"username": {"type": "str", "required": true},
|
{"value": "1", "text": "Enabled"},
|
||||||
"remote_path": {"type": "str", "required": false, "default": "~/.skills"},
|
{"value": "0", "text": "Disabled"}
|
||||||
"auth_method": {"type": "str", "required": false, "default": "key"},
|
]
|
||||||
"ssh_key_path": {"type": "str", "required": false},
|
|
||||||
"description": {"type": "str", "required": false},
|
|
||||||
"category": {"type": "str", "required": false},
|
|
||||||
"version": {"type": "str", "required": false, "default": "1.0.0"},
|
|
||||||
"enabled": {"type": "bool", "required": false, "default": true},
|
|
||||||
"created_at": {"type": "datetime", "required": true, "auto": "now"},
|
|
||||||
"updated_at": {"type": "datetime", "required": true, "auto": "now"}
|
|
||||||
}
|
|
||||||
},
|
},
|
||||||
"read": {
|
"auth_method": {
|
||||||
"url": "/harnessed_agent/remote_skills/{id}",
|
"uitype": "code",
|
||||||
"method": "GET",
|
"data": [
|
||||||
"filters": {
|
{"value": "key", "text": "SSH Key"},
|
||||||
"id": {"type": "str", "required": true},
|
{"value": "password", "text": "Password"}
|
||||||
"user_id": {"type": "str", "required": true, "auto": "current_user_id"}
|
]
|
||||||
}
|
|
||||||
},
|
|
||||||
"update": {
|
|
||||||
"url": "/harnessed_agent/remote_skills/{id}",
|
|
||||||
"method": "PUT",
|
|
||||||
"fields": {
|
|
||||||
"id": {"type": "str", "required": true},
|
|
||||||
"user_id": {"type": "str", "required": true, "auto": "current_user_id"},
|
|
||||||
"name": {"type": "str", "required": false},
|
|
||||||
"host": {"type": "str", "required": false},
|
|
||||||
"port": {"type": "int", "required": false},
|
|
||||||
"username": {"type": "str", "required": false},
|
|
||||||
"remote_path": {"type": "str", "required": false},
|
|
||||||
"auth_method": {"type": "str", "required": false},
|
|
||||||
"ssh_key_path": {"type": "str", "required": false},
|
|
||||||
"description": {"type": "str", "required": false},
|
|
||||||
"category": {"type": "str", "required": false},
|
|
||||||
"version": {"type": "str", "required": false},
|
|
||||||
"enabled": {"type": "bool", "required": false},
|
|
||||||
"updated_at": {"type": "datetime", "required": true, "auto": "now"}
|
|
||||||
},
|
|
||||||
"filters": {
|
|
||||||
"id": {"type": "str", "required": true},
|
|
||||||
"user_id": {"type": "str", "required": true, "auto": "current_user_id"}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"delete": {
|
|
||||||
"url": "/harnessed_agent/remote_skills/{id}",
|
|
||||||
"method": "DELETE",
|
|
||||||
"filters": {
|
|
||||||
"id": {"type": "str", "required": true},
|
|
||||||
"user_id": {"type": "str", "required": true, "auto": "current_user_id"}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"list": {
|
|
||||||
"url": "/harnessed_agent/remote_skills",
|
|
||||||
"method": "GET",
|
|
||||||
"filters": {
|
|
||||||
"user_id": {"type": "str", "required": true, "auto": "current_user_id"},
|
|
||||||
"name": {"type": "str", "required": false},
|
|
||||||
"host": {"type": "str", "required": false},
|
|
||||||
"enabled": {"type": "bool", "required": false}
|
|
||||||
},
|
|
||||||
"orderby": "name ASC"
|
|
||||||
},
|
|
||||||
"deploy": {
|
|
||||||
"url": "/harnessed_agent/remote_skills/{id}/deploy",
|
|
||||||
"method": "POST",
|
|
||||||
"filters": {
|
|
||||||
"id": {"type": "str", "required": true},
|
|
||||||
"user_id": {"type": "str", "required": true, "auto": "current_user_id"}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"execute": {
|
|
||||||
"url": "/harnessed_agent/remote_skills/{id}/execute",
|
|
||||||
"method": "POST",
|
|
||||||
"fields": {
|
|
||||||
"parameters": {"type": "json", "required": false}
|
|
||||||
},
|
|
||||||
"filters": {
|
|
||||||
"id": {"type": "str", "required": true},
|
|
||||||
"user_id": {"type": "str", "required": true, "auto": "current_user_id"}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"list_remote": {
|
|
||||||
"url": "/harnessed_agent/remote_skills/{id}/list",
|
|
||||||
"method": "GET",
|
|
||||||
"filters": {
|
|
||||||
"id": {"type": "str", "required": true},
|
|
||||||
"user_id": {"type": "str", "required": true, "auto": "current_user_id"}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
},
|
||||||
|
"editexclouded": ["id", "user_id", "last_deployed", "last_executed", "last_connected", "created_at", "updated_at"]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,48 +1,22 @@
|
|||||||
{
|
{
|
||||||
"name": "hermes_sessions_crud",
|
"tblname": "hermes_sessions",
|
||||||
"table": "hermes_sessions",
|
"title": "Session Management",
|
||||||
"operations": {
|
"params": {
|
||||||
"create": {
|
"sortby": ["started_at desc"],
|
||||||
"method": "POST",
|
"logined_userid": "user_id",
|
||||||
"url": "/api/hermes/sessions",
|
"confidential_fields": [],
|
||||||
"description": "Create a new session record for current user"
|
"browserfields": {
|
||||||
},
|
"exclouded": ["id", "user_id", "metadata_json", "created_at", "updated_at"],
|
||||||
"read": {
|
"alters": {
|
||||||
"method": "GET",
|
"is_active": {
|
||||||
"url": "/api/hermes/sessions/{id}",
|
"uitype": "code",
|
||||||
"description": "Read a session by ID (user-isolated)"
|
"data": [
|
||||||
},
|
{"value": "1", "text": "Active"},
|
||||||
"update": {
|
{"value": "0", "text": "Inactive"}
|
||||||
"method": "PUT",
|
]
|
||||||
"url": "/api/hermes/sessions/{id}",
|
}
|
||||||
"description": "Update a session record (user-isolated)"
|
}
|
||||||
},
|
},
|
||||||
"delete": {
|
"editexclouded": ["id", "user_id", "created_at", "updated_at"]
|
||||||
"method": "DELETE",
|
|
||||||
"url": "/api/hermes/sessions/{id}",
|
|
||||||
"description": "Delete a session record (user-isolated)"
|
|
||||||
},
|
|
||||||
"list": {
|
|
||||||
"method": "GET",
|
|
||||||
"url": "/api/hermes/sessions",
|
|
||||||
"description": "List all sessions for current user with optional filtering"
|
|
||||||
},
|
|
||||||
"search": {
|
|
||||||
"method": "GET",
|
|
||||||
"url": "/api/hermes/sessions/search",
|
|
||||||
"description": "Search sessions by title, preview, or tags (user-isolated)"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"fields": {
|
|
||||||
"id": {"type": "str", "required": true},
|
|
||||||
"user_id": {"type": "str", "required": true, "auto": "current_user_id"},
|
|
||||||
"title": {"type": "str", "required": false},
|
|
||||||
"preview": {"type": "text", "required": false},
|
|
||||||
"started_at": {"type": "datetime", "required": true},
|
|
||||||
"ended_at": {"type": "datetime", "required": false},
|
|
||||||
"tags": {"type": "text", "required": false}
|
|
||||||
},
|
|
||||||
"filters": {
|
|
||||||
"user_id": {"auto": "current_user_id"}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,48 +1,22 @@
|
|||||||
{
|
{
|
||||||
"name": "hermes_skills_crud",
|
"tblname": "hermes_skills",
|
||||||
"table": "hermes_skills",
|
"title": "Skills Management",
|
||||||
"operations": {
|
"params": {
|
||||||
"create": {
|
"sortby": ["name"],
|
||||||
"method": "POST",
|
"logined_userid": "user_id",
|
||||||
"url": "/api/hermes/skills",
|
"confidential_fields": [],
|
||||||
"description": "Create a new skill for current user"
|
"browserfields": {
|
||||||
},
|
"exclouded": ["id", "user_id", "content", "created_at", "updated_at"],
|
||||||
"read": {
|
"alters": {
|
||||||
"method": "GET",
|
"is_active": {
|
||||||
"url": "/api/hermes/skills/{id}",
|
"uitype": "code",
|
||||||
"description": "Read a skill by ID (user-isolated)"
|
"data": [
|
||||||
},
|
{"value": "1", "text": "Active"},
|
||||||
"update": {
|
{"value": "0", "text": "Inactive"}
|
||||||
"method": "PUT",
|
]
|
||||||
"url": "/api/hermes/skills/{id}",
|
}
|
||||||
"description": "Update a skill (user-isolated)"
|
}
|
||||||
},
|
},
|
||||||
"delete": {
|
"editexclouded": ["id", "user_id", "created_at", "updated_at"]
|
||||||
"method": "DELETE",
|
|
||||||
"url": "/api/hermes/skills/{id}",
|
|
||||||
"description": "Delete a skill (user-isolated)"
|
|
||||||
},
|
|
||||||
"list": {
|
|
||||||
"method": "GET",
|
|
||||||
"url": "/api/hermes/skills",
|
|
||||||
"description": "List all skills for current user with optional filtering"
|
|
||||||
},
|
|
||||||
"search": {
|
|
||||||
"method": "GET",
|
|
||||||
"url": "/api/hermes/skills/search",
|
|
||||||
"description": "Search skills by name or description (user-isolated)"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"fields": {
|
|
||||||
"id": {"type": "str", "required": true},
|
|
||||||
"user_id": {"type": "str", "required": true, "auto": "current_user_id"},
|
|
||||||
"name": {"type": "str", "required": true},
|
|
||||||
"description": {"type": "text", "required": false},
|
|
||||||
"category": {"type": "str", "required": false},
|
|
||||||
"version": {"type": "str", "required": true},
|
|
||||||
"content": {"type": "text", "required": true}
|
|
||||||
},
|
|
||||||
"filters": {
|
|
||||||
"user_id": {"auto": "current_user_id"}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,54 +1,25 @@
|
|||||||
{
|
{
|
||||||
"name": "hermes_tasks_crud",
|
"tblname": "hermes_tasks",
|
||||||
"table": "hermes_tasks",
|
"title": "Task Management",
|
||||||
"operations": {
|
"params": {
|
||||||
"create": {
|
"sortby": ["order_index"],
|
||||||
"method": "POST",
|
"logined_userid": "user_id",
|
||||||
"url": "/api/hermes/tasks",
|
"confidential_fields": ["parameters_json"],
|
||||||
"description": "Create a new task definition for current user"
|
"browserfields": {
|
||||||
},
|
"exclouded": ["id", "user_id", "workflow_id", "parameters_json", "created_at", "updated_at"],
|
||||||
"read": {
|
"alters": {
|
||||||
"method": "GET",
|
"task_type": {
|
||||||
"url": "/api/hermes/tasks/{id}",
|
"uitype": "code",
|
||||||
"description": "Read a task by ID (user-isolated)"
|
"data": [
|
||||||
},
|
{"value": "skill", "text": "Skill Execution"},
|
||||||
"update": {
|
{"value": "tool", "text": "Tool Execution"},
|
||||||
"method": "PUT",
|
{"value": "memory", "text": "Memory Operation"},
|
||||||
"url": "/api/hermes/tasks/{id}",
|
{"value": "session_search", "text": "Session Search"},
|
||||||
"description": "Update a task definition (user-isolated)"
|
{"value": "custom", "text": "Custom Script"}
|
||||||
},
|
]
|
||||||
"delete": {
|
}
|
||||||
"method": "DELETE",
|
}
|
||||||
"url": "/api/hermes/tasks/{id}",
|
},
|
||||||
"description": "Delete a task definition (user-isolated)"
|
"editexclouded": ["id", "user_id", "workflow_id", "created_at", "updated_at"]
|
||||||
},
|
|
||||||
"list": {
|
|
||||||
"method": "GET",
|
|
||||||
"url": "/api/hermes/tasks",
|
|
||||||
"description": "List all tasks for current user with optional filtering"
|
|
||||||
},
|
|
||||||
"search": {
|
|
||||||
"method": "GET",
|
|
||||||
"url": "/api/hermes/tasks/search",
|
|
||||||
"description": "Search tasks by name or type (user-isolated)"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"fields": {
|
|
||||||
"id": {"type": "str", "required": true},
|
|
||||||
"user_id": {"type": "str", "required": true, "auto": "current_user_id"},
|
|
||||||
"workflow_id": {"type": "str", "required": true},
|
|
||||||
"task_name": {"type": "str", "required": true},
|
|
||||||
"task_type": {"type": "str", "required": true},
|
|
||||||
"skill_name": {"type": "str", "required": false},
|
|
||||||
"tool_name": {"type": "str", "required": false},
|
|
||||||
"parameters_json": {"type": "text", "required": false},
|
|
||||||
"depends_on": {"type": "str", "required": false},
|
|
||||||
"parallel_group": {"type": "str", "required": false},
|
|
||||||
"timeout_seconds": {"type": "int", "required": false, "default": 300},
|
|
||||||
"retry_count": {"type": "int", "required": false, "default": 2},
|
|
||||||
"order_index": {"type": "int", "required": false, "default": 0}
|
|
||||||
},
|
|
||||||
"filters": {
|
|
||||||
"user_id": {"auto": "current_user_id"}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,50 +1,45 @@
|
|||||||
{
|
{
|
||||||
"name": "hermes_workflows_crud",
|
"tblname": "hermes_workflows",
|
||||||
"table": "hermes_workflows",
|
"title": "Workflow Management",
|
||||||
"operations": {
|
"params": {
|
||||||
"create": {
|
"sortby": ["created_at desc"],
|
||||||
"method": "POST",
|
"logined_userid": "user_id",
|
||||||
"url": "/api/hermes/workflows",
|
"confidential_fields": [],
|
||||||
"description": "Create a new workflow definition for current user"
|
"browserfields": {
|
||||||
|
"exclouded": ["id", "user_id", "created_at", "updated_at"],
|
||||||
|
"alters": {
|
||||||
|
"workflow_type": {
|
||||||
|
"uitype": "code",
|
||||||
|
"data": [
|
||||||
|
{"value": "sequential", "text": "Sequential"},
|
||||||
|
{"value": "parallel", "text": "Parallel"},
|
||||||
|
{"value": "hybrid", "text": "Hybrid"}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
"read": {
|
"status": {
|
||||||
"method": "GET",
|
"uitype": "code",
|
||||||
"url": "/api/hermes/workflows/{id}",
|
"data": [
|
||||||
"description": "Read a workflow by ID (user-isolated)"
|
{"value": "active", "text": "Active"},
|
||||||
},
|
{"value": "inactive", "text": "Inactive"},
|
||||||
"update": {
|
{"value": "archived", "text": "Archived"}
|
||||||
"method": "PUT",
|
]
|
||||||
"url": "/api/hermes/workflows/{id}",
|
}
|
||||||
"description": "Update a workflow definition (user-isolated)"
|
}
|
||||||
},
|
},
|
||||||
"delete": {
|
"editexclouded": ["id", "user_id", "created_at", "updated_at"],
|
||||||
"method": "DELETE",
|
"subtables": [
|
||||||
"url": "/api/hermes/workflows/{id}",
|
{
|
||||||
"description": "Delete a workflow definition (user-isolated)"
|
"field": "id",
|
||||||
},
|
"title": "Tasks",
|
||||||
"list": {
|
"url": "{{entire_url(hermes_tasks_workflow)}}",
|
||||||
"method": "GET",
|
"subtable": "hermes_tasks"
|
||||||
"url": "/api/hermes/workflows",
|
},
|
||||||
"description": "List all workflows for current user with optional filtering"
|
{
|
||||||
},
|
"field": "id",
|
||||||
"search": {
|
"title": "Executions",
|
||||||
"method": "GET",
|
"url": "{{entire_url(hermes_executions_crud)}}",
|
||||||
"url": "/api/hermes/workflows/search",
|
"subtable": "hermes_executions"
|
||||||
"description": "Search workflows by name or description (user-isolated)"
|
}
|
||||||
}
|
]
|
||||||
},
|
|
||||||
"fields": {
|
|
||||||
"id": {"type": "str", "required": true},
|
|
||||||
"user_id": {"type": "str", "required": true, "auto": "current_user_id"},
|
|
||||||
"name": {"type": "str", "required": true},
|
|
||||||
"description": {"type": "text", "required": false},
|
|
||||||
"workflow_type": {"type": "str", "required": false, "default": "sequential"},
|
|
||||||
"max_concurrent_tasks": {"type": "int", "required": false, "default": 3},
|
|
||||||
"timeout_seconds": {"type": "int", "required": false, "default": 1800},
|
|
||||||
"retry_count": {"type": "int", "required": false, "default": 2},
|
|
||||||
"status": {"type": "str", "required": false, "default": "active"}
|
|
||||||
},
|
|
||||||
"filters": {
|
|
||||||
"user_id": {"auto": "current_user_id"}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -1,14 +0,0 @@
|
|||||||
{
|
|
||||||
"tblname":"memory",
|
|
||||||
"params":{
|
|
||||||
"title":"持久化记忆",
|
|
||||||
"description":"用户和系统持久化记忆存储",
|
|
||||||
"sortby":"created_at",
|
|
||||||
"logined_userid":"user_id",
|
|
||||||
"browserfields":{
|
|
||||||
"exclouded":["id", "user_id"],
|
|
||||||
"alters":{}
|
|
||||||
},
|
|
||||||
"editexclouded":["id", "user_id"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,14 +0,0 @@
|
|||||||
{
|
|
||||||
"tblname":"sessions",
|
|
||||||
"params":{
|
|
||||||
"title":"用户会话",
|
|
||||||
"description":"用户会话管理",
|
|
||||||
"sortby":"created_at",
|
|
||||||
"logined_userid":"user_id",
|
|
||||||
"browserfields":{
|
|
||||||
"exclouded":["id", "user_id"],
|
|
||||||
"alters":{}
|
|
||||||
},
|
|
||||||
"editexclouded":["id", "user_id"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,13 +0,0 @@
|
|||||||
{
|
|
||||||
"tblname":"skills",
|
|
||||||
"params":{
|
|
||||||
"title":"技能管理",
|
|
||||||
"description":"AI技能定义和管理",
|
|
||||||
"sortby":"name",
|
|
||||||
"browserfields":{
|
|
||||||
"exclouded":["id"],
|
|
||||||
"alters":{}
|
|
||||||
},
|
|
||||||
"editexclouded":["id"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -3,10 +3,10 @@
|
|||||||
"title": "Task Dependencies",
|
"title": "Task Dependencies",
|
||||||
"params": {
|
"params": {
|
||||||
"sortby": ["created_at desc"],
|
"sortby": ["created_at desc"],
|
||||||
"logined_userorgid": "user_id",
|
"logined_userid": "user_id",
|
||||||
"confidential_fields": [],
|
"confidential_fields": [],
|
||||||
"browserfields": {
|
"browserfields": {
|
||||||
"exclouded": ["id", "user_id", "workflow_id"],
|
"exclouded": ["id", "user_id", "workflow_id", "created_at", "updated_at"],
|
||||||
"alters": {
|
"alters": {
|
||||||
"dependency_type": {
|
"dependency_type": {
|
||||||
"uitype": "code",
|
"uitype": "code",
|
||||||
|
|||||||
@ -1,46 +0,0 @@
|
|||||||
{
|
|
||||||
"tblname": "tasks",
|
|
||||||
"title": "Task Management",
|
|
||||||
"params": {
|
|
||||||
"sortby": ["execution_order asc"],
|
|
||||||
"logined_userorgid": "user_id",
|
|
||||||
"confidential_fields": [],
|
|
||||||
"browserfields": {
|
|
||||||
"exclouded": ["id", "user_id", "workflow_id", "task_config"],
|
|
||||||
"alters": {
|
|
||||||
"task_type": {
|
|
||||||
"uitype": "code",
|
|
||||||
"data": [
|
|
||||||
{"value": "skill", "text": "Skill Execution"},
|
|
||||||
{"value": "api_call", "text": "API Call"},
|
|
||||||
{"value": "subprocess", "text": "Subprocess"},
|
|
||||||
{"value": "custom_function", "text": "Custom Function"},
|
|
||||||
{"value": "conditional", "text": "Conditional Branch"}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"enabled": {
|
|
||||||
"uitype": "code",
|
|
||||||
"data": [
|
|
||||||
{"value": "Y", "text": "Enabled"},
|
|
||||||
{"value": "N", "text": "Disabled"}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"editexclouded": ["id", "user_id", "workflow_id", "created_at", "updated_at"],
|
|
||||||
"subtables": [
|
|
||||||
{
|
|
||||||
"field": "id",
|
|
||||||
"title": "Dependencies (Dependent)",
|
|
||||||
"url": "{{entire_url('dependencies_by_dependent')}}",
|
|
||||||
"subtable": "task_dependencies"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"field": "id",
|
|
||||||
"title": "Dependencies (Dependency)",
|
|
||||||
"url": "{{entire_url('dependencies_by_dependency')}}",
|
|
||||||
"subtable": "task_dependencies"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,33 +0,0 @@
|
|||||||
{
|
|
||||||
"tblname": "tasks",
|
|
||||||
"alias": "tasks_by_workflow",
|
|
||||||
"title": "Workflow Tasks",
|
|
||||||
"params": {
|
|
||||||
"sortby": ["execution_order asc"],
|
|
||||||
"logined_userorgid": "user_id",
|
|
||||||
"confidential_fields": [],
|
|
||||||
"browserfields": {
|
|
||||||
"exclouded": ["id", "user_id", "workflow_id", "task_config"],
|
|
||||||
"alters": {
|
|
||||||
"task_type": {
|
|
||||||
"uitype": "code",
|
|
||||||
"data": [
|
|
||||||
{"value": "skill", "text": "Skill Execution"},
|
|
||||||
{"value": "api_call", "text": "API Call"},
|
|
||||||
{"value": "subprocess", "text": "Subprocess"},
|
|
||||||
{"value": "custom_function", "text": "Custom Function"},
|
|
||||||
{"value": "conditional", "text": "Conditional Branch"}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"enabled": {
|
|
||||||
"uitype": "code",
|
|
||||||
"data": [
|
|
||||||
{"value": "Y", "text": "Enabled"},
|
|
||||||
{"value": "N", "text": "Disabled"}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"editexclouded": ["id", "user_id", "workflow_id", "created_at", "updated_at"]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,44 +0,0 @@
|
|||||||
{
|
|
||||||
"tblname": "workflows",
|
|
||||||
"title": "Workflow Management",
|
|
||||||
"params": {
|
|
||||||
"sortby": ["created_at desc"],
|
|
||||||
"logined_userorgid": "user_id",
|
|
||||||
"confidential_fields": [],
|
|
||||||
"browserfields": {
|
|
||||||
"exclouded": ["id", "user_id", "retry_policy"],
|
|
||||||
"alters": {
|
|
||||||
"workflow_type": {
|
|
||||||
"uitype": "code",
|
|
||||||
"data": [
|
|
||||||
{"value": "sequential", "text": "Sequential"},
|
|
||||||
{"value": "parallel", "text": "Parallel"},
|
|
||||||
{"value": "hybrid", "text": "Hybrid"}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"enabled": {
|
|
||||||
"uitype": "code",
|
|
||||||
"data": [
|
|
||||||
{"value": "Y", "text": "Enabled"},
|
|
||||||
{"value": "N", "text": "Disabled"}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"editexclouded": ["id", "user_id", "created_at", "updated_at"],
|
|
||||||
"subtables": [
|
|
||||||
{
|
|
||||||
"field": "id",
|
|
||||||
"title": "Tasks",
|
|
||||||
"url": "{{entire_url('tasks_by_workflow')}}",
|
|
||||||
"subtable": "tasks"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"field": "id",
|
|
||||||
"title": "Executions",
|
|
||||||
"url": "{{entire_url('executions_by_workflow')}}",
|
|
||||||
"subtable": "executions"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,7 +1,7 @@
|
|||||||
{
|
{
|
||||||
"summary": [
|
"summary": [
|
||||||
{
|
{
|
||||||
"name": "hermes_remote_skills",
|
"name": "harnessed_remote_skills",
|
||||||
"title": "Remote skills SSH configuration with user isolation",
|
"title": "Remote skills SSH configuration with user isolation",
|
||||||
"primary": "id",
|
"primary": "id",
|
||||||
"catelog": "entity"
|
"catelog": "entity"
|
||||||
@ -24,6 +24,14 @@
|
|||||||
"nullable": "no",
|
"nullable": "no",
|
||||||
"comments": "User who owns this remote skill configuration"
|
"comments": "User who owns this remote skill configuration"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "name",
|
||||||
|
"title": "Skill Name",
|
||||||
|
"type": "str",
|
||||||
|
"length": 100,
|
||||||
|
"nullable": "no",
|
||||||
|
"comments": "Remote skill name"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "host",
|
"name": "host",
|
||||||
"title": "SSH Host",
|
"title": "SSH Host",
|
||||||
@ -48,6 +56,15 @@
|
|||||||
"nullable": "no",
|
"nullable": "no",
|
||||||
"comments": "SSH username"
|
"comments": "SSH username"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "remote_path",
|
||||||
|
"title": "Remote Path",
|
||||||
|
"type": "str",
|
||||||
|
"length": 255,
|
||||||
|
"nullable": "no",
|
||||||
|
"default": "~/.skills",
|
||||||
|
"comments": "Remote skills directory path"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "auth_method",
|
"name": "auth_method",
|
||||||
"title": "Authentication Method",
|
"title": "Authentication Method",
|
||||||
@ -70,15 +87,47 @@
|
|||||||
"title": "Description",
|
"title": "Description",
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"nullable": "yes",
|
"nullable": "yes",
|
||||||
"comments": "Description of the remote host"
|
"comments": "Description of the remote skill"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "is_active",
|
"name": "category",
|
||||||
"title": "Is Active",
|
"title": "Category",
|
||||||
"type": "short",
|
"type": "str",
|
||||||
|
"length": 50,
|
||||||
|
"nullable": "yes",
|
||||||
|
"comments": "Skill category"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "version",
|
||||||
|
"title": "Version",
|
||||||
|
"type": "str",
|
||||||
|
"length": 20,
|
||||||
|
"nullable": "no",
|
||||||
|
"default": "1.0.0",
|
||||||
|
"comments": "Skill version"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "enabled",
|
||||||
|
"title": "Enabled",
|
||||||
|
"type": "str",
|
||||||
|
"length": 1,
|
||||||
"nullable": "no",
|
"nullable": "no",
|
||||||
"default": "1",
|
"default": "1",
|
||||||
"comments": "Whether configuration is active (1=true, 0=false)"
|
"comments": "Whether skill is enabled (1=true, 0=false)"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "last_deployed",
|
||||||
|
"title": "Last Deployed",
|
||||||
|
"type": "timestamp",
|
||||||
|
"nullable": "yes",
|
||||||
|
"comments": "Last deployment timestamp"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "last_executed",
|
||||||
|
"title": "Last Executed",
|
||||||
|
"type": "timestamp",
|
||||||
|
"nullable": "yes",
|
||||||
|
"comments": "Last execution timestamp"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "last_connected",
|
"name": "last_connected",
|
||||||
@ -104,19 +153,19 @@
|
|||||||
],
|
],
|
||||||
"indexes": [
|
"indexes": [
|
||||||
{
|
{
|
||||||
"name": "idx_hermes_remote_skills_user",
|
"name": "idx_remote_skills_user",
|
||||||
"idxtype": "index",
|
"idxtype": "index",
|
||||||
"idxfields": ["user_id", "host"]
|
"idxfields": ["user_id"]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "idx_hermes_remote_skills_host",
|
"name": "idx_remote_skills_user_name",
|
||||||
"idxtype": "unique",
|
"idxtype": "unique",
|
||||||
"idxfields": ["user_id", "host", "port", "username"]
|
"idxfields": ["user_id", "name"]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "idx_hermes_remote_skills_active",
|
"name": "idx_remote_skills_host",
|
||||||
"idxtype": "index",
|
"idxtype": "index",
|
||||||
"idxfields": ["is_active"]
|
"idxfields": ["host"]
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"codes": []
|
"codes": []
|
||||||
|
|||||||
@ -25,7 +25,7 @@
|
|||||||
"comments": "User who owns this session"
|
"comments": "User who owns this session"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "session_title",
|
"name": "title",
|
||||||
"title": "Session Title",
|
"title": "Session Title",
|
||||||
"type": "str",
|
"type": "str",
|
||||||
"length": 200,
|
"length": 200,
|
||||||
@ -33,14 +33,28 @@
|
|||||||
"comments": "Human-readable session title"
|
"comments": "Human-readable session title"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "start_time",
|
"name": "preview",
|
||||||
|
"title": "Preview",
|
||||||
|
"type": "text",
|
||||||
|
"nullable": "yes",
|
||||||
|
"comments": "Session content preview for search"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "tags",
|
||||||
|
"title": "Tags",
|
||||||
|
"type": "text",
|
||||||
|
"nullable": "yes",
|
||||||
|
"comments": "Comma-separated session tags"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "started_at",
|
||||||
"title": "Start Time",
|
"title": "Start Time",
|
||||||
"type": "timestamp",
|
"type": "timestamp",
|
||||||
"nullable": "no",
|
"nullable": "no",
|
||||||
"comments": "Session start timestamp"
|
"comments": "Session start timestamp"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "end_time",
|
"name": "ended_at",
|
||||||
"title": "End Time",
|
"title": "End Time",
|
||||||
"type": "timestamp",
|
"type": "timestamp",
|
||||||
"nullable": "yes",
|
"nullable": "yes",
|
||||||
@ -49,13 +63,14 @@
|
|||||||
{
|
{
|
||||||
"name": "is_active",
|
"name": "is_active",
|
||||||
"title": "Is Active",
|
"title": "Is Active",
|
||||||
"type": "short",
|
"type": "str",
|
||||||
|
"length": 1,
|
||||||
"nullable": "no",
|
"nullable": "no",
|
||||||
"default": "1",
|
"default": "1",
|
||||||
"comments": "Whether session is active (1=true, 0=false)"
|
"comments": "Whether session is active (1=true, 0=false)"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "metadata",
|
"name": "metadata_json",
|
||||||
"title": "Metadata",
|
"title": "Metadata",
|
||||||
"type": "text",
|
"type": "text",
|
||||||
"nullable": "yes",
|
"nullable": "yes",
|
||||||
@ -80,17 +95,12 @@
|
|||||||
{
|
{
|
||||||
"name": "idx_hermes_sessions_user",
|
"name": "idx_hermes_sessions_user",
|
||||||
"idxtype": "index",
|
"idxtype": "index",
|
||||||
"idxfields": ["user_id", "start_time"]
|
"idxfields": ["user_id", "started_at"]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "idx_hermes_sessions_active",
|
"name": "idx_hermes_sessions_active",
|
||||||
"idxtype": "index",
|
"idxtype": "index",
|
||||||
"idxfields": ["user_id", "is_active"]
|
"idxfields": ["user_id", "is_active"]
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "idx_hermes_sessions_time",
|
|
||||||
"idxtype": "index",
|
|
||||||
"idxfields": ["start_time", "end_time"]
|
|
||||||
}
|
}
|
||||||
],
|
],
|
||||||
"codes": []
|
"codes": []
|
||||||
|
|||||||
@ -54,10 +54,20 @@
|
|||||||
"nullable": "yes",
|
"nullable": "yes",
|
||||||
"comments": "Skill category"
|
"comments": "Skill category"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "version",
|
||||||
|
"title": "Version",
|
||||||
|
"type": "str",
|
||||||
|
"length": 20,
|
||||||
|
"nullable": "no",
|
||||||
|
"default": "1.0.0",
|
||||||
|
"comments": "Skill version"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "is_active",
|
"name": "is_active",
|
||||||
"title": "Is Active",
|
"title": "Is Active",
|
||||||
"type": "short",
|
"type": "str",
|
||||||
|
"length": 1,
|
||||||
"nullable": "no",
|
"nullable": "no",
|
||||||
"default": "1",
|
"default": "1",
|
||||||
"comments": "Whether skill is active (1=true, 0=false)"
|
"comments": "Whether skill is active (1=true, 0=false)"
|
||||||
|
|||||||
@ -1,3 +1,25 @@
|
|||||||
[build-system]
|
[build-system]
|
||||||
requires = ["setuptools>=61", "wheel"]
|
requires = ["setuptools>=61", "wheel"]
|
||||||
build-backend = "setuptools.build_meta"
|
build-backend = "setuptools.build_meta"
|
||||||
|
|
||||||
|
[project]
|
||||||
|
name = "harnessed-agent"
|
||||||
|
version = "1.0.0"
|
||||||
|
description = "Hermes Agent module - multi-user AI agent with memory, skills, workflows, and remote skill deployment"
|
||||||
|
requires-python = ">=3.10"
|
||||||
|
dependencies = [
|
||||||
|
"ahserver",
|
||||||
|
"sqlor",
|
||||||
|
"apppublic",
|
||||||
|
"appbase",
|
||||||
|
"rbac",
|
||||||
|
]
|
||||||
|
|
||||||
|
[project.optional-dependencies]
|
||||||
|
dev = [
|
||||||
|
"pytest",
|
||||||
|
"pytest-asyncio",
|
||||||
|
]
|
||||||
|
|
||||||
|
[tool.setuptools.packages.find]
|
||||||
|
include = ["harnessed_agent*"]
|
||||||
|
|||||||
@ -1,37 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
"""
|
|
||||||
Test script to verify harnessed_agent module with llmage integration
|
|
||||||
"""
|
|
||||||
|
|
||||||
import sys
|
|
||||||
import os
|
|
||||||
|
|
||||||
# Add the harnessed_agent directory to Python path
|
|
||||||
sys.path.insert(0, os.path.expanduser('~/repos/harnessed_agent'))
|
|
||||||
|
|
||||||
try:
|
|
||||||
from harnessed_agent import HermesAgent
|
|
||||||
print("✓ harnessed_agent module imported successfully")
|
|
||||||
print(f" Version: {HermesAgent.__module__}")
|
|
||||||
except ImportError as e:
|
|
||||||
print(f"✗ Failed to import harnessed_agent: {e}")
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
try:
|
|
||||||
from harnessed_agent.session_manager import SessionManager
|
|
||||||
from harnessed_agent.skill_manager import SkillManager
|
|
||||||
from harnessed_agent.memory_manager import MemoryManager
|
|
||||||
print("✓ All submodules imported successfully")
|
|
||||||
except ImportError as e:
|
|
||||||
print(f"✗ Failed to import submodules: {e}")
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
# Test llmage integration method exists
|
|
||||||
agent = HermesAgent()
|
|
||||||
if hasattr(agent, '_call_llmage_inference'):
|
|
||||||
print("✓ llmage integration method found")
|
|
||||||
else:
|
|
||||||
print("✗ llmage integration method missing")
|
|
||||||
sys.exit(1)
|
|
||||||
|
|
||||||
print("✓ Hermes Agent module with llmage integration is valid")
|
|
||||||
@ -1,61 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
"""
|
|
||||||
Test script to verify the security fix for skill content validation.
|
|
||||||
"""
|
|
||||||
|
|
||||||
import asyncio
|
|
||||||
import sys
|
|
||||||
import os
|
|
||||||
|
|
||||||
# Add the harnessed_agent module to the path
|
|
||||||
sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'harnessed_agent'))
|
|
||||||
|
|
||||||
from core import HermesAgent
|
|
||||||
|
|
||||||
async def test_security_fix():
|
|
||||||
"""Test that malicious skill content is rejected."""
|
|
||||||
agent = HermesAgent()
|
|
||||||
|
|
||||||
# Test context with user_id
|
|
||||||
context = {"user_id": "test_user"}
|
|
||||||
|
|
||||||
# Test 1: Valid skill content should be accepted
|
|
||||||
valid_content = """
|
|
||||||
name: test-skill
|
|
||||||
description: A valid test skill
|
|
||||||
version: 1.0.0
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- Use terminal to run echo "hello"
|
|
||||||
- Return success
|
|
||||||
"""
|
|
||||||
|
|
||||||
result = await agent.manage_skills("create", "valid-skill", context=context, content=valid_content)
|
|
||||||
print(f"Valid skill creation result: {result}")
|
|
||||||
assert result["success"] == True, "Valid skill should be accepted"
|
|
||||||
|
|
||||||
# Test 2: Malicious skill content with dangerous commands should be rejected
|
|
||||||
malicious_content = """
|
|
||||||
name: malicious-skill
|
|
||||||
description: A malicious skill
|
|
||||||
version: 1.0.0
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- Use terminal to run rm -rf / # This should be blocked
|
|
||||||
- Use terminal to run cat /etc/passwd # This should be blocked
|
|
||||||
"""
|
|
||||||
|
|
||||||
result = await agent.manage_skills("create", "malicious-skill", context=context, content=malicious_content)
|
|
||||||
print(f"Malicious skill creation result: {result}")
|
|
||||||
assert result["success"] == False, "Malicious skill should be rejected"
|
|
||||||
assert "Invalid skill content" in result.get("error", ""), "Should return validation error"
|
|
||||||
|
|
||||||
# Test 3: Empty content should be rejected
|
|
||||||
result = await agent.manage_skills("create", "empty-skill", context=context, content="")
|
|
||||||
print(f"Empty skill creation result: {result}")
|
|
||||||
assert result["success"] == False, "Empty skill should be rejected"
|
|
||||||
|
|
||||||
print("All security tests passed!")
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
asyncio.run(test_security_fix())
|
|
||||||
@ -1,103 +0,0 @@
|
|||||||
#!/usr/bin/env python3
|
|
||||||
"""
|
|
||||||
Test script to verify the security fix for skill content validation.
|
|
||||||
This test only tests the validation method directly, without database dependencies.
|
|
||||||
"""
|
|
||||||
|
|
||||||
import sys
|
|
||||||
import os
|
|
||||||
|
|
||||||
# Add the harnessed_agent module to the path
|
|
||||||
sys.path.insert(0, os.path.join(os.path.dirname(__file__), 'harnessed_agent'))
|
|
||||||
|
|
||||||
from core import HermesAgent
|
|
||||||
|
|
||||||
def test_security_fix():
|
|
||||||
"""Test that malicious skill content is rejected by the validation method."""
|
|
||||||
agent = HermesAgent()
|
|
||||||
|
|
||||||
# Test 1: Valid skill content should be accepted
|
|
||||||
valid_content = """
|
|
||||||
name: test-skill
|
|
||||||
description: A valid test skill
|
|
||||||
version: 1.0.0
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- Use terminal to run echo "hello"
|
|
||||||
- Return success
|
|
||||||
"""
|
|
||||||
|
|
||||||
result = agent._validate_skill_content(valid_content)
|
|
||||||
print(f"Valid skill validation result: {result}")
|
|
||||||
assert result == True, "Valid skill should be accepted"
|
|
||||||
|
|
||||||
# Test 2: Malicious skill content with dangerous commands should be rejected
|
|
||||||
malicious_content = """
|
|
||||||
name: malicious-skill
|
|
||||||
description: A malicious skill
|
|
||||||
version: 1.0.0
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- Use terminal to run rm -rf / # This should be blocked
|
|
||||||
- Use terminal to run cat /etc/passwd # This should be blocked
|
|
||||||
"""
|
|
||||||
|
|
||||||
result = agent._validate_skill_content(malicious_content)
|
|
||||||
print(f"Malicious skill validation result: {result}")
|
|
||||||
assert result == False, "Malicious skill should be rejected"
|
|
||||||
|
|
||||||
# Test 3: Empty content should be rejected
|
|
||||||
result = agent._validate_skill_content("")
|
|
||||||
print(f"Empty skill validation result: {result}")
|
|
||||||
assert result == False, "Empty skill should be rejected"
|
|
||||||
|
|
||||||
# Test 4: Content with dangerous patterns should be rejected
|
|
||||||
dangerous_patterns = [
|
|
||||||
"rm -rf /",
|
|
||||||
"cat /etc/passwd",
|
|
||||||
"wget http://malicious.com",
|
|
||||||
"curl http://attacker.com",
|
|
||||||
"sudo ",
|
|
||||||
"chmod 777",
|
|
||||||
"dd if=/dev/zero"
|
|
||||||
]
|
|
||||||
|
|
||||||
for pattern in dangerous_patterns:
|
|
||||||
dangerous_content = f"""
|
|
||||||
name: dangerous-skill
|
|
||||||
description: A dangerous skill
|
|
||||||
version: 1.0.0
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- Use terminal to run {pattern}
|
|
||||||
"""
|
|
||||||
result = agent._validate_skill_content(dangerous_content)
|
|
||||||
print(f"Dangerous pattern '{pattern}' validation result: {result}")
|
|
||||||
assert result == False, f"Dangerous pattern '{pattern}' should be rejected"
|
|
||||||
|
|
||||||
# Test 5: Safe content should be accepted
|
|
||||||
safe_patterns = [
|
|
||||||
"echo hello",
|
|
||||||
"ls -la",
|
|
||||||
"pwd",
|
|
||||||
"date",
|
|
||||||
"whoami"
|
|
||||||
]
|
|
||||||
|
|
||||||
for pattern in safe_patterns:
|
|
||||||
safe_content = f"""
|
|
||||||
name: safe-skill
|
|
||||||
description: A safe skill
|
|
||||||
version: 1.0.0
|
|
||||||
|
|
||||||
steps:
|
|
||||||
- Use terminal to run {pattern}
|
|
||||||
"""
|
|
||||||
result = agent._validate_skill_content(safe_content)
|
|
||||||
print(f"Safe pattern '{pattern}' validation result: {result}")
|
|
||||||
assert result == True, f"Safe pattern '{pattern}' should be accepted"
|
|
||||||
|
|
||||||
print("All security tests passed!")
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
|
||||||
test_security_fix()
|
|
||||||
@ -1,15 +1,38 @@
|
|||||||
{
|
{
|
||||||
"widgettype": "Dialog",
|
"widgettype": "VBox",
|
||||||
"options": {
|
"options": {
|
||||||
"title": "Deploy Remote Skill",
|
"width": "100%",
|
||||||
"width": "600px",
|
"height": "100%",
|
||||||
"height": "400px"
|
"css": "ios-scroll-area"
|
||||||
|
},
|
||||||
|
"subwidgets": [
|
||||||
|
{
|
||||||
|
"widgettype": "Toolbar",
|
||||||
|
"options": {
|
||||||
|
"css": "ios-navbar",
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
|
"text": "Deploy Skill",
|
||||||
|
"icon": "upload-cloud",
|
||||||
|
"css": "ios-navbar-title",
|
||||||
|
"disabled": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"widgettype": "VBox",
|
||||||
|
"options": {
|
||||||
|
"css": "ios-card",
|
||||||
|
"width": "100%",
|
||||||
|
"padding": "16px"
|
||||||
},
|
},
|
||||||
"subwidgets": [
|
"subwidgets": [
|
||||||
{
|
{
|
||||||
"widgettype": "Form",
|
"widgettype": "Form",
|
||||||
"id": "deploy_form",
|
"id": "deploy_form",
|
||||||
"options": {
|
"options": {
|
||||||
|
"css": "ios-group",
|
||||||
"fields": [
|
"fields": [
|
||||||
{"name": "skill_id", "label": "Skill ID", "readonly": true, "hidden": true},
|
{"name": "skill_id", "label": "Skill ID", "readonly": true, "hidden": true},
|
||||||
{"name": "skill_content", "label": "Skill Content (SKILL.md)", "type": "textarea", "height": "250px", "required": true}
|
{"name": "skill_content", "label": "Skill Content (SKILL.md)", "type": "textarea", "height": "250px", "required": true}
|
||||||
@ -23,12 +46,14 @@
|
|||||||
{
|
{
|
||||||
"id": "deploy_submit",
|
"id": "deploy_submit",
|
||||||
"text": "Deploy",
|
"text": "Deploy",
|
||||||
"icon": "upload-cloud"
|
"icon": "upload-cloud",
|
||||||
|
"css": "ios-btn"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "deploy_cancel",
|
"id": "deploy_cancel",
|
||||||
"text": "Cancel",
|
"text": "Cancel",
|
||||||
"icon": "x"
|
"icon": "x",
|
||||||
|
"css": "ios-btn ios-btn-secondary"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@ -59,9 +84,12 @@
|
|||||||
"options": {
|
"options": {
|
||||||
"text": "",
|
"text": "",
|
||||||
"height": "60px",
|
"height": "60px",
|
||||||
"overflow": "auto"
|
"overflow": "auto",
|
||||||
|
"css": "ios-card-subtitle"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
],
|
],
|
||||||
"binds": [
|
"binds": [
|
||||||
{
|
{
|
||||||
|
|||||||
@ -1,15 +1,38 @@
|
|||||||
{
|
{
|
||||||
"widgettype": "Dialog",
|
"widgettype": "VBox",
|
||||||
"options": {
|
"options": {
|
||||||
"title": "Execute Remote Skill",
|
"width": "100%",
|
||||||
"width": "600px",
|
"height": "100%",
|
||||||
"height": "400px"
|
"css": "ios-scroll-area"
|
||||||
|
},
|
||||||
|
"subwidgets": [
|
||||||
|
{
|
||||||
|
"widgettype": "Toolbar",
|
||||||
|
"options": {
|
||||||
|
"css": "ios-navbar",
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
|
"text": "Execute Skill",
|
||||||
|
"icon": "play",
|
||||||
|
"css": "ios-navbar-title",
|
||||||
|
"disabled": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"widgettype": "VBox",
|
||||||
|
"options": {
|
||||||
|
"css": "ios-card",
|
||||||
|
"width": "100%",
|
||||||
|
"padding": "16px"
|
||||||
},
|
},
|
||||||
"subwidgets": [
|
"subwidgets": [
|
||||||
{
|
{
|
||||||
"widgettype": "Form",
|
"widgettype": "Form",
|
||||||
"id": "execute_form",
|
"id": "execute_form",
|
||||||
"options": {
|
"options": {
|
||||||
|
"css": "ios-group",
|
||||||
"fields": [
|
"fields": [
|
||||||
{"name": "skill_id", "label": "Skill ID", "readonly": true, "hidden": true},
|
{"name": "skill_id", "label": "Skill ID", "readonly": true, "hidden": true},
|
||||||
{"name": "parameters", "label": "Parameters (JSON)", "type": "textarea", "height": "250px", "default": "{}"}
|
{"name": "parameters", "label": "Parameters (JSON)", "type": "textarea", "height": "250px", "default": "{}"}
|
||||||
@ -23,12 +46,14 @@
|
|||||||
{
|
{
|
||||||
"id": "execute_submit",
|
"id": "execute_submit",
|
||||||
"text": "Execute",
|
"text": "Execute",
|
||||||
"icon": "play"
|
"icon": "play",
|
||||||
|
"css": "ios-btn"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"id": "execute_cancel",
|
"id": "execute_cancel",
|
||||||
"text": "Cancel",
|
"text": "Cancel",
|
||||||
"icon": "x"
|
"icon": "x",
|
||||||
|
"css": "ios-btn ios-btn-secondary"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
@ -59,9 +84,12 @@
|
|||||||
"options": {
|
"options": {
|
||||||
"text": "",
|
"text": "",
|
||||||
"height": "60px",
|
"height": "60px",
|
||||||
"overflow": "auto"
|
"overflow": "auto",
|
||||||
|
"css": "ios-card-subtitle"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
],
|
],
|
||||||
"binds": [
|
"binds": [
|
||||||
{
|
{
|
||||||
|
|||||||
@ -2,25 +2,53 @@
|
|||||||
"widgettype": "VBox",
|
"widgettype": "VBox",
|
||||||
"options": {
|
"options": {
|
||||||
"width": "100%",
|
"width": "100%",
|
||||||
"height": "100%"
|
"height": "100%",
|
||||||
|
"css": ""
|
||||||
},
|
},
|
||||||
"subwidgets": [
|
"subwidgets": [
|
||||||
{
|
{
|
||||||
"widgettype": "Toolbar",
|
"widgettype": "HBox",
|
||||||
"options": {
|
"options": {
|
||||||
"items": [
|
"css": "ios-navbar",
|
||||||
|
"width": "100%",
|
||||||
|
"height": "auto",
|
||||||
|
"spacing": 8,
|
||||||
|
"padding": "8px 16px"
|
||||||
|
},
|
||||||
|
"subwidgets": [
|
||||||
{
|
{
|
||||||
|
"widgettype": "VBox",
|
||||||
|
"options": {
|
||||||
|
"width": "100%",
|
||||||
|
"spacing": 2
|
||||||
|
},
|
||||||
|
"subwidgets": [
|
||||||
|
{
|
||||||
|
"widgettype": "Label",
|
||||||
|
"options": {
|
||||||
"text": "Hermes Agent",
|
"text": "Hermes Agent",
|
||||||
"icon": "robot",
|
"css": "ios-navbar-title"
|
||||||
"disabled": true
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"text": "${current_user_id}$",
|
"widgettype": "Label",
|
||||||
"icon": "user",
|
"options": {
|
||||||
"id": "current_user_display"
|
"text": "Agent Dashboard",
|
||||||
|
"css": "ios-navbar-subtitle"
|
||||||
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"widgettype": "Label",
|
||||||
|
"options": {
|
||||||
|
"text": "${current_user_id}$",
|
||||||
|
"id": "current_user_display",
|
||||||
|
"css": "ios-navbar-subtitle",
|
||||||
|
"width": "auto"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
],
|
||||||
"binds": [
|
"binds": [
|
||||||
{
|
{
|
||||||
"wid": "self",
|
"wid": "self",
|
||||||
@ -34,80 +62,223 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"widgettype": "Tab",
|
"widgettype": "VBox",
|
||||||
"options": {
|
"options": {
|
||||||
"tabs": [
|
"css": "ios-stat-card",
|
||||||
{
|
"width": "calc(100% - 32px)",
|
||||||
"title": "Memory",
|
"height": "auto",
|
||||||
"icon": "memory"
|
"margin": "12px 16px",
|
||||||
},
|
"padding": "20px",
|
||||||
{
|
"spacing": 4
|
||||||
"title": "Local Skills",
|
|
||||||
"icon": "code"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"title": "Remote Skills",
|
|
||||||
"icon": "cloud"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"title": "Workflows",
|
|
||||||
"icon": "workflow"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"title": "Tasks",
|
|
||||||
"icon": "tasks"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"title": "Sessions",
|
|
||||||
"icon": "history"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"title": "Tools",
|
|
||||||
"icon": "tools"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
},
|
||||||
"subwidgets": [
|
"subwidgets": [
|
||||||
{
|
{
|
||||||
|
"widgettype": "HBox",
|
||||||
|
"options": {
|
||||||
|
"width": "100%",
|
||||||
|
"spacing": 16
|
||||||
|
},
|
||||||
|
"subwidgets": [
|
||||||
|
{
|
||||||
|
"widgettype": "VBox",
|
||||||
|
"options": {
|
||||||
|
"width": "50%",
|
||||||
|
"spacing": 2
|
||||||
|
},
|
||||||
|
"subwidgets": [
|
||||||
|
{
|
||||||
|
"widgettype": "Label",
|
||||||
|
"options": {
|
||||||
|
"text": "Status",
|
||||||
|
"css": "ios-stat-label"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"widgettype": "Label",
|
||||||
|
"options": {
|
||||||
|
"text": "Active",
|
||||||
|
"css": "ios-stat-value"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"widgettype": "VBox",
|
||||||
|
"options": {
|
||||||
|
"width": "50%",
|
||||||
|
"spacing": 2
|
||||||
|
},
|
||||||
|
"subwidgets": [
|
||||||
|
{
|
||||||
|
"widgettype": "Label",
|
||||||
|
"options": {
|
||||||
|
"text": "Skills",
|
||||||
|
"css": "ios-stat-label"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"widgettype": "Label",
|
||||||
|
"options": {
|
||||||
|
"text": "${skills_count}$",
|
||||||
|
"css": "ios-stat-value"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"widgettype": "HBox",
|
||||||
|
"options": {
|
||||||
|
"width": "100%",
|
||||||
|
"spacing": 16,
|
||||||
|
"margin-top": "8px"
|
||||||
|
},
|
||||||
|
"subwidgets": [
|
||||||
|
{
|
||||||
|
"widgettype": "VBox",
|
||||||
|
"options": {
|
||||||
|
"width": "50%",
|
||||||
|
"spacing": 2
|
||||||
|
},
|
||||||
|
"subwidgets": [
|
||||||
|
{
|
||||||
|
"widgettype": "Label",
|
||||||
|
"options": {
|
||||||
|
"text": "Tasks",
|
||||||
|
"css": "ios-stat-label"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"widgettype": "Label",
|
||||||
|
"options": {
|
||||||
|
"text": "${tasks_count}$",
|
||||||
|
"css": "ios-stat-value"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"widgettype": "VBox",
|
||||||
|
"options": {
|
||||||
|
"width": "50%",
|
||||||
|
"spacing": 2
|
||||||
|
},
|
||||||
|
"subwidgets": [
|
||||||
|
{
|
||||||
|
"widgettype": "Label",
|
||||||
|
"options": {
|
||||||
|
"text": "Sessions",
|
||||||
|
"css": "ios-stat-label"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"widgettype": "Label",
|
||||||
|
"options": {
|
||||||
|
"text": "${sessions_count}$",
|
||||||
|
"css": "ios-stat-value"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"widgettype": "VBox",
|
||||||
|
"options": {
|
||||||
|
"css": "ios-scroll-area",
|
||||||
|
"width": "100%",
|
||||||
|
"height": "100%"
|
||||||
|
},
|
||||||
|
"subwidgets": [
|
||||||
|
{
|
||||||
|
"widgettype": "TabPanel",
|
||||||
|
"options": {
|
||||||
|
"width": "100%",
|
||||||
|
"height": "100%",
|
||||||
|
"tab_pos": "bottom",
|
||||||
|
"css": "ios-tabbar",
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
|
"name": "memory",
|
||||||
|
"label": "Memory",
|
||||||
|
"icon": "memory",
|
||||||
|
"content": {
|
||||||
"widgettype": "urlwidget",
|
"widgettype": "urlwidget",
|
||||||
"options": {
|
"options": {
|
||||||
"url": "{{entire_url('harnessed_agent/memory.ui')}}"
|
"url": "{{entire_url('harnessed_agent/memory.ui')}}"
|
||||||
}
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"name": "skills",
|
||||||
|
"label": "Skills",
|
||||||
|
"icon": "code",
|
||||||
|
"content": {
|
||||||
"widgettype": "urlwidget",
|
"widgettype": "urlwidget",
|
||||||
"options": {
|
"options": {
|
||||||
"url": "{{entire_url('harnessed_agent/skills.ui')}}"
|
"url": "{{entire_url('harnessed_agent/skills.ui')}}"
|
||||||
}
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"name": "remote_skills",
|
||||||
|
"label": "Remote Skills",
|
||||||
|
"icon": "cloud",
|
||||||
|
"content": {
|
||||||
"widgettype": "urlwidget",
|
"widgettype": "urlwidget",
|
||||||
"options": {
|
"options": {
|
||||||
"url": "{{entire_url('harnessed_agent/remote_skills.ui')}}"
|
"url": "{{entire_url('harnessed_agent/remote_skills.ui')}}"
|
||||||
}
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"name": "workflows",
|
||||||
|
"label": "Workflows",
|
||||||
|
"icon": "workflow",
|
||||||
|
"content": {
|
||||||
"widgettype": "urlwidget",
|
"widgettype": "urlwidget",
|
||||||
"options": {
|
"options": {
|
||||||
"url": "{{entire_url('harnessed_agent/workflows.ui')}}"
|
"url": "{{entire_url('harnessed_agent/workflows.ui')}}"
|
||||||
}
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"name": "tasks",
|
||||||
|
"label": "Tasks",
|
||||||
|
"icon": "tasks",
|
||||||
|
"content": {
|
||||||
"widgettype": "urlwidget",
|
"widgettype": "urlwidget",
|
||||||
"options": {
|
"options": {
|
||||||
"url": "{{entire_url('harnessed_agent/tasks.ui')}}"
|
"url": "{{entire_url('harnessed_agent/tasks.ui')}}"
|
||||||
}
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"name": "sessions",
|
||||||
|
"label": "Sessions",
|
||||||
|
"icon": "history",
|
||||||
|
"content": {
|
||||||
"widgettype": "urlwidget",
|
"widgettype": "urlwidget",
|
||||||
"options": {
|
"options": {
|
||||||
"url": "{{entire_url('harnessed_agent/sessions.ui')}}"
|
"url": "{{entire_url('harnessed_agent/sessions.ui')}}"
|
||||||
}
|
}
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
|
"name": "settings",
|
||||||
|
"label": "Settings",
|
||||||
|
"icon": "settings",
|
||||||
|
"content": {
|
||||||
"widgettype": "urlwidget",
|
"widgettype": "urlwidget",
|
||||||
"options": {
|
"options": {
|
||||||
"url": "{{entire_url('harnessed_agent/tools.ui')}}"
|
"url": "{{entire_url('harnessed_agent/agent_config.ui')}}"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
|||||||
@ -1,38 +1,32 @@
|
|||||||
{
|
{
|
||||||
"widgettype": "Bricks",
|
"widgettype": "VBox",
|
||||||
"options": {
|
"options": {
|
||||||
"bricks": [
|
"width": "100%",
|
||||||
{
|
"height": "100%",
|
||||||
"type": "container",
|
"css": "ios-scroll-area"
|
||||||
"children": [
|
|
||||||
{
|
|
||||||
"type": "header",
|
|
||||||
"content": "Hermes Agent - 记忆管理"
|
|
||||||
},
|
},
|
||||||
|
"subwidgets": [
|
||||||
{
|
{
|
||||||
"type": "crud",
|
"widgettype": "Toolbar",
|
||||||
"tablename": "memory",
|
"options": {
|
||||||
"params": {
|
"css": "ios-navbar",
|
||||||
"title": "持久化记忆",
|
"items": [
|
||||||
"description": "管理用户和系统持久化记忆",
|
{
|
||||||
"sortby": "created_at DESC",
|
"text": "Memory",
|
||||||
"logined_userid": "user_id",
|
"icon": "memory",
|
||||||
"browserfields": {
|
"css": "ios-navbar-title",
|
||||||
"exclouded": ["id", "user_id"],
|
"disabled": true
|
||||||
"alters": {
|
|
||||||
"created_at": {
|
|
||||||
"type": "datetime"
|
|
||||||
},
|
|
||||||
"updated_at": {
|
|
||||||
"type": "datetime"
|
|
||||||
}
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"editexclouded": ["id", "user_id"]
|
{
|
||||||
|
"widgettype": "urlwidget",
|
||||||
|
"options": {
|
||||||
|
"url": "{{entire_url(hermes_memory_crud)}}",
|
||||||
|
"width": "100%",
|
||||||
|
"height": "100%"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -2,217 +2,31 @@
|
|||||||
"widgettype": "VBox",
|
"widgettype": "VBox",
|
||||||
"options": {
|
"options": {
|
||||||
"width": "100%",
|
"width": "100%",
|
||||||
"height": "100%"
|
"height": "100%",
|
||||||
|
"css": "ios-scroll-area"
|
||||||
},
|
},
|
||||||
"subwidgets": [
|
"subwidgets": [
|
||||||
{
|
{
|
||||||
"widgettype": "Toolbar",
|
"widgettype": "Toolbar",
|
||||||
"options": {
|
"options": {
|
||||||
|
"css": "ios-navbar",
|
||||||
"items": [
|
"items": [
|
||||||
{
|
{
|
||||||
"text": "Remote Skills Management",
|
"text": "Remote Skills",
|
||||||
"icon": "cloud-upload",
|
"icon": "cloud-upload",
|
||||||
|
"css": "ios-navbar-title",
|
||||||
"disabled": true
|
"disabled": true
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"widgettype": "HBox",
|
"widgettype": "urlwidget",
|
||||||
"options": {
|
"options": {
|
||||||
|
"url": "{{entire_url(hermes_remote_skills_crud)}}",
|
||||||
|
"width": "100%",
|
||||||
"height": "100%"
|
"height": "100%"
|
||||||
},
|
|
||||||
"subwidgets": [
|
|
||||||
{
|
|
||||||
"widgettype": "Grid",
|
|
||||||
"id": "remote_skills_grid",
|
|
||||||
"options": {
|
|
||||||
"url": "/harnessed_agent/remote_skills",
|
|
||||||
"fields": [
|
|
||||||
{"name": "name", "label": "Name", "width": "150px"},
|
|
||||||
{"name": "host", "label": "Host", "width": "120px"},
|
|
||||||
{"name": "username", "label": "Username", "width": "100px"},
|
|
||||||
{"name": "enabled", "label": "Enabled", "width": "80px", "type": "bool"},
|
|
||||||
{"name": "last_deployed", "label": "Last Deployed", "width": "150px"},
|
|
||||||
{"name": "last_executed", "label": "Last Executed", "width": "150px"}
|
|
||||||
],
|
|
||||||
"page_size": 20,
|
|
||||||
"height": "100%"
|
|
||||||
},
|
|
||||||
"binds": [
|
|
||||||
{
|
|
||||||
"wid": "self",
|
|
||||||
"event": "row_selected",
|
|
||||||
"actiontype": "callfunction",
|
|
||||||
"fname": "hermes_manage_remote_skills",
|
|
||||||
"params": {
|
|
||||||
"action": "read",
|
|
||||||
"skill_id": "${id}$"
|
|
||||||
},
|
|
||||||
"target": "skill_detail_form",
|
|
||||||
"method": "load_data"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"widgettype": "VBox",
|
|
||||||
"options": {
|
|
||||||
"width": "400px",
|
|
||||||
"padding": "10px"
|
|
||||||
},
|
|
||||||
"subwidgets": [
|
|
||||||
{
|
|
||||||
"widgettype": "Form",
|
|
||||||
"id": "skill_detail_form",
|
|
||||||
"options": {
|
|
||||||
"fields": [
|
|
||||||
{"name": "id", "label": "ID", "readonly": true, "hidden": true},
|
|
||||||
{"name": "name", "label": "Skill Name", "required": true},
|
|
||||||
{"name": "host", "label": "SSH Host", "required": true},
|
|
||||||
{"name": "port", "label": "SSH Port", "type": "int", "default": 22},
|
|
||||||
{"name": "username", "label": "Username", "required": true},
|
|
||||||
{"name": "remote_path", "label": "Remote Path", "default": "~/.skills"},
|
|
||||||
{"name": "auth_method", "label": "Auth Method", "type": "select", "options": ["key", "password"], "default": "key"},
|
|
||||||
{"name": "ssh_key_path", "label": "SSH Key Path"},
|
|
||||||
{"name": "description", "label": "Description", "type": "textarea"},
|
|
||||||
{"name": "category", "label": "Category"},
|
|
||||||
{"name": "version", "label": "Version", "default": "1.0.0"},
|
|
||||||
{"name": "enabled", "label": "Enabled", "type": "bool", "default": true}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"binds": [
|
|
||||||
{
|
|
||||||
"wid": "save_button",
|
|
||||||
"event": "click",
|
|
||||||
"actiontype": "callfunction",
|
|
||||||
"fname": "hermes_manage_remote_skills",
|
|
||||||
"params": {
|
|
||||||
"action": "${id ? 'update' : 'create'}$",
|
|
||||||
"skill_id": "${id}$",
|
|
||||||
"name": "${name}$",
|
|
||||||
"host": "${host}$",
|
|
||||||
"port": "${port}$",
|
|
||||||
"username": "${username}$",
|
|
||||||
"remote_path": "${remote_path}$",
|
|
||||||
"auth_method": "${auth_method}$",
|
|
||||||
"ssh_key_path": "${ssh_key_path}$",
|
|
||||||
"description": "${description}$",
|
|
||||||
"category": "${category}$",
|
|
||||||
"version": "${version}$",
|
|
||||||
"enabled": "${enabled}$"
|
|
||||||
},
|
|
||||||
"target": "remote_skills_grid",
|
|
||||||
"method": "refresh"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"wid": "delete_button",
|
|
||||||
"event": "click",
|
|
||||||
"actiontype": "callfunction",
|
|
||||||
"fname": "hermes_manage_remote_skills",
|
|
||||||
"params": {
|
|
||||||
"action": "delete",
|
|
||||||
"skill_id": "${id}$"
|
|
||||||
},
|
|
||||||
"target": "remote_skills_grid",
|
|
||||||
"method": "refresh"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"widgettype": "ButtonBar",
|
|
||||||
"options": {
|
|
||||||
"buttons": [
|
|
||||||
{
|
|
||||||
"id": "save_button",
|
|
||||||
"text": "Save",
|
|
||||||
"icon": "save"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"id": "delete_button",
|
|
||||||
"text": "Delete",
|
|
||||||
"icon": "trash",
|
|
||||||
"confirm": "Are you sure you want to delete this remote skill?"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"widgettype": "HBox",
|
|
||||||
"options": {
|
|
||||||
"margin_top": "20px"
|
|
||||||
},
|
|
||||||
"subwidgets": [
|
|
||||||
{
|
|
||||||
"widgettype": "Button",
|
|
||||||
"id": "deploy_button",
|
|
||||||
"options": {
|
|
||||||
"text": "Deploy Skill",
|
|
||||||
"icon": "upload-cloud",
|
|
||||||
"disabled": "${!id || !enabled}$"
|
|
||||||
},
|
|
||||||
"binds": [
|
|
||||||
{
|
|
||||||
"wid": "self",
|
|
||||||
"event": "click",
|
|
||||||
"actiontype": "popup",
|
|
||||||
"url": "{{entire_url('harnessed_agent/deploy_skill.ui')}}?skill_id=${id}$"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"widgettype": "Button",
|
|
||||||
"id": "execute_button",
|
|
||||||
"options": {
|
|
||||||
"text": "Execute Skill",
|
|
||||||
"icon": "play",
|
|
||||||
"disabled": "${!id || !enabled}$"
|
|
||||||
},
|
|
||||||
"binds": [
|
|
||||||
{
|
|
||||||
"wid": "self",
|
|
||||||
"event": "click",
|
|
||||||
"actiontype": "popup",
|
|
||||||
"url": "{{entire_url('harnessed_agent/execute_remote_skill.ui')}}?skill_id=${id}$"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"widgettype": "Button",
|
|
||||||
"id": "list_button",
|
|
||||||
"options": {
|
|
||||||
"text": "List Remote",
|
|
||||||
"icon": "list",
|
|
||||||
"disabled": "${!id || !enabled}$"
|
|
||||||
},
|
|
||||||
"binds": [
|
|
||||||
{
|
|
||||||
"wid": "self",
|
|
||||||
"event": "click",
|
|
||||||
"actiontype": "callfunction",
|
|
||||||
"fname": "hermes_manage_remote_skills",
|
|
||||||
"params": {
|
|
||||||
"action": "list_remote",
|
|
||||||
"skill_id": "${id}$"
|
|
||||||
},
|
|
||||||
"target": "remote_list_result",
|
|
||||||
"method": "set_text"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"widgettype": "Label",
|
|
||||||
"id": "remote_list_result",
|
|
||||||
"options": {
|
|
||||||
"text": "",
|
|
||||||
"height": "100px",
|
|
||||||
"overflow": "auto"
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
|
||||||
@ -1,37 +1,32 @@
|
|||||||
{
|
{
|
||||||
"widgettype": "Bricks",
|
"widgettype": "VBox",
|
||||||
"options": {
|
"options": {
|
||||||
"bricks": [
|
"width": "100%",
|
||||||
{
|
"height": "100%",
|
||||||
"type": "container",
|
"css": "ios-scroll-area"
|
||||||
"children": [
|
|
||||||
{
|
|
||||||
"type": "header",
|
|
||||||
"content": "Hermes Agent - 用户会话管理"
|
|
||||||
},
|
},
|
||||||
|
"subwidgets": [
|
||||||
{
|
{
|
||||||
"type": "crud",
|
"widgettype": "Toolbar",
|
||||||
"tablename": "sessions",
|
"options": {
|
||||||
"params": {
|
"css": "ios-navbar",
|
||||||
"title": "用户会话",
|
"items": [
|
||||||
"description": "管理用户AI代理会话",
|
{
|
||||||
"sortby": "created_at DESC",
|
"text": "Sessions",
|
||||||
"browserfields": {
|
"icon": "history",
|
||||||
"exclouded": ["id", "user_id"],
|
"css": "ios-navbar-title",
|
||||||
"alters": {
|
"disabled": true
|
||||||
"created_at": {
|
|
||||||
"type": "datetime"
|
|
||||||
},
|
|
||||||
"updated_at": {
|
|
||||||
"type": "datetime"
|
|
||||||
}
|
}
|
||||||
|
]
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"editexclouded": ["id", "user_id"]
|
{
|
||||||
|
"widgettype": "urlwidget",
|
||||||
|
"options": {
|
||||||
|
"url": "{{entire_url(hermes_sessions_crud)}}",
|
||||||
|
"width": "100%",
|
||||||
|
"height": "100%"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -1,30 +1,32 @@
|
|||||||
{
|
{
|
||||||
"widgettype": "Bricks",
|
"widgettype": "VBox",
|
||||||
"options": {
|
"options": {
|
||||||
"bricks": [
|
"width": "100%",
|
||||||
|
"height": "100%",
|
||||||
|
"css": "ios-scroll-area"
|
||||||
|
},
|
||||||
|
"subwidgets": [
|
||||||
{
|
{
|
||||||
"type": "container",
|
"widgettype": "Toolbar",
|
||||||
"children": [
|
"options": {
|
||||||
|
"css": "ios-navbar",
|
||||||
|
"items": [
|
||||||
{
|
{
|
||||||
"type": "header",
|
"text": "Skills",
|
||||||
"content": "Hermes Agent - 技能管理"
|
"icon": "code",
|
||||||
|
"css": "ios-navbar-title",
|
||||||
|
"disabled": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"type": "crud",
|
"widgettype": "urlwidget",
|
||||||
"tablename": "skills",
|
"options": {
|
||||||
"params": {
|
"url": "{{entire_url(hermes_skills_crud)}}",
|
||||||
"title": "AI技能",
|
"width": "100%",
|
||||||
"description": "管理AI代理可用的技能",
|
"height": "100%"
|
||||||
"sortby": "name",
|
|
||||||
"browserfields": {
|
|
||||||
"exclouded": ["id"],
|
|
||||||
"alters": {}
|
|
||||||
},
|
|
||||||
"editexclouded": ["id"]
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
]
|
|
||||||
}
|
|
||||||
}
|
|
||||||
@ -2,66 +2,31 @@
|
|||||||
"widgettype": "VBox",
|
"widgettype": "VBox",
|
||||||
"options": {
|
"options": {
|
||||||
"width": "100%",
|
"width": "100%",
|
||||||
"height": "100%"
|
"height": "100%",
|
||||||
|
"css": "ios-scroll-area"
|
||||||
},
|
},
|
||||||
"subwidgets": [
|
"subwidgets": [
|
||||||
{
|
{
|
||||||
"widgettype": "Toolbar",
|
"widgettype": "Toolbar",
|
||||||
"options": {
|
"options": {
|
||||||
|
"css": "ios-navbar",
|
||||||
"items": [
|
"items": [
|
||||||
{
|
{
|
||||||
"text": "Create Task",
|
"text": "Tasks",
|
||||||
"icon": "plus",
|
"icon": "format-list-checks",
|
||||||
"id": "create_task_btn"
|
"css": "ios-navbar-title",
|
||||||
},
|
"disabled": true
|
||||||
{
|
|
||||||
"text": "Refresh",
|
|
||||||
"icon": "refresh",
|
|
||||||
"id": "refresh_tasks_btn"
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
|
||||||
"binds": [
|
|
||||||
{
|
|
||||||
"wid": "create_task_btn",
|
|
||||||
"event": "click",
|
|
||||||
"actiontype": "urlwidget",
|
|
||||||
"url": "{{entire_url('harnessed_agent/create_task.ui')}}"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"wid": "refresh_tasks_btn",
|
|
||||||
"event": "click",
|
|
||||||
"actiontype": "registerfunction",
|
|
||||||
"rfname": "hermes_refresh_tasks",
|
|
||||||
"target": "tasks_grid",
|
|
||||||
"method": "reload"
|
|
||||||
}
|
}
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"widgettype": "DataGrid",
|
"widgettype": "urlwidget",
|
||||||
"id": "tasks_grid",
|
|
||||||
"options": {
|
"options": {
|
||||||
"columns": [
|
"url": "{{entire_url(hermes_tasks_workflow)}}",
|
||||||
{"field": "task_name", "title": "Task Name", "width": "25%"},
|
"width": "100%",
|
||||||
{"field": "task_type", "title": "Type", "width": "15%"},
|
"height": "100%"
|
||||||
{"field": "workflow_id", "title": "Workflow", "width": "20%"},
|
}
|
||||||
{"field": "order_index", "title": "Order", "width": "10%"},
|
|
||||||
{"field": "created_at", "title": "Created", "width": "20%"},
|
|
||||||
{"field": "actions", "title": "Actions", "width": "10%", "renderer": "action_buttons"}
|
|
||||||
],
|
|
||||||
"url": "/api/hermes/tasks",
|
|
||||||
"method": "GET",
|
|
||||||
"auto_load": true
|
|
||||||
},
|
|
||||||
"binds": [
|
|
||||||
{
|
|
||||||
"wid": "self",
|
|
||||||
"event": "row_click",
|
|
||||||
"actiontype": "urlwidget",
|
|
||||||
"url": "{{entire_url('harnessed_agent/task_detail.ui?id=${row.id}$')}}"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
@ -2,24 +2,52 @@
|
|||||||
"widgettype": "VBox",
|
"widgettype": "VBox",
|
||||||
"options": {
|
"options": {
|
||||||
"width": "100%",
|
"width": "100%",
|
||||||
"height": "100%"
|
"height": "100%",
|
||||||
|
"css": "ios-scroll-area"
|
||||||
|
},
|
||||||
|
"subwidgets": [
|
||||||
|
{
|
||||||
|
"widgettype": "Toolbar",
|
||||||
|
"options": {
|
||||||
|
"css": "ios-navbar",
|
||||||
|
"items": [
|
||||||
|
{
|
||||||
|
"text": "Tools",
|
||||||
|
"icon": "tools",
|
||||||
|
"css": "ios-navbar-title",
|
||||||
|
"disabled": true
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"widgettype": "HBox",
|
||||||
|
"options": {
|
||||||
|
"css": "ios-card",
|
||||||
|
"width": "100%",
|
||||||
|
"wrap": true,
|
||||||
|
"gap": "12px"
|
||||||
},
|
},
|
||||||
"subwidgets": [
|
"subwidgets": [
|
||||||
{
|
{
|
||||||
"widgettype": "Form",
|
"widgettype": "Form",
|
||||||
|
"id": "tool_execute_form",
|
||||||
"options": {
|
"options": {
|
||||||
"title": "Execute Tool",
|
"css": "ios-group",
|
||||||
|
"title": "",
|
||||||
"fields": [
|
"fields": [
|
||||||
{
|
{
|
||||||
"name": "tool_name",
|
"name": "tool_name",
|
||||||
"uitype": "str",
|
"uitype": "str",
|
||||||
"label": "Tool Name",
|
"label": "Tool Name",
|
||||||
|
"placeholder": "Enter tool name...",
|
||||||
"required": true
|
"required": true
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"name": "parameters",
|
"name": "parameters",
|
||||||
"uitype": "text",
|
"uitype": "text",
|
||||||
"label": "Parameters (JSON)",
|
"label": "Parameters (JSON)",
|
||||||
|
"placeholder": "{}",
|
||||||
"required": false
|
"required": false
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
@ -33,6 +61,8 @@
|
|||||||
"params": "${form_data}$"
|
"params": "${form_data}$"
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
|
}
|
||||||
|
]
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"widgettype": "Message",
|
"widgettype": "Message",
|
||||||
|
|||||||
@ -2,66 +2,31 @@
|
|||||||
"widgettype": "VBox",
|
"widgettype": "VBox",
|
||||||
"options": {
|
"options": {
|
||||||
"width": "100%",
|
"width": "100%",
|
||||||
"height": "100%"
|
"height": "100%",
|
||||||
|
"css": "ios-scroll-area"
|
||||||
},
|
},
|
||||||
"subwidgets": [
|
"subwidgets": [
|
||||||
{
|
{
|
||||||
"widgettype": "Toolbar",
|
"widgettype": "Toolbar",
|
||||||
"options": {
|
"options": {
|
||||||
|
"css": "ios-navbar",
|
||||||
"items": [
|
"items": [
|
||||||
{
|
{
|
||||||
"text": "Create Workflow",
|
"text": "Workflows",
|
||||||
"icon": "plus",
|
"icon": "account-tree",
|
||||||
"id": "create_workflow_btn"
|
"css": "ios-navbar-title",
|
||||||
},
|
"disabled": true
|
||||||
{
|
|
||||||
"text": "Refresh",
|
|
||||||
"icon": "refresh",
|
|
||||||
"id": "refresh_workflows_btn"
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
},
|
|
||||||
"binds": [
|
|
||||||
{
|
|
||||||
"wid": "create_workflow_btn",
|
|
||||||
"event": "click",
|
|
||||||
"actiontype": "urlwidget",
|
|
||||||
"url": "{{entire_url('harnessed_agent/create_workflow.ui')}}"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"wid": "refresh_workflows_btn",
|
|
||||||
"event": "click",
|
|
||||||
"actiontype": "registerfunction",
|
|
||||||
"rfname": "hermes_refresh_workflows",
|
|
||||||
"target": "workflows_grid",
|
|
||||||
"method": "reload"
|
|
||||||
}
|
}
|
||||||
]
|
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"widgettype": "DataGrid",
|
"widgettype": "urlwidget",
|
||||||
"id": "workflows_grid",
|
|
||||||
"options": {
|
"options": {
|
||||||
"columns": [
|
"url": "{{entire_url(hermes_workflows_crud)}}",
|
||||||
{"field": "name", "title": "Name", "width": "20%"},
|
"width": "100%",
|
||||||
{"field": "workflow_type", "title": "Type", "width": "15%"},
|
"height": "100%"
|
||||||
{"field": "status", "title": "Status", "width": "15%"},
|
}
|
||||||
{"field": "created_at", "title": "Created", "width": "20%"},
|
|
||||||
{"field": "updated_at", "title": "Updated", "width": "20%"},
|
|
||||||
{"field": "actions", "title": "Actions", "width": "10%", "renderer": "action_buttons"}
|
|
||||||
],
|
|
||||||
"url": "/api/hermes/workflows",
|
|
||||||
"method": "GET",
|
|
||||||
"auto_load": true
|
|
||||||
},
|
|
||||||
"binds": [
|
|
||||||
{
|
|
||||||
"wid": "self",
|
|
||||||
"event": "row_click",
|
|
||||||
"actiontype": "urlwidget",
|
|
||||||
"url": "{{entire_url('harnessed_agent/workflow_detail.ui?id=${row.id}$')}}"
|
|
||||||
}
|
|
||||||
]
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user