Skip to content

fix: isolate static subagent registries by runtime context#2371

Open
zouyx wants to merge 3 commits into
agentscope-ai:mainfrom
zouyx:fix/2328-subagent-filesystem-loader
Open

fix: isolate static subagent registries by runtime context#2371
zouyx wants to merge 3 commits into
agentscope-ai:mainfrom
zouyx:fix/2328-subagent-filesystem-loader

Conversation

@zouyx

@zouyx zouyx commented Jul 23, 2026

Copy link
Copy Markdown
Contributor

AgentScope-Java Version

2.0.1-SNAPSHOT

Description

Fixes #2328

Fix static subagent declaration isolation for namespace-scoped filesystems.

Previously, SubagentsMiddleware refreshed a shared subagent registry for every call. An interleaved call from another user could overwrite the declarations and manager used by an in-flight call, causing the prompt or agent_spawn to use another user's subagents.

This change:

  • loads Markdown declarations using the caller's RuntimeContext;
  • stores a per-call subagent snapshot in RuntimeContext;
  • makes agent_spawn resolve the same call-scoped manager;
  • adds an Alice/Bob interleaving regression test;
  • updates outdated manager documentation.

Validation performed:

  • mvn -T1 -pl agentscope-harness -am -Dtest=HarnessAgentTest#staticSubagentsMiddleware_keepsNamespacedDeclarationsCallScoped test

Checklist

  • Code has been formatted with mvn spotless:apply
  • All tests are passing (mvn test) — full suite not run; targeted regression test passed
  • Javadoc comments are complete and follow project conventions
  • Related documentation has been updated (e.g. links, examples, etc.) — not applicable
  • Code is ready for review

Copilot AI review requested due to automatic review settings July 23, 2026 15:44

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Pull request overview

This PR fixes a concurrency bug in agentscope-harness where static subagent Markdown declarations (and the DefaultAgentManager derived from them) could be overwritten across concurrent calls, causing one user’s invocation to see another user’s subagent registry. It does this by making subagent declaration loading namespace-aware via RuntimeContext, caching an immutable per-call snapshot on the RuntimeContext, and teaching agent_spawn / agent_send to resolve the same call-scoped manager.

Changes:

  • Add RuntimeContext-aware overloads to AgentSpecLoader.loadFromFilesystem(...) and use them from SubagentsMiddleware.
  • Store a per-call subagent snapshot (entries + DefaultAgentManager) in RuntimeContext, and pass the selected manager to tools via AgentSpawnTool.CTX_AGENT_MANAGER.
  • Update AgentSpawnTool to consistently resolve the manager from RuntimeContext (with fallback to the tool’s default manager) and add regression tests.

Reviewed changes

Copilot reviewed 5 out of 5 changed files in this pull request and generated 3 comments.

Show a summary per file
File Description
agentscope-harness/src/test/java/io/agentscope/harness/agent/HarnessAgentTest.java Adds tests for namespaced Markdown declarations and call-scoped isolation; introduces a recording Model helper.
agentscope-harness/src/main/java/io/agentscope/harness/agent/tool/AgentSpawnTool.java Resolves DefaultAgentManager per invocation from RuntimeContext to keep agent_spawn/agent_send consistent with call-scoped subagent snapshots.
agentscope-harness/src/main/java/io/agentscope/harness/agent/subagent/DefaultAgentManager.java Updates refreshEntries documentation to reflect its simpler role after the snapshot approach.
agentscope-harness/src/main/java/io/agentscope/harness/agent/subagent/AgentSpecLoader.java Adds a RuntimeContext-aware filesystem loader overload and updates Javadoc to clarify when to use it.
agentscope-harness/src/main/java/io/agentscope/harness/agent/middleware/SubagentsMiddleware.java Removes shared mutable entry refresh; loads a per-call snapshot and installs it into RuntimeContext for concurrency safety.

Comment on lines +564 to +565
aliceCall.block();
bobCall.block();

private static final class RecordingModel implements Model {

private final List<List<Msg>> inputs = new java.util.concurrent.CopyOnWriteArrayList<>();
Comment on lines +1364 to +1367
public Flux<ChatResponse> stream(
List<Msg> messages,
List<ToolSchema> tools,
io.agentscope.core.model.GenerateOptions options) {
@codecov

codecov Bot commented Jul 23, 2026

Copy link
Copy Markdown

Codecov Report

❌ Patch coverage is 77.77778% with 10 lines in your changes missing coverage. Please review.

Files with missing lines Patch % Lines
.../agentscope/harness/agent/tool/AgentSpawnTool.java 71.42% 5 Missing and 1 partial ⚠️
.../harness/agent/middleware/SubagentsMiddleware.java 81.81% 2 Missing and 2 partials ⚠️

📢 Thoughts on this report? Let us know!

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[Bug] AgentSpecLoader glob fails to find *.md subagent files under ShellAwareOverlay filesystem

2 participants