fix: allow remote Execute without bubblewrap
Remote Hosts without the Ask-only bubblewrap tool could report matching Agent and Runtime versions but fail project creation because the Agent hid the Runtime ACP capability entirely. The Agent now advertises a verified Runtime independently of bubblewrap, so Execute can start directly while Ask keeps its existing read-only bubblewrap boundary. Release note: 修复远程 Host 缺少 bubblewrap 时 Execute 项目无法创建的问题;更新到 Agent 0.11.16 后,Execute 不再受 Ask 专用系统工具影响。
This commit is contained in:
@@ -1,6 +1,6 @@
|
||||
{
|
||||
"formatVersion": 1,
|
||||
"agentVersion": "0.11.15",
|
||||
"agentVersion": "0.11.16",
|
||||
"protocol": {
|
||||
"major": 2,
|
||||
"minor": 0
|
||||
|
||||
@@ -12,7 +12,7 @@ Linux x64/arm64、取消和离线 GoodBuddy 传输的真实 Host 验收。
|
||||
Windows 到 Linux x64 的安装、Agent-owned Prompt、Agent 本地模型 gateway、断线恢复、
|
||||
同一 OpenCode Session 续接、取消和终态清理已经使用真实模型与工具验证。Agent
|
||||
`0.11.14` 已通过独立 workflow 发布 Linux x64/arm64 复合包和签名累计目录;当前未发布
|
||||
Agent 源码 lock 为 `0.11.15`,Desktop 恢复候选为 `0.12.2`,等待各自独立发布审批。
|
||||
Agent 源码 lock 为 `0.11.16`,Desktop 恢复候选为 `0.12.2`,等待各自独立发布审批。
|
||||
现有源码显示本地与远端 OpenCode 原生 Task,并取消 GoodBuddy 对生产 Prompt 的
|
||||
固定墙钟总时限。失败的 `agent-v0.11.3` 保持不可变且未发布。
|
||||
|
||||
@@ -192,7 +192,8 @@ Ask 使用系统 `bwrap`:
|
||||
search、edit、execute、未知工具以及只提供持久授权的请求全部拒绝。
|
||||
|
||||
`allow_once` 只解决 OpenCode 发起原生读取前的 ACP 协商,真正的文件系统边界仍是只读
|
||||
`bwrap` bind。Host 缺少 `bwrap` 时 Ask 不可用。
|
||||
`bwrap` bind。Host 缺少 `bwrap` 时 Ask 启动失败,但不影响 Runtime 能力声明或 Execute
|
||||
直接启动。
|
||||
|
||||
### Execute
|
||||
|
||||
@@ -349,7 +350,7 @@ model bridge,以及生命周期和恢复逻辑。单元测试、mock、fixture
|
||||
- 2026-08 的本地 fixture 完整验证 Linux x64 Agent `0.11.2-e2e.12`、Node `24.19.0`
|
||||
和 Agent protocol `2.0`;当时没有 arm64 fixture,因此该记录不能作为当前独立发布
|
||||
的双架构验收。Agent `0.11.10` 后续已由原生 workflow 发布并公开验证双架构工件;
|
||||
当前源码 lock 固定为 `0.11.15`;正式发布状态以独立 Agent Release 与签名 catalog 为准。
|
||||
当前源码 lock 固定为 `0.11.16`;正式发布状态以独立 Agent Release 与签名 catalog 为准。
|
||||
- 2026-08-30 在共享 Linux x64 Host 的隔离测试 HOME 中验证当前 `0.11.13` 源码候选:
|
||||
签名 Runtime 清单的测试墙钟上限为 1 秒,模型桥首轮故意延迟 2.515 秒后 Prompt 仍在
|
||||
5.770 秒正常完成;随后 OpenCode 原生 Task 依次产生 `running`、`completed` 子 Agent
|
||||
@@ -397,6 +398,11 @@ model bridge,以及生命周期和恢复逻辑。单元测试、mock、fixture
|
||||
workflow 与 Release Notes 聚焦测试 `106/106` 通过、1 项平台用例跳过;全量
|
||||
`npm test` 为 `3478` 通过、`51` 跳过,typecheck 与 lint 通过。本轮没有新增模型调用,
|
||||
也未在本地运行 production build、package 或安装探针。
|
||||
- 2026-09-03 使用包含当前 Runtime capability 修复的源码 harness,在共享 Linux x64 Host
|
||||
的唯一 `/tmp/goodbuddy-e2e-runtime-capability-*` 隔离 HOME 中读取签名 Runtime 副本。
|
||||
Agent 成功报告已登记 OpenCode Runtime,Execute 随后直接启动 OpenCode 而未经过
|
||||
`bwrap`;Runtime owner 和隔离目录均已清理,未修改 Host current Agent/Runtime。
|
||||
本次只验证能力声明和真实进程启动,没有发送 Prompt,真实文本模型调用 0 次。
|
||||
- 正常 Host 更新路径把 Linux x64 Host 的 Agent 更新为 `0.11.2-e2e.12`,并确认
|
||||
OpenCode Runtime 已安装版本与所需版本均为 `1.18.9`。
|
||||
- 一条新的 Ask 用户操作只提交一次。OpenCode 先在 build 模型轮次请求一个原生
|
||||
|
||||
@@ -37,7 +37,7 @@ afterEach(() => {
|
||||
})
|
||||
|
||||
describe('production Runtime composition', () => {
|
||||
it('loads metadata installed after startup and caches the registered Runtime identity', async () => {
|
||||
it('loads Runtime metadata independently of Ask-only Host prerequisites', async () => {
|
||||
const fixture = await createRuntimeBundleTestFixture()
|
||||
const root = fixture.root
|
||||
temporaryPaths.push(root)
|
||||
@@ -62,7 +62,6 @@ describe('production Runtime composition', () => {
|
||||
blobSink: async () => {},
|
||||
agentExecutablePath,
|
||||
reportError,
|
||||
prerequisitesAvailable: async () => true,
|
||||
verificationEnvironment: 'test',
|
||||
filesystemPlatform: 'win32'
|
||||
})
|
||||
@@ -128,7 +127,7 @@ describe('production Runtime composition', () => {
|
||||
events.close()
|
||||
})
|
||||
|
||||
it('composes all autonomous ACP methods but advertises no Runtime when prerequisites fail', async () => {
|
||||
it('composes all autonomous ACP methods when no Runtime is installed', async () => {
|
||||
const root = temporaryDirectory()
|
||||
const runtimeRoot = resolve(root, 'runtimes')
|
||||
const stateDirectory = resolve(root, 'state')
|
||||
@@ -155,7 +154,6 @@ describe('production Runtime composition', () => {
|
||||
releaseKeyRegistry,
|
||||
runtimeLock: {} as RemoteRuntimeLock,
|
||||
registry,
|
||||
prerequisitesAvailable: async () => false,
|
||||
verificationEnvironment: 'test',
|
||||
filesystemPlatform: 'win32'
|
||||
})
|
||||
|
||||
@@ -46,8 +46,6 @@ import {
|
||||
} from './agent-model-gateway'
|
||||
import type { AgentDiagnosticLog } from './diagnostic-log'
|
||||
|
||||
const BWRAP_EXECUTABLE = '/usr/bin/bwrap'
|
||||
|
||||
export type ProductionRuntimeProtocol = {
|
||||
runtimes: ReturnType<typeof createVerifiedRuntimeCapabilitySource>
|
||||
methods: RuntimeAcpBackend['methods']
|
||||
@@ -85,7 +83,6 @@ export type ProductionRuntimeCompositionOptions = {
|
||||
releaseKeyRegistry?: AgentReleaseKeyRegistry
|
||||
runtimeLock?: RemoteRuntimeLock
|
||||
registry?: RuntimeBundleRegistry
|
||||
prerequisitesAvailable?: () => boolean | Promise<boolean>
|
||||
launchProcess?: typeof launchDirectLinuxStdioProcessOwner
|
||||
reconcileOrphanedProcesses?: (
|
||||
installationId: string
|
||||
@@ -222,9 +219,6 @@ export async function createProductionRuntimeProtocol(
|
||||
})
|
||||
return await source()
|
||||
}
|
||||
const prerequisites =
|
||||
options.prerequisitesAvailable ??
|
||||
productionRuntimePrerequisitesAvailable
|
||||
const launchProcess =
|
||||
options.launchProcess ?? launchDirectLinuxStdioProcessOwner
|
||||
let backend: RuntimeAcpBackend
|
||||
@@ -328,8 +322,7 @@ export async function createProductionRuntimeProtocol(
|
||||
options.agentExecutablePath === undefined ||
|
||||
!(await executableAvailable(
|
||||
resolve(options.agentExecutablePath)
|
||||
)) ||
|
||||
!(await prerequisites())
|
||||
))
|
||||
) {
|
||||
return []
|
||||
}
|
||||
@@ -540,12 +533,3 @@ function bindingDirectoryDigest(
|
||||
]))
|
||||
.digest('hex')
|
||||
}
|
||||
|
||||
async function productionRuntimePrerequisitesAvailable(): Promise<boolean> {
|
||||
try {
|
||||
await access(BWRAP_EXECUTABLE, constants.X_OK)
|
||||
return true
|
||||
} catch {
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user