@yuandc/aica-proxy
v0.1.12
Published
Optional ACA Worker version manager
Readme
AICA Proxy
可选的 ACA Worker 版本管理器。独立 Worker 仍可照常使用;Proxy 包本身没有 Worker 或 Codex 运行依赖。
支持 Linux、Node.js 22+、npm 和 flock,可接管 npm 全局安装、专用 prefix 安装和运行中的 npx Worker。Server 和 Worker 都需要包含管理协议 v1;旧 Worker 不会被自动停止。Windows、单文件 Worker 和源码启动暂不支持自动维护。
接入
先启动支持管理协议的 Worker(npm 全局安装或 npx @yuandc/aica@latest daemon start),然后直接启动包含 npx 支持的 Proxy 版本,无需手动配置:
npx @yuandc/aica-proxy@latest daemon restart也可以全局安装 Proxy 后启动:
npm install -g @yuandc/aica-proxy
aica-proxy daemon start
aica-proxy daemon status未配置时,Proxy 优先通过当前 AICA_HOME 的本地管理通道识别正在运行的 npx Worker;没有 npx 实例时检测当前 npm prefix -g 下的 Worker。验证包身份、进程身份和命令入口后,将安装位置保存到 <AICA_HOME>/proxy/config.json。已有配置始终优先。service print 和 update 命令也使用相同发现规则,但迁移只由运行中的 Proxy 执行。
只有自定义安装目录或 Registry 才需要 configure。专用 prefix 安装不传 --global,例如 aica-proxy configure --worker-prefix /opt/aica-worker;其他全局 prefix 使用 aica-proxy configure --worker-prefix /path/to/prefix --global。自定义 Worker 配置使用与 Worker 相同的 AICA_HOME、AICA_CONFIG;旧的 ACA_HOME、ACA_CONFIG 环境变量也兼容,默认继续使用 ~/.aica 中的登录信息。
npx @yuandc/aica-proxy daemon restart 同样可用:npx 启动时会把这个无运行依赖的小包复制到 <AICA_HOME>/proxy/runtime/<Proxy版本>/,避免常驻进程依赖临时 npm 缓存。这不是另存一套 Worker。
aica-proxy update check # 查询 Registry 并通知运行中的 Proxy 检查
aica-proxy update retry # 清除失败目标隔离,等待当前工作结束
aica-proxy daemon logs
aica-proxy daemon restart # 重启管理进程,正常运行的 Worker 保持运行
aica-proxy daemon stop # 在安全边界停止管理,正常运行的 Worker 保持运行人工执行 aica daemon stop/restart 会与管理入口协调。安装期间拒绝人工启动/重启;明确人工停止的 Worker 不会立即被 Proxy 拉起,需要使用 aica daemon start 恢复。发现原 Worker 不在运行且没有人工停止记录时,Proxy 可使用显式暂停启动入口拉起已安装 Worker。
npx Worker 接管
首次接管时保持原 npx Worker 和安装目录不变,按常规策略检查补丁更新。没有可升级的新补丁时,不迁移、不重装、不等待空闲。发现新补丁后,保持设备正常领取各会话任务;本机空闲后先将新版及依赖完整安装到 <AICA_HOME>/proxy/versions/<版本>-<随机标识>/,并把 npx 原版的完整依赖树复制到另一保留目录。准备失败、空间或写入检查失败时不停止 Worker。只有准备完成、Server 与本机均确认空闲且在途请求排空后,才停止原实例并切换到已经安装好的新版,继续复用原登录信息和运行数据。
已是最新版本时,不显示“待空闲升级”或“待空闲迁移”。旧 Proxy 遗留的同版本 preparing/waiting 计划会自动取消;等待期间若人工更新使原升级计划失效,也会清除旧计划。已经停机或安装中的事务仍完成安全恢复,避免 Worker 停留在不可用状态。
Proxy 直接通过管理心跳向 Server 上报更新检查结果,不依赖 Worker 转发。检查中、检查失败和等待空闲会显示在设备/会话列表;设备详情显示 Registry 版本、最近成功查询时间和失败原因。检查失败不会触发 Worker 停机;没有可升级版本时不会显示等待空闲。需更新 Proxy 常驻进程及 Server/Web 才能使用完整展示,单独执行新版 npx CLI 不会替换旧常驻进程。上报失败时仍可用 daemon status / daemon logs 查看本地状态。
“待空闲升级”以整台 Worker 当前正在执行的工作为准。设备详情的“等待原因”列出尚未结束的任务、文件传输、设备操作和终端进程。普通长轮询和终端通道连接不算忙碌;已经创建且尚未退出的终端 Shell 仍保留保护,不能仅凭暂时没有输出判定其中的程序已结束。历史上传失败、收尾异常和领取回执失效只保留为告警,不再要求先修复历史异常才能升级。告警可在 Proxy 日志和本地 state.json 的 warnings 中查看,Worker 原始诊断仍保留。
切换仍有停止和启动进程的短暂窗口,但新升级事务在停机期间不执行 npm 安装。新版启动失败或退出检查失败时,立即进入原版恢复;使用保留的本地安装,不重新下载或安装依赖。已失败的目标被隔离,需显式 retry 才重试该版本。激活回执不确定时先查实际状态,保留已开始工作的实例;确认候选退出后恢复原版。Proxy 重启会继续事务,并优先核对实际存活的候选,避免因旧 PID 记录而循环启动重复实例。
实际 Worker 版本及安装位置以 daemon status 的 version、activeConfig 为准;原 npm 安装和全局 CLI 不被覆盖。通过原 CLI 人工重启会启动该 CLI 对应的版本,Proxy 在验证后重新跟踪该实例。版本目录和原 npx 缓存均保留,不自动删除可能仍被后台进程使用的资源;磁盘不足会推迟下一次升级。没有存活实例且 npx 缓存已经丢失时,仍可能需要联网恢复,这是故障恢复路径。旧版遗留的原目录安装事务继续兼容处理,不能补造此前不存在的回退副本。
首次自动发现需要 npx Worker 正在运行并支持管理协议,不扫描历史 npm 缓存猜测目标。迁移成功后,Proxy 可以直接从稳定目录恢复 Worker,后续更新不依赖原缓存。再次人工通过 npx 启动同一 AICA_HOME 的 Worker 时,npx 管理模式会重新验证来源,仍只在发现新补丁时等待空闲升级。显式配置其他安装目录的 Proxy 则仍遵循原配置。
更新与恢复
- 默认查询 npm 官方 Registry,约每 15 分钟检查一次,附带随机延迟;可在 configure 时通过
--registry指定镜像。 - 版本检查兼容 npm 返回字符串或单元素数组(包括 npm 12);空值、多版本或格式异常会明确报错,不猜测升级目标,也不会因此停止 Worker。
- 仅自动更新同一主版本、次版本内的稳定补丁版本。准备好升级包后继续正常领取和执行用户任务;有运行中或排队的 Job 时继续等待,用户使用优先。持续有工作时升级可以持续推迟。
- 后台缓存目标和旧版的 npm 包。新升级事务在停止 Worker 前,完整安装新版及依赖并验证原版保留入口;空间不足、inode 不足或状态目录写入失败都会暂缓升级。检查在准备前及最终停机提交前重复执行;至少保留 256 MiB 可用空间及 64 个空闲 inode,这只是切换余量,安装本身失败同样不会触发停机。
- Server 支持
user-priority-claim-recovery时,等待阶段不封锁任何领取通道。只有本机实际活动及 Server 上的运行中、排队 Job 均已清空,才进入可撤销的排空阶段;此时新增 Job 会立即恢复领取,图片读取、打开终端和设备操作也可以取消准备。普通 Worker 空轮询不算用户活动。最后再次核对空闲并显式提交停机,之后才进入不可撤销的安装切换。 - 任务准备、执行、等待用户、结果收尾、文件操作、活跃或脱离浏览器的终端都会阻止升级。
- 无法确认会由 ACP 池收尾的子进程(包括仍在进程树中的办公进程)及已脱离进程树的残留,会在停止业务之前阻止升级;释放本次领取隔离并保持 Worker 服务。正常子进程仍由 Worker 关闭流程收尾,最终退出检查失败也会进入恢复原版流程,不强杀办公进程。新旧安装彼此独立,不覆盖仍被子进程引用的资源。
- 子进程归属兼容 Worker、当前 ACP 与旧 ACP 实例标记。已被 init 接管的系统
gpg-agent --daemon、/usr/bin/qemu-system-x86_64 -daemonize和默认后台模式的系统dnsmasq,若没有通过启动参数、当前目录、打开文件或内存映射使用 Worker 安装目录,会保留运行并不再阻塞升级;不会停止这些独立服务或删除数据。前台模式、未知进程、仍占用安装目录的服务和 Worker 本体继续阻止替换。退出确认超时会列出阻塞进程的 PID 和名称,不输出完整命令参数或环境中的凭据。 - Proxy 常驻进程和候选 Worker 启动前清除上游 Worker/ACP 身份;候选实例只使用本次升级分配的新身份,避免从网页终端或模型命令启动管理器时继承旧归属。
- 此项修复需安装包含修复的新 Proxy 版本,并通过原启动方式重启 Proxy 常驻进程;只更新 Worker 或执行新版 CLI 的
status不会替换旧管理器。正常运行的 Worker 不随 Proxy 重启而停止。 - 新版安装失败时保留正在运行的原版;激活前启动失败时直接拉起已保留的原版,新升级事务不再通过重新安装旧版来回退。新版就绪检查按 15 秒期限重试,单次管理请求另有 5 秒超时;旧实例退出检查期限为 5 秒,检查失败后直接尝试恢复。管理心跳展示上报失败不打断本机恢复,领取隔离的解除仍须由 Server 确认。身份、进程退出或 Server 连通性无法确认时,不承诺可在固定时间恢复业务。
- 若人工恢复了一个可用 Worker,先验证本机管理通道、PID/启动时间、版本、安装入口及管理者;符合当前恢复事务且旧实例已退出时,复用该实例并解除隔离,不反复重装或拉起。不同管理者或无法确认身份的实例保持保护。
- 同一安装目录存在其他 Worker 时不自动升级。不要在维护期间同时运行外部
npm install操作这个包。 - Server 重启或回执过期留下的历史异常不再阻止升级。空闲时保留 60 秒在途请求排空窗口,期间新增用户任务可取消本次准备;此前等待 Job 的时间不能抵扣此窗口。再核对当前任务、文件活动和终端命令,按同一 PID、启动标识和实例身份停机;这不是等待历史异常消失。
- 新升级只在安装准备完成后切换进程;等待、准备或升级条件检查失败不应长期封锁新 Job。旧版原目录升级遗留事务若在安装前被子进程挡住,会在验证原版入口未变后直接恢复原版;若原安装已损坏且没有保留副本,仍须完成旧恢复流程。Proxy 的管理心跳不会伪造 Worker 心跳或 Job 心跳。
系统服务
普通 daemon start 不提供 Proxy 自身崩溃后的外部拉起保证。生产环境建议用 systemd:
aica-proxy service print > /etc/systemd/system/aica-proxy.service
# 先停止已通过 daemon start 启动的 Proxy,再由 systemd 接管。
aica-proxy daemon stop
systemctl daemon-reload
systemctl enable --now aica-proxy模板使用 flock --no-fork、KillMode=process 和无限停止等待,防止停止 Proxy 时连带杀掉忙碌 Worker 或正在安装的 npm。生成前设好自定义 AICA_HOME、AICA_CONFIG。若 Node/npm 由 nvm 安装,请给 unit 设置包含对应 npm 和 Node 的 PATH。使用自签名 Server TLS 时需显式配置 ACA_SERVER_INSECURE_TLS=1。
使用 systemd 后,通过 systemctl stop/restart aica-proxy 管理服务。不要同时让其他 supervisor 管理同一个 Worker。Proxy 自身的自动升级不在首版范围内。
构建验证和发布
从仓库根目录运行:
./publish-aica-proxy.sh --dry-run
./publish-aica-proxy.shProxy 独立版本、独立发布锁及记录。首次发布使用源码版本,后续递增最后已发布版本的补丁号。支持 --version x.y.z 和 --otp code。复用 NPM_TOKEN 或 npm 配置,不把 Token 写入包或脚本。发布前验证语法、故障测试、打包内容、临时安装及 CLI。
上传后会轮询 npm 官方 Registry 的指定版本,最多 30 次、每次间隔 5 秒,只有查询到目标版本才提示发布成功并更新发布记录。查询强制刷新缓存,单次请求超时为 10 秒,不启用 npm 内部重试。
构建验证失败或 Registry 明确拒绝认证/权限时恢复源码版本。上传被接受或返回其他错误,但轮询结束仍未确认版本时,脚本以非零状态退出,保留 release/.pending-publish 和本次版本,不回退、不重复发布。再次执行脚本会继续轮询该版本,确认后补全记录并退出;只有确认未发布时才可手动移除待确认记录后重试。脚本不会更新任何运行中的 Worker,也不会重启服务。
当前活动检查与旧 Worker 兼容
支持 user-priority-claim-recovery 的 Server 和更新后的 Proxy 使用用户优先升级入口,等待期间各会话任务、图片、文件和终端继续正常服务。无历史异常的 Worker 和同时带有上传、收尾、领取回执异常的旧 Worker 都使用此流程,无需清空异常标记或先人工重启 Worker。人工停止/重启仍与自动升级互斥。
先更新 Server,再更新 Proxy 并通过原启动方式重启 Proxy;不要停止正在执行任务的 Worker。Server 自动为小型隔离表增加阶段及排空起点字段,兼容 SQLite 和 MariaDB,新增排队任务检查复用现有状态索引及会话主键,不新增业务索引。仅支持旧恢复协议的 Server 仍保留原排空流程,但新版 Proxy 不会在本机有实际工作时开始隔离,并会释放尚未停机的旧等待隔离;完整的新任务抢占行为需要更新 Server 和 Proxy。完全不支持恢复能力的 Server 继续使用原 canUpdate 路径,带历史异常的旧 Worker 则需先更新 Server。
新版 Server 的 waiting 阶段开放所有领取通道。新版 Proxy 在本机忙碌时会解除旧等待隔离,空闲后再核对管理者及 Worker 实例并尝试升级;旧协议的全面排空与已提交停机的事务不会因新增用户工作自动倒退。新增协议的可撤销排空和最终提交阶段会持久保存。阶段和排空起点跨 Server/Proxy 重启持久保留,网络断开或设备仍有实际活动时继续等待。Proxy 更新本身仍需部署,不属于 Worker 自动升级范围。
恢复中的隔离和操作身份会持久保存,请保留 Proxy 的 state.json。不要通过删除状态文件或强制清除 Worker 的异常标记来绕过检查。
