What happened / 发生了什么
在使用 Shipyard Neo 作为 sandbox runtime 时,冷启动后的首次 sandbox 工具调用可能返回空的 error:,AstrBot 日志中对应表现为 Error booting sandbox for session ...: 后面没有异常详情。
从线上环境观察,Bay 能成功创建 sandbox,后续 ship 与 browser 子容器也能正常启动;等待一段时间后,同一个 sandbox 可以正常执行 shell 与 python 命令。因此当前现象更像是 AstrBot 在 create_sandbox() 返回后立刻执行 skills 同步或首次工具命令,但 Shipyard Neo 底层子容器尚未完全就绪,导致首次请求触发 httpx.ReadTimeout。由于 ReadTimeout 的字符串内容为空,最终对话侧容易只看到空的 error:。
相关历史问题:#7130 和 AstrBotDevs/shipyard-neo#15 都出现过相近的 ReadTimeout 或 sandbox 启动后首次执行失败现象。不过当前环境中 Bay 与 AstrBot 在同一 Docker 部署环境内,网络连通正常,等待 sandbox 完全启动后命令可以成功执行。
计划从 AstrBot 侧修复:在 ShipyardNeoBooter.boot() 的 create_sandbox() 之后增加 sandbox 就绪探测,确认 shell 可执行后再进入 skills 同步或返回 booter;同时在异常格式化处增加兜底文本,避免空异常显示为 error:。
Reproduce / 如何复现?
- 配置 AstrBot 使用 sandbox runtime,并选择 Shipyard Neo:
{
"computer_use_runtime": "sandbox",
"sandbox": {
"booter": "shipyard_neo",
"shipyard_neo_endpoint": "http://bay:8114",
"shipyard_neo_profile": "browser-python",
"shipyard_neo_ttl": 3600
}
}
-
确保当前没有可复用的已就绪 sandbox,触发一次需要 sandbox 的对话工具调用,例如 shell 或 python 工具。
-
在冷启动较慢的环境中,首次调用可能在 Bay 尚未完成 ship、browser 子容器启动时发出执行请求,并在约 40 秒后出现 httpx.ReadTimeout。
-
等待同一个 sandbox 子容器完全启动后,再次执行同类命令可以成功。
容器内最小验证脚本:
import asyncio, json
from pathlib import Path
from astrbot.core.computer.booters.shipyard_neo import ShipyardNeoBooter
creds = json.loads(Path('/run/bay-credentials/credentials.json').read_text())
async def main():
booter = ShipyardNeoBooter(
creds['endpoint'],
creds['api_key'],
profile='browser-python',
ttl=120,
)
await booter.boot('diagnose-sandbox')
try:
print('caps', booter.capabilities)
print(await booter.shell.exec('echo hello && pwd', timeout=30))
finally:
await booter.shutdown()
asyncio.run(main())
在同一环境中,booter.boot() 后立即执行命令会触发 httpx.ReadTimeout;如果在 booter.boot() 后等待约 65 秒,再执行 echo hello && pwd 和 print(1+1),shell 与 python 均可成功返回。
AstrBot version, deployment method (e.g., Windows Docker Desktop deployment), provider used, and messaging platform used. / AstrBot 版本、部署方式(如 Windows Docker Desktop 部署)、使用的提供商、使用的消息平台适配器
AstrBot v4.23.5,Docker 部署。
Sandbox 使用 Shipyard Neo,Bay 与 AstrBot 通过 Docker 网络通信,endpoint 为 http://bay:8114,profile 为 browser-python。
Provider 与 messaging platform 对该问题没有强绑定关系;实际现象来自 sandbox booter 初始化后的首次 shell/python 执行。线上是通过私聊自然语言触发 sandbox 工具调用发现,随后使用容器内最小脚本确认。
OS
Linux
Logs / 报错日志
AstrBot 侧首次调用相关日志形态如下,注意 Error booting sandbox ...: 后异常详情为空:
[Core] [INFO] [computer.computer_client]: [Computer] Initializing booter: type=shipyard_neo, session=...
[Core] [INFO] [computer.computer_client]: [Computer] Shipyard Neo config: endpoint=http://bay:8114, profile=browser-python, ttl=3600
[Core] [INFO] [booters.shipyard_neo]: Got Shipyard Neo sandbox: sandbox-1f16274cd147 (profile=browser-python, capabilities=['browser', 'filesystem', 'python', 'shell'], auto=False)
[Core] [INFO] [computer.computer_client]: [Computer] Sandbox booted successfully: type=shipyard_neo, session=...
[Core] [INFO] [computer.computer_client]: Uploading skills bundle to sandbox...
[Core] [ERRO] [computer.computer_client]: Error booting sandbox for session ...:
Traceback (most recent call last):
...
httpx.ReadTimeout
Bay 侧同一时间段可以看到 sandbox 创建成功,但底层容器仍在启动,首次执行请求早于完全就绪:
2026-04-24 15:21:03 sandbox.create sandbox_id=sandbox-1f16274cd147
2026-04-24 15:21:03 session.create session_id=sess-6a693484d546
2026-04-24 15:21:14 docker.start_multi
2026-04-24 15:21:41 docker.start_multi.container_started container_role=ship endpoint=http://172.31.0.6:8123
2026-04-24 15:21:43 docker.start_multi.container_started container_role=browser endpoint=http://172.31.0.7:8115
2026-04-24 15:22:01 session.multi_container_started
2026-04-24 15:22:02 capability.shell.exec command='echo hello && pwd'
等待 sandbox 完全启动后,同一环境验证成功:
shell {"stdout": "hello\n/workspace", "stderr": "", "exit_code": 0, "success": true, "execution_time_ms": 993}
python {"success": true, "output": "2", "error": "", "execution_time_ms": 1142}
Are you willing to submit a PR? / 你愿意提交 PR 吗?
Code of Conduct
What happened / 发生了什么
在使用 Shipyard Neo 作为 sandbox runtime 时,冷启动后的首次 sandbox 工具调用可能返回空的
error:,AstrBot 日志中对应表现为Error booting sandbox for session ...:后面没有异常详情。从线上环境观察,Bay 能成功创建 sandbox,后续
ship与browser子容器也能正常启动;等待一段时间后,同一个 sandbox 可以正常执行 shell 与 python 命令。因此当前现象更像是 AstrBot 在create_sandbox()返回后立刻执行 skills 同步或首次工具命令,但 Shipyard Neo 底层子容器尚未完全就绪,导致首次请求触发httpx.ReadTimeout。由于ReadTimeout的字符串内容为空,最终对话侧容易只看到空的error:。相关历史问题:#7130 和 AstrBotDevs/shipyard-neo#15 都出现过相近的
ReadTimeout或 sandbox 启动后首次执行失败现象。不过当前环境中 Bay 与 AstrBot 在同一 Docker 部署环境内,网络连通正常,等待 sandbox 完全启动后命令可以成功执行。计划从 AstrBot 侧修复:在
ShipyardNeoBooter.boot()的create_sandbox()之后增加 sandbox 就绪探测,确认 shell 可执行后再进入 skills 同步或返回 booter;同时在异常格式化处增加兜底文本,避免空异常显示为error:。Reproduce / 如何复现?
{ "computer_use_runtime": "sandbox", "sandbox": { "booter": "shipyard_neo", "shipyard_neo_endpoint": "http://bay:8114", "shipyard_neo_profile": "browser-python", "shipyard_neo_ttl": 3600 } }确保当前没有可复用的已就绪 sandbox,触发一次需要 sandbox 的对话工具调用,例如 shell 或 python 工具。
在冷启动较慢的环境中,首次调用可能在 Bay 尚未完成
ship、browser子容器启动时发出执行请求,并在约 40 秒后出现httpx.ReadTimeout。等待同一个 sandbox 子容器完全启动后,再次执行同类命令可以成功。
容器内最小验证脚本:
在同一环境中,
booter.boot()后立即执行命令会触发httpx.ReadTimeout;如果在booter.boot()后等待约 65 秒,再执行echo hello && pwd和print(1+1),shell 与 python 均可成功返回。AstrBot version, deployment method (e.g., Windows Docker Desktop deployment), provider used, and messaging platform used. / AstrBot 版本、部署方式(如 Windows Docker Desktop 部署)、使用的提供商、使用的消息平台适配器
AstrBot v4.23.5,Docker 部署。
Sandbox 使用 Shipyard Neo,Bay 与 AstrBot 通过 Docker 网络通信,endpoint 为
http://bay:8114,profile 为browser-python。Provider 与 messaging platform 对该问题没有强绑定关系;实际现象来自 sandbox booter 初始化后的首次 shell/python 执行。线上是通过私聊自然语言触发 sandbox 工具调用发现,随后使用容器内最小脚本确认。
OS
Linux
Logs / 报错日志
AstrBot 侧首次调用相关日志形态如下,注意
Error booting sandbox ...:后异常详情为空:Bay 侧同一时间段可以看到 sandbox 创建成功,但底层容器仍在启动,首次执行请求早于完全就绪:
等待 sandbox 完全启动后,同一环境验证成功:
Are you willing to submit a PR? / 你愿意提交 PR 吗?
Code of Conduct