基于官方 nousresearch/hermes-agent 镜像的 CLI、Docker Compose 与 Web 管理界面,支持多实例部署;敏感配置与实例数据由 .gitignore 排除。 Co-authored-by: Cursor <cursoragent@cursor.com>
107 lines
5.6 KiB
HTML
107 lines
5.6 KiB
HTML
{% extends "base.html" %}
|
||
{% block title %}实例 · Hermes Agent Web{% endblock %}
|
||
{% block body %}
|
||
<h2 style="margin-top:0;">实例</h2>
|
||
<p class="muted">
|
||
数据目录:<code>{{ data_root }}</code> ·
|
||
合计 <strong>{{ total }}</strong> 个实例 ·
|
||
网关运行中 <strong>{{ running_n }}</strong> 个
|
||
· 列表「所属人」记在每台目录下的 <code>web-meta.json</code>(与 <code>data/config.yaml</code> 分离)
|
||
</p>
|
||
<p class="muted" style="max-width:52rem;">
|
||
首次配置请点 <strong>「Hermes 引导」</strong>(<code>setup</code> → 启动 gateway → 容器 shell)。
|
||
Docker 项目名 <code>hermes-<序号></code>,服务 <code>gateway</code>(NousResearch/hermes-agent)。
|
||
</p>
|
||
{% if compose_error %}
|
||
<div class="flash error">Compose 配置错误:{{ compose_error }}</div>
|
||
{% endif %}
|
||
|
||
<form method="post" action="{{ url_for('instance_create') }}" style="margin:1rem 0;">
|
||
<input type="hidden" name="csrf_token" value="{{ csrf_token }}">
|
||
<button type="submit" class="primary">新建实例</button>
|
||
<span class="muted">将分配新序号、创建目录并执行 <code>bootstrap</code>;之后可点「启动」拉起网关。</span>
|
||
</form>
|
||
|
||
{% if not rows %}
|
||
<p class="muted">暂无实例。点击「新建实例」开始。</p>
|
||
{% else %}
|
||
<table>
|
||
<thead>
|
||
<tr>
|
||
<th>#</th>
|
||
<th>状态</th>
|
||
<th>所属人</th>
|
||
<th>端口</th>
|
||
<th>操作</th>
|
||
</tr>
|
||
</thead>
|
||
<tbody>
|
||
{% for r in rows %}
|
||
<tr>
|
||
<td><strong>{{ r.id }}</strong></td>
|
||
<td>
|
||
{% if r.status.running %}
|
||
<span class="badge ok">运行中</span>
|
||
{% elif r.status.state == 'not_created' %}
|
||
<span class="badge off">未创建容器</span>
|
||
{% elif r.status.state in ('exited', 'dead') %}
|
||
<span class="badge off">已停止</span> <span class="muted">{{ r.status.state }}</span>
|
||
{% else %}
|
||
<span class="badge err">{{ r.status.state }}</span>
|
||
{% endif %}
|
||
{% if r.status.name %}
|
||
<div class="muted" style="margin-top:0.35rem;"><code>{{ r.status.name }}</code></div>
|
||
{% endif %}
|
||
{% if r.status.detail %}
|
||
<div class="muted" style="margin-top:0.25rem;">{{ r.status.detail }}</div>
|
||
{% endif %}
|
||
{% if not r.has_config %}
|
||
<div class="muted" style="margin-top:0.25rem;">未配置(无 config.yaml / .env)</div>
|
||
{% endif %}
|
||
</td>
|
||
<td style="min-width:12rem;vertical-align:middle;">
|
||
<form method="post" action="{{ url_for('instance_set_owner', iid=r.id) }}" style="margin:0;display:flex;flex-direction:column;gap:0.45rem;align-items:stretch;">
|
||
<input type="hidden" name="csrf_token" value="{{ csrf_token }}">
|
||
<input type="text" name="owner" value="{{ r.metadata_owner }}" placeholder="未设置" maxlength="128" autocomplete="off" style="width:50%;box-sizing:border-box;padding:0.4rem 0.5rem;border-radius:6px;border:1px solid var(--border);background:#0c1017;color:var(--text);font:inherit;">
|
||
<button type="submit" class="btn" style="align-self:flex-start;">保存</button>
|
||
</form>
|
||
</td>
|
||
<td>
|
||
<span class="muted">网关</span> <code>{{ r.gateway_port }}</code>
|
||
<br>
|
||
<span class="muted">Dashboard</span> <code>{{ r.dashboard_port }}</code>
|
||
</td>
|
||
<td>
|
||
<div class="row-actions">
|
||
<form method="post" action="{{ url_for('instance_compose_build', iid=r.id) }}" style="margin:0;display:inline;">
|
||
<input type="hidden" name="csrf_token" value="{{ csrf_token }}">
|
||
<button type="submit" title="从 Docker Hub 拉取官方镜像 nousresearch/hermes-agent">拉取镜像</button>
|
||
</form>
|
||
<form method="post" action="{{ url_for('instance_run', iid=r.id) }}" style="margin:0;display:inline;">
|
||
<input type="hidden" name="csrf_token" value="{{ csrf_token }}">
|
||
<button type="submit" class="primary">启动</button>
|
||
</form>
|
||
<a href="{{ url_for('instance_guide', iid=r.id) }}" class="btn primary" style="display:inline-block;padding:0.35rem 0.65rem;text-decoration:none;background:#1a4d7a;border:1px solid #2563a8;border-radius:6px;color:#e7edf4;font:inherit;">Hermes 引导</a>
|
||
<a href="{{ url_for('instance_docker_terminal', iid=r.id) }}" class="btn" style="display:inline-block;padding:0.35rem 0.65rem;text-decoration:none;background:#111827;border:1px solid #374151;border-radius:6px;color:#e7edf4;font:inherit;">终端</a>
|
||
<form method="post" action="{{ url_for('instance_stop', iid=r.id) }}" style="margin:0;display:inline;">
|
||
<input type="hidden" name="csrf_token" value="{{ csrf_token }}">
|
||
<button type="submit">停止</button>
|
||
</form>
|
||
<form method="post" action="{{ url_for('instance_restart', iid=r.id) }}" style="margin:0;display:inline;">
|
||
<input type="hidden" name="csrf_token" value="{{ csrf_token }}">
|
||
<button type="submit">重启</button>
|
||
</form>
|
||
<form method="post" action="{{ url_for('instance_destroy', iid=r.id) }}" style="margin:0;display:inline;" onsubmit="return confirm('确定销毁该实例?将执行 compose down,并永久删除宿主机上该序号的配置与工作区目录(不可恢复)。');">
|
||
<input type="hidden" name="csrf_token" value="{{ csrf_token }}">
|
||
<button type="submit" class="danger">销毁</button>
|
||
</form>
|
||
<a href="{{ url_for('instance_config', iid=r.id) }}">编辑配置</a>
|
||
</div>
|
||
</td>
|
||
</tr>
|
||
{% endfor %}
|
||
</tbody>
|
||
</table>
|
||
{% endif %}
|
||
{% endblock %}
|