diff --git a/messages/ar.json b/messages/ar.json index 8c8a527a6..8f0e481f8 100644 --- a/messages/ar.json +++ b/messages/ar.json @@ -1580,7 +1580,10 @@ "justNow": "الآن", "minutesAgo": "منذ {count} د", "hoursAgo": "منذ {count} س", - "daysAgo": "منذ {count} ي" + "daysAgo": "منذ {count} ي", + "runtimeType": "Runtime", + "runtimeTypeAuto": "Auto-detect", + "runtimeTypeCustom": "Custom" }, "multiGateway": { "title": "مدير البوابات", diff --git a/messages/de.json b/messages/de.json index 3c884e99d..62327fa64 100644 --- a/messages/de.json +++ b/messages/de.json @@ -1580,7 +1580,10 @@ "justNow": "Gerade eben", "minutesAgo": "vor {count}m", "hoursAgo": "vor {count}h", - "daysAgo": "vor {count}d" + "daysAgo": "vor {count}d", + "runtimeType": "Runtime", + "runtimeTypeAuto": "Auto-detect", + "runtimeTypeCustom": "Custom" }, "multiGateway": { "title": "Gateway-Manager", diff --git a/messages/en.json b/messages/en.json index b906d6161..4a2ba454b 100644 --- a/messages/en.json +++ b/messages/en.json @@ -1729,7 +1729,10 @@ "justNow": "Just now", "minutesAgo": "{count}m ago", "hoursAgo": "{count}h ago", - "daysAgo": "{count}d ago" + "daysAgo": "{count}d ago", + "runtimeType": "Runtime", + "runtimeTypeAuto": "Auto-detect", + "runtimeTypeCustom": "Custom" }, "multiGateway": { "title": "Gateway Manager", diff --git a/messages/es.json b/messages/es.json index 5aeabf243..681cf2bb6 100644 --- a/messages/es.json +++ b/messages/es.json @@ -1580,7 +1580,10 @@ "justNow": "Ahora mismo", "minutesAgo": "hace {count}m", "hoursAgo": "hace {count}h", - "daysAgo": "hace {count}d" + "daysAgo": "hace {count}d", + "runtimeType": "Runtime", + "runtimeTypeAuto": "Auto-detect", + "runtimeTypeCustom": "Custom" }, "multiGateway": { "title": "Gestor de puertas de enlace", diff --git a/messages/fr.json b/messages/fr.json index 2a6870a56..9a97255b4 100644 --- a/messages/fr.json +++ b/messages/fr.json @@ -1580,7 +1580,10 @@ "justNow": "À l'instant", "minutesAgo": "il y a {count}m", "hoursAgo": "il y a {count}h", - "daysAgo": "il y a {count}j" + "daysAgo": "il y a {count}j", + "runtimeType": "Runtime", + "runtimeTypeAuto": "Auto-detect", + "runtimeTypeCustom": "Custom" }, "multiGateway": { "title": "Gestionnaire de passerelles", diff --git a/messages/ja.json b/messages/ja.json index bcee272e5..5be7802f3 100644 --- a/messages/ja.json +++ b/messages/ja.json @@ -1580,7 +1580,10 @@ "justNow": "たった今", "minutesAgo": "{count}分前", "hoursAgo": "{count}時間前", - "daysAgo": "{count}日前" + "daysAgo": "{count}日前", + "runtimeType": "Runtime", + "runtimeTypeAuto": "Auto-detect", + "runtimeTypeCustom": "Custom" }, "multiGateway": { "title": "ゲートウェイマネージャー", diff --git a/messages/ko.json b/messages/ko.json index 829f7bb7b..9f3548535 100644 --- a/messages/ko.json +++ b/messages/ko.json @@ -1729,7 +1729,10 @@ "justNow": "방금", "minutesAgo": "{count}분 전", "hoursAgo": "{count}시간 전", - "daysAgo": "{count}일 전" + "daysAgo": "{count}일 전", + "runtimeType": "Runtime", + "runtimeTypeAuto": "Auto-detect", + "runtimeTypeCustom": "Custom" }, "multiGateway": { "title": "게이트웨이 관리자", diff --git a/messages/pt.json b/messages/pt.json index b412a2a66..34739a67c 100644 --- a/messages/pt.json +++ b/messages/pt.json @@ -1580,7 +1580,10 @@ "justNow": "Agora mesmo", "minutesAgo": "há {count}m", "hoursAgo": "há {count}h", - "daysAgo": "há {count}d" + "daysAgo": "há {count}d", + "runtimeType": "Runtime", + "runtimeTypeAuto": "Auto-detect", + "runtimeTypeCustom": "Custom" }, "multiGateway": { "title": "Gerenciador de gateways", diff --git a/messages/ru.json b/messages/ru.json index 6f7378170..0a3c4048f 100644 --- a/messages/ru.json +++ b/messages/ru.json @@ -1580,7 +1580,10 @@ "justNow": "Только что", "minutesAgo": "{count}м назад", "hoursAgo": "{count}ч назад", - "daysAgo": "{count}д назад" + "daysAgo": "{count}д назад", + "runtimeType": "Runtime", + "runtimeTypeAuto": "Auto-detect", + "runtimeTypeCustom": "Custom" }, "multiGateway": { "title": "Менеджер шлюзов", diff --git a/messages/zh.json b/messages/zh.json index 8b5398fd7..7d3b262fb 100644 --- a/messages/zh.json +++ b/messages/zh.json @@ -1818,7 +1818,10 @@ "justNow": "刚刚", "minutesAgo": "{count}分钟前", "hoursAgo": "{count}小时前", - "daysAgo": "{count}天前" + "daysAgo": "{count}天前", + "runtimeType": "Runtime", + "runtimeTypeAuto": "Auto-detect", + "runtimeTypeCustom": "Custom" }, "multiGateway": { "title": "网关管理器", diff --git a/src/app/api/agents/route.ts b/src/app/api/agents/route.ts index 28e5bb16d..d1f5ab2a0 100644 --- a/src/app/api/agents/route.ts +++ b/src/app/api/agents/route.ts @@ -175,7 +175,8 @@ export async function POST(request: NextRequest) { gateway_config, write_to_gateway, provision_openclaw_workspace, - openclaw_workspace_path + openclaw_workspace_path, + runtime_type, } = body; const openclawId = (openclaw_id || name || 'agent') @@ -239,11 +240,11 @@ export async function POST(request: NextRequest) { const stmt = db.prepare(` INSERT INTO agents ( - name, role, session_key, soul_content, status, - created_at, updated_at, config, workspace_id - ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?) + name, role, session_key, soul_content, status, + created_at, updated_at, config, workspace_id, runtime_type + ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?) `); - + const dbResult = stmt.run( name, finalRole, @@ -253,11 +254,37 @@ export async function POST(request: NextRequest) { now, now, JSON.stringify(finalConfig), - workspaceId + workspaceId, + runtime_type || null ); const agentId = dbResult.lastInsertRowid as number; - + + // Provision Hermes profile directory if runtime_type is hermes + if (runtime_type === 'hermes') { + try { + const { mkdirSync, writeFileSync, existsSync: fsExists } = require('node:fs') + const profileDir = path.join(appConfig.homeDir, '.hermes', 'profiles', name) + if (!fsExists(profileDir)) { + mkdirSync(profileDir, { recursive: true }) + // Write config.yaml with model from agent config or default + const model = finalConfig.model || 'claude-sonnet-4-6' + const provider = finalConfig.provider || 'anthropic' + writeFileSync( + path.join(profileDir, 'config.yaml'), + `model: ${model}\nprovider: ${provider}\ntoolsets:\n- all\nmax_turns: 100\n`, + ) + // Write SOUL.md if soul_content provided + if (soul_content) { + writeFileSync(path.join(profileDir, 'SOUL.md'), soul_content) + } + logger.info({ agentName: name, profileDir }, 'Provisioned Hermes profile directory') + } + } catch (err) { + logger.warn({ err, agentName: name }, 'Failed to provision Hermes profile (non-fatal)') + } + } + // Log activity db_helpers.logActivity( 'agent_created', diff --git a/src/components/panels/agent-squad-panel.tsx b/src/components/panels/agent-squad-panel.tsx index 19978ab3e..259e13050 100644 --- a/src/components/panels/agent-squad-panel.tsx +++ b/src/components/panels/agent-squad-panel.tsx @@ -26,6 +26,7 @@ interface Agent { in_progress: number completed: number } + runtime_type?: string } const statusColors: Record = { @@ -217,7 +218,14 @@ export function AgentSquadPanel() { {/* Agent Header */}
-

{agent.name}

+
+

{agent.name}

+ {agent.runtime_type && ( + + {agent.runtime_type} + + )} +

{agent.role}

@@ -528,6 +536,7 @@ function CreateAgentModal({ role: '', session_key: '', soul_content: '', + runtime_type: '' as string, }) const handleSubmit = async (e: React.FormEvent) => { @@ -537,7 +546,10 @@ function CreateAgentModal({ const response = await fetch('/api/agents', { method: 'POST', headers: { 'Content-Type': 'application/json' }, - body: JSON.stringify(formData) + body: JSON.stringify({ + ...formData, + runtime_type: formData.runtime_type || undefined, + }) }) if (!response.ok) throw new Error(t('failedToCreate')) @@ -579,6 +591,22 @@ function CreateAgentModal({ />
+
+ + +
+