agentscope-ai / agentscope-ai/agentscope-java

[Bug]:abstractFilesystem() with user-registered SandboxLifecycleMiddleware should participate in wrappedCall lifecycle

未关闭
#1,605 0 条评论 0 个 reaction 已指派 0 人 在 GitHub 查看
area/harness bug
主要语言
Java
星标
5.6k
派生
1.3k
平均合并
4 天 12 小时
30 天内合并 PR
77

描述

When using builder.abstractFilesystem(sandboxFs) combined with builder.middleware(new SandboxLifecycleMiddleware(sandboxManager, sandboxFs)), the sandbox lifecycle is never triggered.

Root cause: HarnessAgent.wrappedCall() / wrappedStreamEvents() only invokes the private field sandboxLifecycleMw, which is exclusively populated through the
builder.filesystem(SandboxFilesystemSpec) path. SandboxLifecycleMiddleware does not override any MiddlewareBase methods, so adding it to the middleware chain via builder.middleware() is
a no-op.

Use Case

Custom tools (e.g., an OSS upload tool) need a reference to the SandboxBackedFilesystem instance at construction time to call execute() / downloadFiles(). These tools are registered via
builder.toolkit() before build().

With builder.filesystem(SandboxFilesystemSpec), the SandboxBackedFilesystem is created internally during build() — there's no way for user-provided tools to obtain a reference to it.

This forces users to use abstractFilesystem(), but that path has no lifecycle management, requiring manual acquireForCall / releaseForCall invocation from the application layer —
reimplementing the Mono.using() pattern that wrappedCall already provides.

┌───────────────────────────────────┬───────────────────┬───────────────────────────────────┐
│ Path │ Lifecycle managed │ Custom tool can access sandbox FS │
├───────────────────────────────────┼───────────────────┼───────────────────────────────────┤
│ filesystem(SandboxFilesystemSpec) │ ✅ │ ❌ │
├───────────────────────────────────┼───────────────────┼───────────────────────────────────┤
│ abstractFilesystem(fs) │ ❌ │ ✅ │
└───────────────────────────────────┴───────────────────┴───────────────────────────────────┘

Proposed Solution

In HarnessAgent.Builder.build(), if sandboxLifecycleMw is still null after the sandboxFilesystemSpec block, scan the registered middlewares for a user-provided
SandboxLifecycleMiddleware and promote it to the sandboxLifecycleMw field:

if (sandboxLifecycleMw == null) {
for (MiddlewareBase mw : allMiddlewares) {
if (mw instanceof SandboxLifecycleMiddleware slm) {
sandboxLifecycleMw = slm;
break;
}
}
}

This makes the existing abstractFilesystem() + middleware(SandboxLifecycleMiddleware) combination work as expected — the framework's wrappedCall() handles acquire/release automatically.

Alternatives Considered

1. Allow SandboxFilesystemSpec to accept a pre-created SandboxBackedFilesystem — more invasive API change.
2. Post-build tool registration — e.g., builder.afterSandboxReady(fs -> {...}) callback — new API surface.
3. Application-layer workaround (current) — call acquireForCall / releaseForCall from the service layer, bypassing framework lifecycle.

Environment

- agentscope-harness: 2.0.0-RC1 / 2.0.0-SNAPSHOT (main branch)
- Affected classes: HarnessAgent, SandboxLifecycleMiddleware

贡献指南

打开贡献指南

评估

这个 Issue 还没有评估数据。

把新 issue 发到你的邮箱

精选适合新手参与的 GitHub issue 摘要。