mio-agent-runtime 0.3.4 → 0.3.6
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +102 -79
- package/adapters/hermes.js +90 -0
- package/bin/mio.js +255 -247
- package/observe/observer.js +576 -1
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -1,79 +1,102 @@
|
|
|
1
|
-
# mio-agent-runtime
|
|
2
|
-
|
|
3
|
-
Mio Agent Runtime 的可发布 CLI 包。
|
|
4
|
-
|
|
5
|
-
安装一次,所有 Agent 自动接入 Mio。
|
|
6
|
-
|
|
7
|
-
## Install
|
|
8
|
-
|
|
9
|
-
```bash
|
|
10
|
-
npm install -g mio-agent-runtime
|
|
11
|
-
```
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
mio
|
|
21
|
-
mio
|
|
22
|
-
mio
|
|
23
|
-
mio
|
|
24
|
-
mio
|
|
25
|
-
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
|
|
29
|
-
|
|
30
|
-
|
|
31
|
-
|
|
32
|
-
|
|
33
|
-
|
|
34
|
-
|
|
35
|
-
|
|
36
|
-
|
|
37
|
-
|
|
38
|
-
|
|
39
|
-
|
|
40
|
-
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
1
|
+
# mio-agent-runtime
|
|
2
|
+
|
|
3
|
+
Mio Agent Runtime 的可发布 CLI 包。
|
|
4
|
+
|
|
5
|
+
安装一次,所有 Agent 自动接入 Mio。
|
|
6
|
+
|
|
7
|
+
## Install
|
|
8
|
+
|
|
9
|
+
```bash
|
|
10
|
+
npm install -g mio-agent-runtime
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
> 新机器 / 升级:请安装 `>=0.3.6`(Codex + OpenCode + Hermes 被动观察)。
|
|
14
|
+
> 旧版本只有主动 MCP 规则注入,没有「无感存/取」。安装后执行一次
|
|
15
|
+
> `mio init && mio install <host>`。
|
|
16
|
+
|
|
17
|
+
## Commands
|
|
18
|
+
|
|
19
|
+
```text
|
|
20
|
+
mio init Initialize MIO_HOME
|
|
21
|
+
mio mcp Start Mio MCP server (stdio)
|
|
22
|
+
mio install <host> Install Mio into a host (codex|opencode|workbuddy)
|
|
23
|
+
mio status Show runtime and adapter status
|
|
24
|
+
mio agents List installed agents
|
|
25
|
+
mio observe Watch WorkBuddy transcripts and auto-ingest task outcomes (foreground)
|
|
26
|
+
mio observe --start|--stop|--status|--once Manage the background observer daemon
|
|
27
|
+
mio --json status Machine-readable status
|
|
28
|
+
mio --json agents Machine-readable agents
|
|
29
|
+
```
|
|
30
|
+
|
|
31
|
+
## Host notes
|
|
32
|
+
|
|
33
|
+
- OpenCode uses `~/.config/opencode/opencode.json` for MCP registration and
|
|
34
|
+
`~/.config/opencode/AGENTS.md` for global instructions. `mio install opencode`
|
|
35
|
+
writes both files and injects Mio usage rules into `AGENTS.md` so OpenCode
|
|
36
|
+
calls Mio memory/observer/policy automatically. If OpenCode is already
|
|
37
|
+
running, restart it once so it reloads both files. `mio observe` also
|
|
38
|
+
passively tails the OpenCode session database (`opencode db`) without
|
|
39
|
+
requiring the model to call Mio tools.
|
|
40
|
+
- Hermes uses `hermes mcp add mio-intelligence --command node --args <server>`
|
|
41
|
+
to register the Mio MCP server. Hermes has native memory and reads
|
|
42
|
+
AGENTS.md Context Files, so retrieval works without Mio rule injection.
|
|
43
|
+
- WorkBuddy uses `~/.workbuddy/mcp.json` and requires each custom MCP server to
|
|
44
|
+
be approved in `~/.workbuddy/mcp-approvals.json`. `mio install workbuddy`
|
|
45
|
+
writes both files and injects Mio usage rules into
|
|
46
|
+
`~/.workbuddy/CODEBUDDY.md` (user-level memory rules, auto-loaded by
|
|
47
|
+
WorkBuddy into every session; the CLI hardcodes the CodeBuddy product name, so the file is CODEBUDDY.md not WORKBUDDY.md) plus `<workspace>/AGENTS.md` (project-level).
|
|
48
|
+
If WorkBuddy is already running, restart it once so it reloads the approval
|
|
49
|
+
and memory rule files.
|
|
50
|
+
|
|
51
|
+
## Passive observer (`mio observe`)
|
|
52
|
+
|
|
53
|
+
WorkBuddy 的默认模型不一定会主动调用 Mio MCP 工具,即使规则已注入
|
|
54
|
+
(`CODEBUDDY.md` / `AGENTS.md`)。`mio observe` 是一个不依赖模型自觉的
|
|
55
|
+
兜底:它持续监听 `~/.workbuddy/projects/**/*.jsonl` 会话记录,把每个任务的
|
|
56
|
+
结果(`task_outcome`)、工具调用错误(`error`)以及完成任务的摘要自动写入
|
|
57
|
+
`MIO_HOME/traces.jsonl` 和 `MIO_HOME/memory.jsonl`(与 MCP 服务同一套
|
|
58
|
+
schema,`source=workbuddy-observer`)。
|
|
59
|
+
|
|
60
|
+
- `mio install <host>` 会自动执行一次回填并启动后台观察器。
|
|
61
|
+
|
|
62
|
+
- 除了写入 `MIO_HOME`,观察器还会把任务摘要**写回 WorkBuddy 自己的记忆文件**
|
|
63
|
+
(`<workspace>/.workbuddy/memory/YYYY-MM-DD.md`,标为 `## Mio 自动摘要`)。
|
|
64
|
+
WorkBuddy 的系统提示要求模型每次会话维护并阅读这些文件,所以下一次会话
|
|
65
|
+
WorkBuddy 会**被动取到** Mio 记录的内容——单 Agent 的「存 + 取」闭环不依赖
|
|
66
|
+
模型调用 Mio 工具。
|
|
67
|
+
- 已处理的文件偏移记录在 `MIO_HOME/observe-state.json`,不会重复写入。
|
|
68
|
+
- 只回填最近 24h 内更新的会话,避免把历史记录灌入记忆库。
|
|
69
|
+
|
|
70
|
+
OpenCode 会话不依赖模型自觉:`mio observe` 通过 `opencode db` 增量读取
|
|
71
|
+
`~/.local/share/opencode/opencode.db`(Windows 下该文件被 OpenCode 独占锁定,
|
|
72
|
+
必须经 opencode 自带 CLI 读取),按 `part` 表的 rowid 做增量游标,只传输
|
|
73
|
+
`text`/`tool` 两种 part,把每个用户回合的 `task_outcome` 与工具错误写入
|
|
74
|
+
`MIO_HOME/traces.jsonl` / `memory.jsonl`(`source=opencode-observer`),并同样
|
|
75
|
+
把摘要写回 `<workspace>/AGENTS.md` 的 `MIO_CONTEXT` 块,供 OpenCode 下一会话
|
|
76
|
+
被动取用。首次启动只回填最近 24h 的 part,避免历史会话灌入记忆库。
|
|
77
|
+
|
|
78
|
+
Hermes(Nous hermes-agent)同理:`mio observe` 以只读方式增量读取
|
|
79
|
+
`<LocalAppData>/hermes/state.db`(`messages.id` 自增游标,无需调用 hermes CLI),
|
|
80
|
+
把每个用户回合的 `task_outcome` 写入 `MIO_HOME`(`source=hermes-observer`)。
|
|
81
|
+
Hermes 本身有原生记忆,Mio 只负责让 Hermes 经验进入跨 Agent 生态;仅当会话
|
|
82
|
+
发生在真实 git 仓库时才写回该仓库的 `AGENTS.md`,避免污染用户主目录。
|
|
83
|
+
|
|
84
|
+
## MIO_HOME
|
|
85
|
+
|
|
86
|
+
默认 `~/.mio-intelligence`,可通过环境变量 `MIO_HOME` 覆盖。
|
|
87
|
+
|
|
88
|
+
## Package layout
|
|
89
|
+
|
|
90
|
+
```text
|
|
91
|
+
packages/mio-cli
|
|
92
|
+
├── bin/mio.js
|
|
93
|
+
├── adapters/
|
|
94
|
+
│ ├── codex.js
|
|
95
|
+
│ ├── opencode.js
|
|
96
|
+
│ └── workbuddy.js
|
|
97
|
+
├── observe/
|
|
98
|
+
│ └── observer.js
|
|
99
|
+
├── server/
|
|
100
|
+
│ └── mio-intelligence-mcp/index.js
|
|
101
|
+
└── package.json
|
|
102
|
+
```
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
'use strict'
|
|
2
|
+
|
|
3
|
+
const fs = require('fs')
|
|
4
|
+
const path = require('path')
|
|
5
|
+
const os = require('os')
|
|
6
|
+
const { spawnSync } = require('child_process')
|
|
7
|
+
|
|
8
|
+
const SERVER_NAME = 'mio-intelligence'
|
|
9
|
+
|
|
10
|
+
function hermesBin() {
|
|
11
|
+
if (process.env.HERMES_BIN && fs.existsSync(process.env.HERMES_BIN)) return process.env.HERMES_BIN
|
|
12
|
+
const candidates = [
|
|
13
|
+
path.join(os.homedir(), 'AppData', 'Local', 'hermes', 'hermes-agent', 'bin', 'hermes.exe'),
|
|
14
|
+
path.join(os.homedir(), '.hermes', 'bin', 'hermes.exe'),
|
|
15
|
+
]
|
|
16
|
+
for (const c of candidates) {
|
|
17
|
+
if (fs.existsSync(c)) return c
|
|
18
|
+
}
|
|
19
|
+
return null
|
|
20
|
+
}
|
|
21
|
+
|
|
22
|
+
function runHermes(args) {
|
|
23
|
+
const bin = hermesBin()
|
|
24
|
+
// `hermes mcp add` asks to confirm tool enablement interactively; pre-answer
|
|
25
|
+
// it so the install is non-interactive.
|
|
26
|
+
const input = args[0] === 'mcp' && args[1] === 'add' ? 'Y\n' : undefined
|
|
27
|
+
let res
|
|
28
|
+
try {
|
|
29
|
+
res = bin
|
|
30
|
+
? spawnSync(bin, args, { encoding: 'utf8', timeout: 60000, windowsHide: true, input: input })
|
|
31
|
+
: spawnSync('hermes', args, { encoding: 'utf8', timeout: 60000, shell: true, windowsHide: true, input: input })
|
|
32
|
+
} catch (_) {
|
|
33
|
+
return null
|
|
34
|
+
}
|
|
35
|
+
if (res.error || res.status !== 0) return null
|
|
36
|
+
return (res.stdout || '') + (res.stderr || '')
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
function isInstalled() {
|
|
40
|
+
const out = runHermes(['mcp', 'list'])
|
|
41
|
+
return Boolean(out && out.indexOf(SERVER_NAME) !== -1)
|
|
42
|
+
}
|
|
43
|
+
|
|
44
|
+
function install({ node, serverScript, home, workspace, project }) {
|
|
45
|
+
if (!hermesBin() && !isHermesOnPath()) {
|
|
46
|
+
return {
|
|
47
|
+
changed: false,
|
|
48
|
+
message: 'Hermes binary not found. Install hermes-agent first.',
|
|
49
|
+
configPath: null,
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
if (isInstalled()) {
|
|
53
|
+
return { changed: false, message: 'Hermes Mio MCP already installed.', configPath: null }
|
|
54
|
+
}
|
|
55
|
+
|
|
56
|
+
const context = JSON.stringify({
|
|
57
|
+
agentId: 'hermes',
|
|
58
|
+
project: project || path.basename(workspace || process.cwd()),
|
|
59
|
+
workspace: workspace || process.cwd(),
|
|
60
|
+
sessionId: 'hermes-session',
|
|
61
|
+
})
|
|
62
|
+
|
|
63
|
+
const args = [
|
|
64
|
+
'mcp', 'add', SERVER_NAME,
|
|
65
|
+
'--command', node,
|
|
66
|
+
'--args', serverScript,
|
|
67
|
+
'--env', 'MIO_DATA_DIR=' + home, 'MIO_CONTEXT=' + context,
|
|
68
|
+
]
|
|
69
|
+
const out = runHermes(args)
|
|
70
|
+
const installed = isInstalled()
|
|
71
|
+
|
|
72
|
+
let message
|
|
73
|
+
if (installed) {
|
|
74
|
+
message = 'Hermes Mio MCP installed (config: <LocalAppData>/hermes/config.yaml). Start a new Hermes session to load it.'
|
|
75
|
+
} else {
|
|
76
|
+
message = 'Hermes mcp add returned but Mio was not detected. Run `hermes mcp add ' + SERVER_NAME + ' --command ' + node + ' --args ' + serverScript + '` manually and answer Y to the prompt.'
|
|
77
|
+
}
|
|
78
|
+
return { changed: installed, configPath: null, message }
|
|
79
|
+
}
|
|
80
|
+
|
|
81
|
+
function isHermesOnPath() {
|
|
82
|
+
try {
|
|
83
|
+
const res = spawnSync('where', ['hermes'], { encoding: 'utf8', shell: true })
|
|
84
|
+
return res.status === 0 && /hermes/.test(res.stdout || '')
|
|
85
|
+
} catch (_) {
|
|
86
|
+
return false
|
|
87
|
+
}
|
|
88
|
+
}
|
|
89
|
+
|
|
90
|
+
module.exports = { hermesBin, isInstalled, install }
|