⛅ Sync 2026-09-03 23:42:31

This commit is contained in:
github-actions[bot] committed 2026-09-03 23:42:31 +08:00
1 parent 58f9300b4a
commit 92c3e430e5
17 files changed
+395 -22

No files matched your search

+1 -1
View File
@@ -15,7 +15,7 @@ AGENTFLOW_HASH_aarch64:=6d733ebc49b095bf8670a1b655a13bb8ad98c90ced19701b67d5cdd4
PKG_NAME:=agentflow
PKG_VERSION:=0.3.0
PKG_RELEASE:=5
PKG_RELEASE:=6
AGENTFLOW_URL_FILE:=agentflow-linux-$(AGENTFLOW_ARCH)
AGENTFLOW_DOWNLOAD:=$(AGENTFLOW_URL_FILE)-$(AGENTFLOW_HASH_$(ARCH))
@@ -0,0 +1,84 @@
# AgentFlow 共享 Runtime HOME 实施里程碑
## 目标架构
AgentFlow 的应用数据和设备级开发运行时分离:
- AgentFlow 数据目录:`<quickstart.conf_dir>/AgentFlow`
- 共享 Runtime HOME:`<quickstart.conf_dir>/Runtime/home`
共享 Runtime HOME 由 `mise` 包提供公共 helper 初始化,AgentFlow 和后续运行时感知应用复用同一套 `HOME`、XDG、`MISE_*` 和 `PATH`。
## Milestone 1:公共 Runtime HOME 合约
目标:
- `mise` 包安装 `/etc/config/mise`。
- `mise` 包安装 `/lib/functions/istore_runtime.sh`。
- helper 自动从 `quickstart.main.conf_dir` 推导 `<conf_dir>/Runtime/home`。
- helper 支持 `ISTORE_RUNTIME_CONF_DIR` 兜底,便于应用从自身 Configs 目录派生 Runtime。
- helper 统一导出 `HOME`、`XDG_DATA_HOME`、`XDG_CACHE_HOME`、`XDG_CONFIG_HOME`、`XDG_STATE_HOME`、`MISE_DATA_DIR`、`MISE_CACHE_DIR`、`MISE_CONFIG_DIR`、`MISE_STATE_DIR` 和 `PATH`。
验收:
- 新安装 `mise` 后,存在 `/etc/config/mise` 和 `/lib/functions/istore_runtime.sh`。
- 已配置 quickstart 时,初始化路径为 `<quickstart.conf_dir>/Runtime/home`。
- 未配置 quickstart 但应用提供 `ISTORE_RUNTIME_CONF_DIR` 时,初始化路径为 `$ISTORE_RUNTIME_CONF_DIR/Runtime/home`。
## Milestone 2:AgentFlow 接入共享 Runtime HOME
目标:
- AgentFlow 不再使用 `$data_dir/global` 作为 `HOME` 或 mise shim 根。
- AgentFlow 启动时调用 `istore_runtime_export_env`。
- `AGENT_FLOW_DATA` 继续固定在 AgentFlow 数据目录下的 `data` 子目录。
- AgentFlow 服务进程及其子进程继承共享 Runtime HOME。
验收:
- `/etc/init.d/agentflow start` 后,AgentFlow 进程环境中 `HOME=<conf_dir>/Runtime/home`。
- `MISE_DATA_DIR=$HOME/.local/share/mise`。
- `PATH` 以 `$MISE_DATA_DIR/shims:$HOME/.local/bin` 开头。
- AgentFlow 数据库仍写入 `<conf_dir>/AgentFlow/data/db/db.sqlite`。
## Milestone 3:LuCI 可见性
目标:
- AgentFlow LuCI 页面继续配置 AgentFlow 数据目录。
- 页面展示推导出的共享 Runtime HOME。
- 如果 `mise.runtime_dir` 被显式设置,页面展示其对应的 `home`。
验收:
- quickstart `conf_dir=/mnt/vio3-1/Configs` 时,页面显示 `/mnt/vio3-1/Configs/Runtime/home`。
- AgentFlow 数据目录仍显示 `/mnt/vio3-1/Configs/AgentFlow`。
## Milestone 4:迁移与兼容
目标:
- 新安装默认使用共享 Runtime HOME。
- 老安装中已有 `$data_dir/global/.local/share/mise` 时,不自动移动大目录。
- 后续提供显式迁移命令或 LuCI 操作。
验收:
- 升级不会删除或搬移旧 runtime 数据。
- 用户确认迁移后,旧 mise data 可迁移到 `<conf_dir>/Runtime/home/.local/share/mise`。
- 迁移失败不会影响 AgentFlow 私有数据。
## Milestone 5:AgentFlow 后端项目环境集成
目标:
- OpenWrt 层面完成共享 HOME 后,再在 AgentFlow 后端引入项目环境 wrapper。
- coding agent 进程使用 `mise exec -- <agent> ...` 应用项目 `mise.toml`。
- 运行期设置 `MISE_EXEC_AUTO_INSTALL=0`,缺失工具只在准备阶段安装。
验收:
- 单 repo 项目中,agent 看到项目声明的 Node/Python/Go 版本。
- 没有隐式运行期下载。
- Codex/Claude/Kimi 等 agent 凭据继续来自共享 Runtime HOME。
- 取消任务时 wrapper 和 agent 子进程都能退出。
+31 -8
View File
@@ -10,11 +10,20 @@ get_config() {
config_get port "$1" port "9000"
}
set_mise_env() {
procd_set_param env \
"$@" \
HOME="$data_dir/global" \
PATH="$data_dir/global/.local/share/mise/shims:$PATH"
load_runtime_env() {
local conf_dir
[ -n "$data_dir" ] || return 1
conf_dir="$(dirname "$data_dir")"
export ISTORE_RUNTIME_CONF_DIR="$conf_dir"
if [ -r /lib/functions/istore_runtime.sh ]; then
. /lib/functions/istore_runtime.sh
istore_runtime_export_env
return $?
fi
return 1
}
start_service() {
@@ -26,15 +35,29 @@ start_service() {
logger -t agentflow "missing executable: /usr/sbin/agentflow"
return 1
}
mkdir -p "$data_dir" "$data_dir/global" || return 1
mkdir -p "$data_dir" "$data_dir/data" || return 1
if ! load_runtime_env; then
logger -t agentflow "shared runtime home is not configured"
return 1
fi
logger -t agentflow "starting AgentFlow on $host:$port"
procd_open_instance
procd_set_param command /usr/sbin/agentflow
set_mise_env \
procd_set_param env \
"AGENT_FLOW_DATA=$data_dir/data" \
"AGENT_FLOW_HOST=$host" \
"AGENT_FLOW_PORT=$port"
"AGENT_FLOW_PORT=$port" \
"HOME=$HOME" \
"XDG_DATA_HOME=$XDG_DATA_HOME" \
"XDG_CACHE_HOME=$XDG_CACHE_HOME" \
"XDG_CONFIG_HOME=$XDG_CONFIG_HOME" \
"XDG_STATE_HOME=$XDG_STATE_HOME" \
"MISE_DATA_DIR=$MISE_DATA_DIR" \
"MISE_CACHE_DIR=$MISE_CACHE_DIR" \
"MISE_CONFIG_DIR=$MISE_CONFIG_DIR" \
"MISE_STATE_DIR=$MISE_STATE_DIR" \
"PATH=$PATH"
procd_set_param stdout 1
procd_set_param stderr 1
procd_set_param respawn
@@ -0,0 +1,65 @@
from pathlib import Path
import unittest
ROOT = Path(__file__).resolve().parents[3]
APPLICATIONS = ROOT / "applications"
def read(relative):
return (APPLICATIONS / relative).read_text()
class MiseRuntimeContractTest(unittest.TestCase):
def test_mise_package_installs_shared_runtime_contract(self):
makefile = read("mise/Makefile")
config = read("mise/files/mise.config")
defaults = read("mise/files/mise.uci-default")
helper = read("mise/files/istore_runtime.sh")
self.assertIn("/etc/config/mise", makefile)
self.assertIn("/lib/functions/istore_runtime.sh", makefile)
self.assertIn("$(INSTALL_BIN) ./files/mise.uci-default", makefile)
self.assertIn("[ -f /etc/uci-defaults/mise ]", makefile)
self.assertIn("config mise 'main'", config)
self.assertIn("option runtime_dir ''", config)
self.assertIn("option auto_discover '1'", config)
self.assertIn(". /lib/functions/istore_runtime.sh", defaults)
self.assertIn("istore_runtime_init", defaults)
self.assertIn("config_get conf_dir main conf_dir", helper)
self.assertIn('"$conf_dir" "$ISTORE_RUNTIME_DEFAULT_SUBDIR"', helper)
self.assertIn("ISTORE_RUNTIME_HOME_SUBDIR=\"home\"", helper)
self.assertIn("ISTORE_RUNTIME_CONF_DIR", helper)
self.assertIn('export HOME="$runtime_home"', helper)
self.assertIn('export XDG_DATA_HOME="$HOME/.local/share"', helper)
self.assertIn('export MISE_DATA_DIR="$XDG_DATA_HOME/mise"', helper)
self.assertIn('export PATH="$MISE_DATA_DIR/shims:$HOME/.local/bin:$PATH"', helper)
def test_agentflow_consumes_shared_runtime_home(self):
init = read("agentflow/files/agentflow.init")
cbi = read("luci-app-agentflow/luasrc/model/cbi/agentflow.lua")
model = read("luci-app-agentflow/luasrc/model/agentflow.lua")
translations = read("luci-app-agentflow/po/zh-cn/agentflow.po")
self.assertIn(". /lib/functions/istore_runtime.sh", init)
self.assertIn("istore_runtime_export_env", init)
self.assertIn('AGENT_FLOW_DATA=$data_dir/data', init)
self.assertIn('HOME=$HOME', init)
self.assertIn('MISE_DATA_DIR=$MISE_DATA_DIR', init)
self.assertNotIn("$data_dir/global", init)
self.assertNotIn(".local/share/mise/shims:$PATH", init)
self.assertIn('translate("Shared runtime home")', cbi)
self.assertIn("agentflow_model.runtime_home", cbi)
self.assertIn('return runtime_dir .. "/home"', model)
self.assertIn('return conf_dir .. "/Runtime"', model)
self.assertIn('msgid "Shared runtime home"', translations)
self.assertIn('msgstr "共享运行时 HOME"', translations)
if __name__ == "__main__":
unittest.main()