hermes-labyrinth-observability
Compare original and translation side by side
🇺🇸
Original
English🇨🇳
Translation
ChineseHermes Labyrinth
Hermes Labyrinth
Skill by ara.so — Daily 2026 Skills collection.
Hermes Labyrinth is a read-only observability dashboard plugin for Hermes Agent. It turns autonomous agent runs into a navigable map of crossings (prompts, tool calls, tool results, failures, model switches, subagents, approvals, memory hits, redactions, context compression, cron runs) with exportable evidence. It is not a chat UI — it is a black-box recorder for agents moving through unknown work.
由ara.so开发的Skill——属于Daily 2026 Skills合集。
Hermes Labyrinth是一款面向Hermes Agent的只读可观测性仪表盘插件。它将自主Agent的运行过程转化为可导航的地图,记录各类节点(提示词、工具调用、工具结果、失败记录、模型切换、子Agent、审批操作、内存命中、内容脱敏、上下文压缩、定时任务运行),并支持导出证据。它并非聊天UI,而是用于追踪Agent在未知任务流程中运行情况的黑盒记录工具。
Install
安装
Plugin Directory Install
插件目录安装
bash
mkdir -p ~/.hermes/plugins
git clone https://github.com/stainlu/hermes-labyrinth.git ~/.hermes/plugins/hermes-labyrinthStart or restart the Hermes dashboard:
bash
hermes dashboardIf the dashboard is already running, rescan plugins without restarting:
bash
curl http://127.0.0.1:9119/api/dashboard/plugins/rescanOpen the dashboard in your browser and select the Labyrinth tab.
bash
mkdir -p ~/.hermes/plugins
git clone https://github.com/stainlu/hermes-labyrinth.git ~/.hermes/plugins/hermes-labyrinth启动或重启Hermes仪表盘:
bash
hermes dashboard如果仪表盘已在运行,无需重启即可重新扫描插件:
bash
curl http://127.0.0.1:9119/api/dashboard/plugins/rescan在浏览器中打开仪表盘,选择Labyrinth标签页。
Optional Theme
可选主题
bash
mkdir -p ~/.hermes/dashboard-themes
cp ~/.hermes/plugins/hermes-labyrinth/theme/hermes-labyrinth.yaml ~/.hermes/dashboard-themes/bash
mkdir -p ~/.hermes/dashboard-themes
cp ~/.hermes/plugins/hermes-labyrinth/theme/hermes-labyrinth.yaml ~/.hermes/dashboard-themes/What Labyrinth Tracks
Labyrinth追踪内容
| View | Contents |
|---|---|
| Journey index | Recent CLI, dashboard, gateway, cron, and delegated work |
| Labyrinth map | Ordered crossings through a selected agent journey |
| Inspector | Input, output, duration, status, evidence, guideposts per crossing |
| Guideposts | Generated observations backed by local evidence |
| Skill atlas | Bundled, optional, external, and user skill inventory |
| Cron gate | Scheduled autonomy, next runs, last failures, workdirs |
| Model ferry | Model/provider transitions across sessions |
| Reports | Redacted Markdown and JSON exports for one journey |
| 视图 | 内容 |
|---|---|
| 旅程索引 | 近期的CLI、仪表盘、网关、定时任务及委托任务 |
| Labyrinth地图 | 所选Agent旅程中的有序节点 |
| 检查器 | 每个节点的输入、输出、时长、状态、证据、指引标记 |
| 指引标记 | 基于本地证据生成的观测记录 |
| Skill图谱 | 内置、可选、外部及用户自定义Skill清单 |
| 定时任务网关 | 计划任务自动化、下次运行时间、最近失败记录、工作目录 |
| 模型切换器 | 跨会话的模型/提供商切换记录 |
| 报告 | 单旅程的脱敏Markdown和JSON导出文件 |
API Surface
API接口
All endpoints are read-only. The plugin API is served by Hermes dashboard at:
http://127.0.0.1:9119/api/plugins/hermes-labyrinth/所有接口均为只读。插件API由Hermes仪表盘提供,地址为:
http://127.0.0.1:9119/api/plugins/hermes-labyrinth/Endpoints
接口列表
GET /api/plugins/hermes-labyrinth/health
GET /api/plugins/hermes-labyrinth/journeys
GET /api/plugins/hermes-labyrinth/journeys/{journey_id}
GET /api/plugins/hermes-labyrinth/journeys/{journey_id}/crossings
GET /api/plugins/hermes-labyrinth/skills
GET /api/plugins/hermes-labyrinth/cron
GET /api/plugins/hermes-labyrinth/guideposts
GET /api/plugins/hermes-labyrinth/reports/{journey_id}.json
GET /api/plugins/hermes-labyrinth/reports/{journey_id}.mdGET /api/plugins/hermes-labyrinth/health
GET /api/plugins/hermes-labyrinth/journeys
GET /api/plugins/hermes-labyrinth/journeys/{journey_id}
GET /api/plugins/hermes-labyrinth/journeys/{journey_id}/crossings
GET /api/plugins/hermes-labyrinth/skills
GET /api/plugins/hermes-labyrinth/cron
GET /api/plugins/hermes-labyrinth/guideposts
GET /api/plugins/hermes-labyrinth/reports/{journey_id}.json
GET /api/plugins/hermes-labyrinth/reports/{journey_id}.mdExample: Fetch All Journeys
示例:获取所有旅程
bash
curl http://127.0.0.1:9119/api/plugins/hermes-labyrinth/journeys | jq .bash
curl http://127.0.0.1:9119/api/plugins/hermes-labyrinth/journeys | jq .Example: Fetch Crossings for a Journey
示例:获取某旅程的节点记录
bash
JOURNEY_ID="your-journey-id"
curl "http://127.0.0.1:9119/api/plugins/hermes-labyrinth/journeys/${JOURNEY_ID}/crossings" | jq .bash
JOURNEY_ID="your-journey-id"
curl "http://127.0.0.1:9119/api/plugins/hermes-labyrinth/journeys/${JOURNEY_ID}/crossings" | jq .Example: Export a Journey Report as Markdown
示例:导出旅程报告为Markdown格式
bash
JOURNEY_ID="your-journey-id"
curl "http://127.0.0.1:9119/api/plugins/hermes-labyrinth/reports/${JOURNEY_ID}.md" > report.mdbash
JOURNEY_ID="your-journey-id"
curl "http://127.0.0.1:9119/api/plugins/hermes-labyrinth/reports/${JOURNEY_ID}.md" > report.mdExample: Export a Journey Report as JSON
示例:导出旅程报告为JSON格式
bash
JOURNEY_ID="your-journey-id"
curl "http://127.0.0.1:9119/api/plugins/hermes-labyrinth/reports/${JOURNEY_ID}.json" > report.jsonbash
JOURNEY_ID="your-journey-id"
curl "http://127.0.0.1:9119/api/plugins/hermes-labyrinth/reports/${JOURNEY_ID}.json" > report.jsonExample: Health Check
示例:健康检查
bash
curl http://127.0.0.1:9119/api/plugins/hermes-labyrinth/healthbash
curl http://127.0.0.1:9119/api/plugins/hermes-labyrinth/healthPython API Client Examples
Python API客户端示例
The plugin backend lives at . You can also call the HTTP API from any language. Here are Python examples:
dashboard/plugin_api.pypython
import urllib.request
import json
BASE = "http://127.0.0.1:9119/api/plugins/hermes-labyrinth"
def get_journeys():
with urllib.request.urlopen(f"{BASE}/journeys") as r:
return json.loads(r.read())
def get_crossings(journey_id: str):
with urllib.request.urlopen(f"{BASE}/journeys/{journey_id}/crossings") as r:
return json.loads(r.read())
def get_report_json(journey_id: str):
with urllib.request.urlopen(f"{BASE}/reports/{journey_id}.json") as r:
return json.loads(r.read())
def get_report_md(journey_id: str) -> str:
with urllib.request.urlopen(f"{BASE}/reports/{journey_id}.md") as r:
return r.read().decode("utf-8")插件后端位于。你也可以用任意语言调用HTTP API。以下是Python示例:
dashboard/plugin_api.pypython
import urllib.request
import json
BASE = "http://127.0.0.1:9119/api/plugins/hermes-labyrinth"
def get_journeys():
with urllib.request.urlopen(f"{BASE}/journeys") as r:
return json.loads(r.read())
def get_crossings(journey_id: str):
with urllib.request.urlopen(f"{BASE}/journeys/{journey_id}/crossings") as r:
return json.loads(r.read())
def get_report_json(journey_id: str):
with urllib.request.urlopen(f"{BASE}/reports/{journey_id}.json") as r:
return json.loads(r.read())
def get_report_md(journey_id: str) -> str:
with urllib.request.urlopen(f"{BASE}/reports/{journey_id}.md") as r:
return r.read().decode("utf-8")Usage
使用示例
journeys = get_journeys()
for j in journeys:
print(j["id"], j.get("status"), j.get("started_at"))
undefinedjourneys = get_journeys()
for j in journeys:
print(j["id"], j.get("status"), j.get("started_at"))
undefinedIterate Crossings and Inspect Tool Calls
遍历节点并检查工具调用
python
import urllib.request
import json
BASE = "http://127.0.0.1:9119/api/plugins/hermes-labyrinth"
def inspect_tool_crossings(journey_id: str):
with urllib.request.urlopen(f"{BASE}/journeys/{journey_id}/crossings") as r:
crossings = json.loads(r.read())
for crossing in crossings:
if crossing.get("type") == "tool_call":
print(f"Tool: {crossing['tool']}")
print(f" Status: {crossing.get('status')}")
print(f" Duration: {crossing.get('duration_ms')}ms")
print(f" Input: {json.dumps(crossing.get('input', {}))[:200]}")
print()
inspect_tool_crossings("your-journey-id")python
import urllib.request
import json
BASE = "http://127.0.0.1:9119/api/plugins/hermes-labyrinth"
def inspect_tool_crossings(journey_id: str):
with urllib.request.urlopen(f"{BASE}/journeys/{journey_id}/crossings") as r:
crossings = json.loads(r.read())
for crossing in crossings:
if crossing.get("type") == "tool_call":
print(f"工具: {crossing['tool']}")
print(f" 状态: {crossing.get('status')}")
print(f" 时长: {crossing.get('duration_ms')}ms")
print(f" 输入: {json.dumps(crossing.get('input', {}))[:200]}")
print()
inspect_tool_crossings("your-journey-id")Download and Save All Reports for Recent Journeys
下载并保存近期旅程的所有报告
python
import urllib.request
import json
import pathlib
BASE = "http://127.0.0.1:9119/api/plugins/hermes-labyrinth"
OUT = pathlib.Path("./labyrinth-reports")
OUT.mkdir(exist_ok=True)
with urllib.request.urlopen(f"{BASE}/journeys") as r:
journeys = json.loads(r.read())
for j in journeys[:10]: # last 10 journeys
jid = j["id"]
try:
with urllib.request.urlopen(f"{BASE}/reports/{jid}.json") as r:
(OUT / f"{jid}.json").write_bytes(r.read())
with urllib.request.urlopen(f"{BASE}/reports/{jid}.md") as r:
(OUT / f"{jid}.md").write_bytes(r.read())
print(f"Saved reports for {jid}")
except Exception as e:
print(f"Failed {jid}: {e}")python
import urllib.request
import json
import pathlib
BASE = "http://127.0.0.1:9119/api/plugins/hermes-labyrinth"
OUT = pathlib.Path("./labyrinth-reports")
OUT.mkdir(exist_ok=True)
with urllib.request.urlopen(f"{BASE}/journeys") as r:
journeys = json.loads(r.read())
for j in journeys[:10]: # 最近10个旅程
jid = j["id"]
try:
with urllib.request.urlopen(f"{BASE}/reports/{jid}.json") as r:
(OUT / f"{jid}.json").write_bytes(r.read())
with urllib.request.urlopen(f"{BASE}/reports/{jid}.md") as r:
(OUT / f"{jid}.md").write_bytes(r.read())
print(f"已保存{jid}的报告")
except Exception as e:
print(f"{jid}保存失败: {e}")JavaScript / Frontend API Examples
JavaScript/前端API示例
The frontend plugin bundle lives in . If you're extending the UI or writing a custom integration:
dashboard/dist/javascript
const BASE = "http://127.0.0.1:9119/api/plugins/hermes-labyrinth";
async function fetchJourneys() {
const res = await fetch(`${BASE}/journeys`);
if (!res.ok) throw new Error(`HTTP ${res.status}`);
return res.json();
}
async function fetchCrossings(journeyId) {
const res = await fetch(`${BASE}/journeys/${journeyId}/crossings`);
if (!res.ok) throw new Error(`HTTP ${res.status}`);
return res.json();
}
async function fetchReportMarkdown(journeyId) {
const res = await fetch(`${BASE}/reports/${journeyId}.md`);
if (!res.ok) throw new Error(`HTTP ${res.status}`);
return res.text();
}
// Example: log all failed crossings in the most recent journey
async function logFailures() {
const journeys = await fetchJourneys();
if (!journeys.length) return;
const crossings = await fetchCrossings(journeys[0].id);
const failed = crossings.filter(c => c.status === "failure" || c.status === "error");
console.table(failed.map(c => ({
type: c.type,
tool: c.tool ?? "-",
duration_ms: c.duration_ms,
error: c.error?.slice(0, 120),
})));
}
logFailures();前端插件包位于。如果你要扩展UI或编写自定义集成:
dashboard/dist/javascript
const BASE = "http://127.0.0.1:9119/api/plugins/hermes-labyrinth";
async function fetchJourneys() {
const res = await fetch(`${BASE}/journeys`);
if (!res.ok) throw new Error(`HTTP ${res.status}`);
return res.json();
}
async function fetchCrossings(journeyId) {
const res = await fetch(`${BASE}/journeys/${journeyId}/crossings`);
if (!res.ok) throw new Error(`HTTP ${res.status}`);
return res.json();
}
async function fetchReportMarkdown(journeyId) {
const res = await fetch(`${BASE}/reports/${journeyId}.md`);
if (!res.ok) throw new Error(`HTTP ${res.status}`);
return res.text();
}
// 示例:记录最近一个旅程中所有失败的节点
async function logFailures() {
const journeys = await fetchJourneys();
if (!journeys.length) return;
const crossings = await fetchCrossings(journeys[0].id);
const failed = crossings.filter(c => c.status === "failure" || c.status === "error");
console.table(failed.map(c => ({
type: c.type,
tool: c.tool ?? "-",
duration_ms: c.duration_ms,
error: c.error?.slice(0, 120),
})));
}
logFailures();Build & Development
构建与开发
The frontend is built from + into . The demo is generated with content-hash query strings.
src/parts/*.jssrc/labyrinth.cssdashboard/dist/index.htmlbash
undefined前端代码从 + 构建到。演示用的会生成带内容哈希查询字符串的版本。
src/parts/*.jssrc/labyrinth.cssdashboard/dist/index.htmlbash
undefinedBuild dashboard/dist and index.html
构建dashboard/dist和index.html
npm run build
npm run build
Run reproducibility and parse checks
运行可复现性和语法检查
npm run check
npm run check
Run browser smoke tests (headless Chrome)
运行浏览器冒烟测试(无头Chrome)
npm run smoke
npm run smoke
Smoke-test the deployed GitHub Pages demo
对部署在GitHub Pages的演示版本进行冒烟测试
npm run smoke:live
npm run smoke:live
Run all tests (build checks, fixture tests, smoke)
运行所有测试(构建检查、测试用例测试、冒烟测试)
npm test
undefinednpm test
undefinedFull Test Suite
完整测试套件
bash
npm testRuns:
- Reproducible build checks for and
dashboard/distindex.html - Frontend JavaScript parse checks
- Backend Python parse checks
- API normalization fixture tests (including numeric Hermes timestamps)
- Packed-artifact and dead-control regressions
- Headless Chrome smoke coverage for map modes, route changes, search, dataset switching, and threshold filter
bash
npm test运行以下测试:
- 和
dashboard/dist的可复现构建检查index.html - 前端JavaScript语法检查
- 后端Python语法检查
- API标准化测试用例(包括Hermes的数字时间戳)
- 打包产物和无效控制流回归测试
- 无头Chrome冒烟测试,覆盖地图模式、路由切换、搜索、数据集切换和阈值过滤
Repository Layout
仓库结构
.
├── dashboard/
│ ├── manifest.json # Hermes dashboard plugin manifest
│ ├── plugin_api.py # Read-only API over local Hermes state
│ └── dist/ # Generated dashboard plugin bundle
├── docs/
│ ├── CONCEPT.md
│ ├── DESIGN_BRIEF.md
│ └── FUNCTIONAL_SPEC.md
├── scripts/
│ ├── build-plugin.mjs # Builds dashboard/dist and index.html
│ ├── smoke-demo.mjs # Browser smoke test for public demo
│ ├── test-plugin-api.py # Fixture tests for API normalization
│ └── verify.mjs # Local verification checks
├── src/
│ ├── demo/ # GitHub Pages demo source
│ ├── parts/ # Ordered frontend source chunks
│ └── labyrinth.css # Frontend CSS source
├── theme/
│ └── hermes-labyrinth.yaml
├── index.html # Generated GitHub Pages demo
└── package.json.
├── dashboard/
│ ├── manifest.json # Hermes仪表盘插件清单
│ ├── plugin_api.py # 基于本地Hermes状态的只读API
│ └── dist/ # 生成的仪表盘插件包
├── docs/
│ ├── CONCEPT.md
│ ├── DESIGN_BRIEF.md
│ └── FUNCTIONAL_SPEC.md
├── scripts/
│ ├── build-plugin.mjs # 构建dashboard/dist和index.html
│ ├── smoke-demo.mjs # 公开演示版本的浏览器冒烟测试
│ ├── test-plugin-api.py # API标准化的测试用例
│ └── verify.mjs # 本地验证检查
├── src/
│ ├── demo/ # GitHub Pages演示版本源码
│ ├── parts/ # 有序的前端源码片段
│ └── labyrinth.css # 前端CSS源码
├── theme/
│ └── hermes-labyrinth.yaml
├── index.html # 生成的GitHub Pages演示页面
└── package.jsonArchitecture
架构
Hermes local state
├─ state.db sessions/messages
├─ skills directories
└─ cron config
↓
dashboard/plugin_api.py
↓
/api/plugins/hermes-labyrinth/*
↓
src/parts/*.js + src/labyrinth.css
↓ npm run build
dashboard/dist/*
↓
Hermes dashboard tab: LabyrinthHermes本地状态
├─ state.db会话/消息
├─ skills目录
└─ cron配置
↓
dashboard/plugin_api.py
↓
/api/plugins/hermes-labyrinth/*
↓
src/parts/*.js + src/labyrinth.css
↓ npm run build
dashboard/dist/*
↓
Hermes仪表盘标签页: LabyrinthData Policy (Important)
数据政策(重要)
- Read-only by design: does not start, stop, resume, mutate, or create Hermes sessions.
- Secret redaction: applied to previews and reports.
- Unknown fields: stay unknown — not silently dropped.
- Reports: generated from local Hermes state only.
- Public demo: uses sample/mocked data — not live telemetry.
- 设计为只读:不会启动、停止、恢复、修改或创建Hermes会话。
- 敏感信息脱敏:应用于预览和报告中。
- 未知字段保留:不会被静默丢弃。
- 报告生成:仅基于本地Hermes状态生成。
- 公开演示:使用示例/模拟数据——无实时遥测数据。
Common Patterns
常见模式
Check Plugin Health Before Querying
查询前检查插件健康状态
python
import urllib.request, json
def is_labyrinth_healthy() -> bool:
try:
with urllib.request.urlopen(
"http://127.0.0.1:9119/api/plugins/hermes-labyrinth/health",
timeout=3
) as r:
data = json.loads(r.read())
return data.get("status") == "ok"
except Exception:
return False
if not is_labyrinth_healthy():
print("Labyrinth plugin not reachable — is `hermes dashboard` running?")python
import urllib.request, json
def is_labyrinth_healthy() -> bool:
try:
with urllib.request.urlopen(
"http://127.0.0.1:9119/api/plugins/hermes-labyrinth/health",
timeout=3
) as r:
data = json.loads(r.read())
return data.get("status") == "ok"
except Exception:
return False
if not is_labyrinth_healthy():
print("无法连接到Labyrinth插件——是否运行了`hermes dashboard`?")Filter Journeys by Type
按类型过滤旅程
python
import urllib.request, json
BASE = "http://127.0.0.1:9119/api/plugins/hermes-labyrinth"
with urllib.request.urlopen(f"{BASE}/journeys") as r:
journeys = json.loads(r.read())python
import urllib.request, json
BASE = "http://127.0.0.1:9119/api/plugins/hermes-labyrinth"
with urllib.request.urlopen(f"{BASE}/journeys") as r:
journeys = json.loads(r.read())Filter to only cron-triggered journeys
过滤仅定时任务触发的旅程
cron_journeys = [j for j in journeys if j.get("origin") == "cron"]
cron_journeys = [j for j in journeys if j.get("origin") == "cron"]
Filter to only failed journeys
过滤仅失败的旅程
failed_journeys = [j for j in journeys if j.get("status") in ("failure", "error")]
undefinedfailed_journeys = [j for j in journeys if j.get("status") in ("failure", "error")]
undefinedSummarize Crossing Types in a Journey
汇总某旅程的节点类型
python
from collections import Counter
import urllib.request, json
BASE = "http://127.0.0.1:9119/api/plugins/hermes-labyrinth"
def summarize_journey(journey_id: str):
with urllib.request.urlopen(f"{BASE}/journeys/{journey_id}/crossings") as r:
crossings = json.loads(r.read())
counts = Counter(c.get("type", "unknown") for c in crossings)
total_ms = sum(c.get("duration_ms", 0) for c in crossings)
print(f"Journey {journey_id}: {len(crossings)} crossings, {total_ms}ms total")
for ctype, n in counts.most_common():
print(f" {ctype}: {n}")python
from collections import Counter
import urllib.request, json
BASE = "http://127.0.0.1:9119/api/plugins/hermes-labyrinth"
def summarize_journey(journey_id: str):
with urllib.request.urlopen(f"{BASE}/journeys/{journey_id}/crossings") as r:
crossings = json.loads(r.read())
counts = Counter(c.get("type", "unknown") for c in crossings)
total_ms = sum(c.get("duration_ms", 0) for c in crossings)
print(f"旅程{journey_id}: {len(crossings)}个节点,总时长{total_ms}ms")
for ctype, n in counts.most_common():
print(f" {ctype}: {n}")Troubleshooting
故障排除
Plugin tab not appearing in dashboard
插件标签页未在仪表盘中显示
- Confirm clone location:
ls ~/.hermes/plugins/hermes-labyrinth/dashboard/manifest.json - Restart or rescan:
hermes dashboardcurl http://127.0.0.1:9119/api/dashboard/plugins/rescan - Check is valid JSON.
manifest.json
- 确认克隆位置:
ls ~/.hermes/plugins/hermes-labyrinth/dashboard/manifest.json - 重启或重新扫描:
hermes dashboardcurl http://127.0.0.1:9119/api/dashboard/plugins/rescan - 检查是否为有效的JSON文件。
manifest.json
API returns 404
API返回404错误
- Verify the plugin loaded:
curl http://127.0.0.1:9119/api/plugins/hermes-labyrinth/health - Confirm is running on port
hermes dashboard.9119
- 验证插件是否加载:
curl http://127.0.0.1:9119/api/plugins/hermes-labyrinth/health - 确认在端口
hermes dashboard运行。9119
Build artifacts out of date
构建产物过期
bash
npm run buildbash
npm run buildThen verify reproducibility
然后验证可复现性
npm run check
undefinednpm run check
undefinedSmoke tests fail locally
冒烟测试在本地失败
- Requires headless Chrome/Chromium available in .
PATH - Run for local,
npm run smokefor the deployed Pages demo.npm run smoke:live
- 需要在中提供无头Chrome/Chromium。
PATH - 运行进行本地测试,运行
npm run smoke测试部署在Pages的演示版本。npm run smoke:live
Reports contain redacted fields
报告包含脱敏字段
This is expected. Labyrinth applies secret redaction to all previews and exports by design. Raw values are only accessible inside the Hermes process itself.
这是预期行为。Labyrinth设计上会对所有预览和导出内容进行敏感信息脱敏。原始值仅能在Hermes进程内部访问。
Numeric timestamps in API responses
API响应中的数字时间戳
The API normalization layer handles numeric Hermes timestamps automatically (covered by fixture tests in ). If you consume the API directly, expect either ISO 8601 strings or Unix epoch integers in timestamp fields.
scripts/test-plugin-api.pyAPI标准化层会自动处理Hermes的数字时间戳(由中的测试用例覆盖)。如果直接调用API,时间戳字段可能是ISO 8601字符串或Unix时间戳整数。
scripts/test-plugin-api.pyLinks
链接
- Live demo: https://stainlu.github.io/hermes-labyrinth/
- Hermes Agent: https://github.com/NousResearch/hermes-agent
- Release v0.1.0: https://github.com/stainlu/hermes-labyrinth/releases/tag/v0.1.0
- License: MIT
- 在线演示:https://stainlu.github.io/hermes-labyrinth/
- Hermes Agent:https://github.com/NousResearch/hermes-agent
- v0.1.0版本发布:https://github.com/stainlu/hermes-labyrinth/releases/tag/v0.1.0
- 许可证:MIT