firm-acp-bridge
⚠️ Contenu généré par IA — validation humaine requise avant déploiement en production.
Purpose
Ce skill rend le bridge ACP résilient aux crashs et les sessions agents autonomes
pleinement fonctionnelles en comblant les gaps découverts dans openclaw/openclaw.
Gaps couverts :
| Gap | Sévérité | Outil |
|---|
| C4 — ACP sessions en mémoire uniquement (crash = perte) | CRITICAL | INLINECODE1 |
| H3 — Sessions spawn/cron sans provider env vars |
HIGH |
fleet_session_inject_env |
| H4 — Cron tools sur denylist sandbox | HIGH |
fleet_cron_schedule |
| H5 — Race condition shared-workspace read/write | HIGH |
openclaw_workspace_lock |
Tools activés
CODEBLOCK0
Protocole ACP Persistence (C4)
Problème : Si le bridge openclaw acp crashe ou est tué (OOM, reboot), tous les
mappings run_id → gateway_session_key en mémoire sont perdus. Les IDE integrations
(VS Code, Cursor) se reconnectent silencieusement à de nouvelles sessions.
Intégration côté bridge (pattern d'appel)
À chaque création de session ACP, appeler immédiatement :
CODEBLOCK1
Au démarrage du bridge (après crash ou restart) :
CODEBLOCK2
→ Retourne les sessions récupérables + purge automatique des sessions > 24h stale.
Pour monitorer :
CODEBLOCK3
Décision d'architecture — ACP session store
| Option | Décision | Raison |
|---|
| Redis | ❌ NON | Trop lourd pour single-operator, dépendance externe |
| SQLite |
❌ NON | Overkill pour des clés simples, migration schema |
| JSON file (atomic rename) | ✅ OUI | Zéro dépendance, atomic write (tmp + os.replace), léger |
Autonomous Session Bootstrap (H3)
Problème : Les sessions spawned via sessions_spawn ou cron n'ont pas accès aux
env vars des providers configurés (ANTHROPICAPIKEY, OPENAIAPIKEY, etc.).
Tout appel LLM dans une session non-main échoue silencieusement.
Séquence obligatoire avant sessions_spawn
Étape 1 — Validation dry_run (vérifier les clés sans envoyer) :
CODEBLOCK4
→ Vérifie que les clés passent l'allowlist. Si rejected non vide, les clés sont invalides.
Étape 2 — Injection effective avant spawn :
CODEBLOCK5
Étape 3 — Spawn la session (via Gateway direct) :
CODEBLOCK6
Clés autorisées (allowlist intégrée)
CODEBLOCK7
Jamais dans les logs — les valeurs sont masquées avec ****{last4}.
Cron Outside Sandbox (H4)
Problème : cron tools sont sur la denylist dans les sessions Docker sandbox.
Tout workflow autonome planifié dans un container non-main est bloqué.
Solution : Planifier sur la session main (accès hôte) via fleet_cron_schedule.
CODEBLOCK8
Utiliser fleet_cron_schedule quand :
- - ✅ La tâche est un script léger et déterministe
- ✅ La tâche ne nécessite pas d'isolation sécurité
- ✅ La command passe l'allowlist INLINECODE14
Utiliser sessions_spawn (session non-main) quand :
- - ✅ La tâche implique du code non vérifié / externe
- ✅ Isolation sécurité requise (sandbox Docker)
- ✅ La tâche peut se déclencher ad-hoc (pas planifiée)
Workspace Locking (H5)
Problème : Race condition documentée (#29947) sur shared-workspace read/modify/write.
Plusieurs sessions agent peuvent corrompre la même ressource partagée.
Pattern acquire / work / release
CODEBLOCK9
Vérifier le statut d'un lock :
CODEBLOCK10
Règles
- - Le lock est advisory (pas kernel-level) — tous les agents doivent coopérer
- INLINECODE16 max = 300s. Si lock non acquis →
ok: false + current_owner - Toujours
release dans un bloc try/finally pour éviter les locks orphelins - Un lock expired ne se libère pas automatiquement — utiliser
acp_session_restore pour purger les owners stale
Monitoring de santé ACP
Flux de monitoring recommandé (à exécuter périodiquement) :
CODEBLOCK11
Si restored: 0 et purged > 0 après un intervalle normal → le bridge a crashé et les
sessions ont été perdues → notifier via firm_export_slack_digest.
OpenClaw gaps : C4 (ACP in-memory), H3 (#29886 isolated sessions no provider env), H4 (#29921 cron sandbox denylist), H5 (#29947 race condition)
💎 Support
Si ce skill vous est utile, vous pouvez soutenir le développement :
Dogecoin : INLINECODE23
firm-acp-bridge
⚠️ AI生成内容——在生产环境部署前需人工验证。
目的
此技能使ACP桥接器具备崩溃恢复能力,并让自主代理会话完全正常运行,弥补openclaw/openclaw中发现的缺口。
已覆盖的缺口:
| 缺口 | 严重程度 | 工具 |
|---|
| C4 — ACP会话仅存在于内存中(崩溃=数据丢失) | 严重 | acpsessionpersist/restore |
| H3 — 生成的会话/定时任务缺少提供者环境变量 |
高 | fleet
sessioninject_env |
| H4 — 沙箱中的定时任务工具被列入黑名单 | 高 | fleet
cronschedule |
| H5 — 共享工作区的读写竞态条件 | 高 | openclaw
workspacelock |
已激活的工具
acpsessionpersist — 将runid → gatewaysession_key持久化到磁盘 (C4)
acpsessionrestore — 在桥接器崩溃/重启后重新加载会话 (C4)
acpsessionlist_active — 列出活跃和过期的ACP会话 (C4)
fleetsessioninject_env — 向非主会话注入提供者环境变量 (H3)
fleetcronschedule — 在主会话上调度定时任务 (H4)
openclawworkspacelock — 建议性锁,避免竞态条件 (H5)
ACP持久化协议 (C4)
问题: 如果openclaw acp桥接器崩溃或被终止(OOM、重启),内存中所有runid → gatewaysession_key映射都会丢失。IDE集成(VS Code、Cursor)会静默地重新连接到新会话。
桥接器端集成(调用模式)
每次创建ACP会话时,立即调用:
json
{
tool: acpsessionpersist,
args: {
runid: run_id>,
gatewaysessionkey: ,
metadata: {
ide: vscode,
workspace: /path/to/project,
created_by: agent-name
}
}
}
桥接器启动时(崩溃或重启后):
json
{
tool: acpsessionrestore,
args: { maxagehours: 24 }
}
→ 返回可恢复的会话,并自动清除超过24小时的过期会话。
用于监控:
json
{
tool: acpsessionlist_active,
args: { include_stale: false }
}
架构决策 — ACP会话存储
| 选项 | 决策 | 原因 |
|---|
| Redis | ❌ 否 | 对单操作员来说太重,外部依赖 |
| SQLite |
❌ 否 | 对简单键值对来说过度设计,需要迁移模式 |
| JSON文件(原子重命名) | ✅ 是 | 零依赖,原子写入(tmp + os.replace),轻量 |
自主会话引导 (H3)
问题: 通过sessionsspawn或定时任务生成的会话无法访问已配置提供者的环境变量(ANTHROPICAPIKEY、OPENAIAPI_KEY等)。在非主会话中任何LLM调用都会静默失败。
在sessions_spawn前的必需步骤
步骤1 — 干运行验证(检查密钥但不发送):
json
{
tool: fleetsessioninject_env,
args: {
env_vars: {
ANTHROPICAPIKEY: ,
OPENCLAW_MODEL: claude-3-5-sonnet-20241022
},
dry_run: true
}
}
→ 验证密钥是否通过允许列表。如果rejected不为空,则密钥无效。
步骤2 — 在生成前实际注入:
json
{
tool: fleetsessioninject_env,
args: {
env_vars: {
ANTHROPICAPIKEY: ,
OPENCLAW_MODEL: claude-3-5-sonnet-20241022
},
filter_tags: [engineering, quality]
}
}
步骤3 — 生成会话(通过Gateway直接):
json
{
method: sessions_spawn,
params: {
agent: engineering,
reply_session: main
}
}
允许的密钥(内置允许列表)
ANTHROPICAPIKEY | OPENAIAPIKEY | OPENROUTERAPIKEY | GEMINIAPIKEY
OPENCLAWMODEL | OPENCLAWPROVIDER | OPENCLAWMAXTOKENS
CLAWMODEL | CLAWPROVIDER | PROXYURL | CUSTOM*
绝不会出现在日志中——值会被屏蔽为{last4}。
沙箱外的定时任务 (H4)
问题: cron工具在Docker沙箱会话中被列入黑名单。任何在非主容器中计划的自主工作流都会被阻止。
解决方案: 通过fleetcronschedule在主会话(主机访问)上调度。
json
{
tool: fleetcronschedule,
args: {
command: node scripts/daily-report.js,
schedule: 0 9 1-5,
session: main,
description: 每日业务报告 — 周一至周五 9点
}
}
使用fleetcronschedule当:
- - ✅ 任务是轻量且确定性的脚本
- ✅ 任务不需要安全隔离
- ✅ 命令通过允许列表[a-zA-Z0-9 /._-=]+
使用sessions_spawn(非主会话)当:
- - ✅ 任务涉及未验证/外部代码
- ✅ 需要安全隔离(Docker沙箱)
- ✅ 任务可以临时触发(非计划性)
工作区锁定 (H5)
问题: 共享工作区读/修改/写操作的竞态条件(#29947)。多个代理会话可能损坏同一共享资源。
获取 / 工作 / 释放模式
json
// 1. 获取锁
{
tool: openclawworkspacelock,
args: {
path: shared/config.json,
action: acquire,
owner: engineering-session-001,
timeout_s: 30
}
}
// 2. 执行工作(读取 → 修改 → 写入)
// ... 对资源的操作 ...
// 3. 释放锁
{
tool: openclawworkspacelock,
args: {
path: shared/config.json,
action: release,
owner: engineering-session-001
}
}
检查锁的状态:
json
{
tool: openclawworkspacelock,
args: {
path: shared/config.json,
action: status,
owner: any
}
}
规则
- - 锁是建议性的(非内核级别)——所有代理必须协作
- timeouts最大=300秒。如果锁未获取到→ok: false + currentowner
- 始终在try/finally块中release,以避免孤儿锁
- 过期的锁不会自动释放——使用acpsessionrestore清除过期的所有者
ACP健康监控
推荐的监控流程(定期执行):
acpsessionlistactive → 过期会话 > 2小时 → acpsessionrestore(maxage_hours=2) → 重新检查
如果在正常间隔后restored: 0且purged > 0→桥接器已崩溃且会话已丢失→通过firmexportslack_digest通知。
OpenClaw缺口:C4(ACP内存中)、H3(#29886隔离会话无提供者环境变量)、H4(#29921定时任务沙箱黑名单)、H5(#29947竞态条件)
💎 支持
如果此技能对您有帮助,您可以支持开发:
狗狗币:DQBggqFNWsRNTPb6kkiwppnMo1Hm8edfWq