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,
|
"formatVersion": 1,
|
||||||
"agentVersion": "0.11.15",
|
"agentVersion": "0.11.16",
|
||||||
"protocol": {
|
"protocol": {
|
||||||
"major": 2,
|
"major": 2,
|
||||||
"minor": 0
|
"minor": 0
|
||||||
|
|||||||
@@ -12,7 +12,7 @@ Linux x64/arm64、取消和离线 GoodBuddy 传输的真实 Host 验收。
|
|||||||
Windows 到 Linux x64 的安装、Agent-owned Prompt、Agent 本地模型 gateway、断线恢复、
|
Windows 到 Linux x64 的安装、Agent-owned Prompt、Agent 本地模型 gateway、断线恢复、
|
||||||
同一 OpenCode Session 续接、取消和终态清理已经使用真实模型与工具验证。Agent
|
同一 OpenCode Session 续接、取消和终态清理已经使用真实模型与工具验证。Agent
|
||||||
`0.11.14` 已通过独立 workflow 发布 Linux x64/arm64 复合包和签名累计目录;当前未发布
|
`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 的
|
现有源码显示本地与远端 OpenCode 原生 Task,并取消 GoodBuddy 对生产 Prompt 的
|
||||||
固定墙钟总时限。失败的 `agent-v0.11.3` 保持不可变且未发布。
|
固定墙钟总时限。失败的 `agent-v0.11.3` 保持不可变且未发布。
|
||||||
|
|
||||||
@@ -192,7 +192,8 @@ Ask 使用系统 `bwrap`:
|
|||||||
search、edit、execute、未知工具以及只提供持久授权的请求全部拒绝。
|
search、edit、execute、未知工具以及只提供持久授权的请求全部拒绝。
|
||||||
|
|
||||||
`allow_once` 只解决 OpenCode 发起原生读取前的 ACP 协商,真正的文件系统边界仍是只读
|
`allow_once` 只解决 OpenCode 发起原生读取前的 ACP 协商,真正的文件系统边界仍是只读
|
||||||
`bwrap` bind。Host 缺少 `bwrap` 时 Ask 不可用。
|
`bwrap` bind。Host 缺少 `bwrap` 时 Ask 启动失败,但不影响 Runtime 能力声明或 Execute
|
||||||
|
直接启动。
|
||||||
|
|
||||||
### 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`
|
- 2026-08 的本地 fixture 完整验证 Linux x64 Agent `0.11.2-e2e.12`、Node `24.19.0`
|
||||||
和 Agent protocol `2.0`;当时没有 arm64 fixture,因此该记录不能作为当前独立发布
|
和 Agent protocol `2.0`;当时没有 arm64 fixture,因此该记录不能作为当前独立发布
|
||||||
的双架构验收。Agent `0.11.10` 后续已由原生 workflow 发布并公开验证双架构工件;
|
的双架构验收。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` 源码候选:
|
- 2026-08-30 在共享 Linux x64 Host 的隔离测试 HOME 中验证当前 `0.11.13` 源码候选:
|
||||||
签名 Runtime 清单的测试墙钟上限为 1 秒,模型桥首轮故意延迟 2.515 秒后 Prompt 仍在
|
签名 Runtime 清单的测试墙钟上限为 1 秒,模型桥首轮故意延迟 2.515 秒后 Prompt 仍在
|
||||||
5.770 秒正常完成;随后 OpenCode 原生 Task 依次产生 `running`、`completed` 子 Agent
|
5.770 秒正常完成;随后 OpenCode 原生 Task 依次产生 `running`、`completed` 子 Agent
|
||||||
@@ -397,6 +398,11 @@ model bridge,以及生命周期和恢复逻辑。单元测试、mock、fixture
|
|||||||
workflow 与 Release Notes 聚焦测试 `106/106` 通过、1 项平台用例跳过;全量
|
workflow 与 Release Notes 聚焦测试 `106/106` 通过、1 项平台用例跳过;全量
|
||||||
`npm test` 为 `3478` 通过、`51` 跳过,typecheck 与 lint 通过。本轮没有新增模型调用,
|
`npm test` 为 `3478` 通过、`51` 跳过,typecheck 与 lint 通过。本轮没有新增模型调用,
|
||||||
也未在本地运行 production build、package 或安装探针。
|
也未在本地运行 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`,并确认
|
- 正常 Host 更新路径把 Linux x64 Host 的 Agent 更新为 `0.11.2-e2e.12`,并确认
|
||||||
OpenCode Runtime 已安装版本与所需版本均为 `1.18.9`。
|
OpenCode Runtime 已安装版本与所需版本均为 `1.18.9`。
|
||||||
- 一条新的 Ask 用户操作只提交一次。OpenCode 先在 build 模型轮次请求一个原生
|
- 一条新的 Ask 用户操作只提交一次。OpenCode 先在 build 模型轮次请求一个原生
|
||||||
|
|||||||
@@ -37,7 +37,7 @@ afterEach(() => {
|
|||||||
})
|
})
|
||||||
|
|
||||||
describe('production Runtime composition', () => {
|
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 fixture = await createRuntimeBundleTestFixture()
|
||||||
const root = fixture.root
|
const root = fixture.root
|
||||||
temporaryPaths.push(root)
|
temporaryPaths.push(root)
|
||||||
@@ -62,7 +62,6 @@ describe('production Runtime composition', () => {
|
|||||||
blobSink: async () => {},
|
blobSink: async () => {},
|
||||||
agentExecutablePath,
|
agentExecutablePath,
|
||||||
reportError,
|
reportError,
|
||||||
prerequisitesAvailable: async () => true,
|
|
||||||
verificationEnvironment: 'test',
|
verificationEnvironment: 'test',
|
||||||
filesystemPlatform: 'win32'
|
filesystemPlatform: 'win32'
|
||||||
})
|
})
|
||||||
@@ -128,7 +127,7 @@ describe('production Runtime composition', () => {
|
|||||||
events.close()
|
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 root = temporaryDirectory()
|
||||||
const runtimeRoot = resolve(root, 'runtimes')
|
const runtimeRoot = resolve(root, 'runtimes')
|
||||||
const stateDirectory = resolve(root, 'state')
|
const stateDirectory = resolve(root, 'state')
|
||||||
@@ -155,7 +154,6 @@ describe('production Runtime composition', () => {
|
|||||||
releaseKeyRegistry,
|
releaseKeyRegistry,
|
||||||
runtimeLock: {} as RemoteRuntimeLock,
|
runtimeLock: {} as RemoteRuntimeLock,
|
||||||
registry,
|
registry,
|
||||||
prerequisitesAvailable: async () => false,
|
|
||||||
verificationEnvironment: 'test',
|
verificationEnvironment: 'test',
|
||||||
filesystemPlatform: 'win32'
|
filesystemPlatform: 'win32'
|
||||||
})
|
})
|
||||||
|
|||||||
@@ -46,8 +46,6 @@ import {
|
|||||||
} from './agent-model-gateway'
|
} from './agent-model-gateway'
|
||||||
import type { AgentDiagnosticLog } from './diagnostic-log'
|
import type { AgentDiagnosticLog } from './diagnostic-log'
|
||||||
|
|
||||||
const BWRAP_EXECUTABLE = '/usr/bin/bwrap'
|
|
||||||
|
|
||||||
export type ProductionRuntimeProtocol = {
|
export type ProductionRuntimeProtocol = {
|
||||||
runtimes: ReturnType<typeof createVerifiedRuntimeCapabilitySource>
|
runtimes: ReturnType<typeof createVerifiedRuntimeCapabilitySource>
|
||||||
methods: RuntimeAcpBackend['methods']
|
methods: RuntimeAcpBackend['methods']
|
||||||
@@ -85,7 +83,6 @@ export type ProductionRuntimeCompositionOptions = {
|
|||||||
releaseKeyRegistry?: AgentReleaseKeyRegistry
|
releaseKeyRegistry?: AgentReleaseKeyRegistry
|
||||||
runtimeLock?: RemoteRuntimeLock
|
runtimeLock?: RemoteRuntimeLock
|
||||||
registry?: RuntimeBundleRegistry
|
registry?: RuntimeBundleRegistry
|
||||||
prerequisitesAvailable?: () => boolean | Promise<boolean>
|
|
||||||
launchProcess?: typeof launchDirectLinuxStdioProcessOwner
|
launchProcess?: typeof launchDirectLinuxStdioProcessOwner
|
||||||
reconcileOrphanedProcesses?: (
|
reconcileOrphanedProcesses?: (
|
||||||
installationId: string
|
installationId: string
|
||||||
@@ -222,9 +219,6 @@ export async function createProductionRuntimeProtocol(
|
|||||||
})
|
})
|
||||||
return await source()
|
return await source()
|
||||||
}
|
}
|
||||||
const prerequisites =
|
|
||||||
options.prerequisitesAvailable ??
|
|
||||||
productionRuntimePrerequisitesAvailable
|
|
||||||
const launchProcess =
|
const launchProcess =
|
||||||
options.launchProcess ?? launchDirectLinuxStdioProcessOwner
|
options.launchProcess ?? launchDirectLinuxStdioProcessOwner
|
||||||
let backend: RuntimeAcpBackend
|
let backend: RuntimeAcpBackend
|
||||||
@@ -328,8 +322,7 @@ export async function createProductionRuntimeProtocol(
|
|||||||
options.agentExecutablePath === undefined ||
|
options.agentExecutablePath === undefined ||
|
||||||
!(await executableAvailable(
|
!(await executableAvailable(
|
||||||
resolve(options.agentExecutablePath)
|
resolve(options.agentExecutablePath)
|
||||||
)) ||
|
))
|
||||||
!(await prerequisites())
|
|
||||||
) {
|
) {
|
||||||
return []
|
return []
|
||||||
}
|
}
|
||||||
@@ -540,12 +533,3 @@ function bindingDirectoryDigest(
|
|||||||
]))
|
]))
|
||||||
.digest('hex')
|
.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