Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -399,6 +399,8 @@ static SubagentFactory buildDeclaredFactory(
capturedLocalFilesystemSpec = b.localFilesystemSpec;
final List<AgentSkillRepository> capturedSkillRepos = List.copyOf(b.skillRepositories);
final Path capturedProjectGlobalSkillsDir = b.projectGlobalSkillsDir;
final CompactionConfig capturedCompactionConfig = b.compactionConfig;
final boolean capturedDisableCompaction = b.disableCompaction;
// See buildGeneralPurposeFactory: propagate the parent's (distributed) state store so the
// subagent's conversation survives cross-node re-materialization. Null in local defaults.
final io.agentscope.core.state.AgentStateStore capturedStateStore = b.stateStoreOverride;
Expand Down Expand Up @@ -470,6 +472,15 @@ static SubagentFactory buildDeclaredFactory(
if (capturedModelExec != null) sub.modelExecutionConfig(capturedModelExec);
if (capturedToolExec != null) sub.toolExecutionConfig(capturedToolExec);

CompactionConfig declaredCompactionConfig = decl.getCompactionConfig();
if (declaredCompactionConfig != null) {
sub.compaction(declaredCompactionConfig);
} else if (capturedDisableCompaction) {
sub.disableCompaction();
} else if (capturedCompactionConfig != null) {
sub.compaction(capturedCompactionConfig);
}

if (capturedDisableFilesystemTools) sub.disableFilesystemTools();
if (capturedDisableShellTool) sub.disableShellTool();
if (capturedDisableMemoryTools) sub.disableMemoryTools();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@
*/
package io.agentscope.harness.agent.subagent;

import io.agentscope.harness.agent.memory.compaction.CompactionConfig;
import java.nio.file.Path;
import java.util.List;
import java.util.Map;
Expand Down Expand Up @@ -95,6 +96,7 @@ public enum Mode {
private final Boolean exposeToUser;
private final List<String> tools;
private final List<String> skills;
private final CompactionConfig compactionConfig;

/** Base URL of the remote task server (e.g. {@code http://host:8080}). */
private final String url;
Expand All @@ -119,6 +121,7 @@ private SubagentDeclaration(Builder b) {
this.exposeToUser = b.exposeToUser;
this.tools = b.tools != null ? List.copyOf(b.tools) : List.of();
this.skills = b.skills != null ? List.copyOf(b.skills) : List.of();
this.compactionConfig = b.compactionConfig;
this.url = b.url;
this.headers = b.headers != null && !b.headers.isEmpty() ? Map.copyOf(b.headers) : null;
}
Expand Down Expand Up @@ -280,6 +283,16 @@ public List<String> getSkills() {
return skills;
}

/**
* Optional compaction configuration for this subagent.
*
* <p>When {@code null}, the subagent inherits the parent agent's compaction configuration and
* enabled/disabled state.
*/
public CompactionConfig getCompactionConfig() {
return compactionConfig;
}

/** Returns {@code true} when this declaration targets a remote task HTTP server. */
public boolean isRemote() {
return url != null && !url.isBlank();
Expand Down Expand Up @@ -328,6 +341,7 @@ public static final class Builder {
private Boolean exposeToUser;
private List<String> tools;
private List<String> skills;
private CompactionConfig compactionConfig;
private String url;
private Map<String, String> headers;

Expand Down Expand Up @@ -501,6 +515,18 @@ public Builder skills(List<String> skills) {
return this;
}

/**
* Sets a compaction configuration for this subagent.
*
* <p>An explicit declaration-level configuration takes precedence over the parent agent's
* compaction configuration and can enable compaction for this subagent even when the parent
* disables it.
*/
public Builder compaction(CompactionConfig compactionConfig) {
this.compactionConfig = compactionConfig;
return this;
}

/**
* Remote task server base URL. Mutually exclusive with {@link #workspace(Path)} and a
* non-blank {@link #inlineAgentsBody(String)}.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -943,6 +943,74 @@ void declaredSubagent_inheritsExecutionConfigsFromParent() throws Exception {
"declared subagent must inherit parent modelExecutionConfig");
}

@Test
void declaredSubagent_explicitCompactionOverridesDisabledParent() throws Exception {
Files.createDirectories(workspace);
CompactionConfig subagentCompaction = CompactionConfig.builder().triggerMessages(5).build();
SubagentDeclaration decl =
SubagentDeclaration.builder()
.name("compact-worker")
.description("worker with independent compaction")
.inlineAgentsBody("You are a worker subagent.")
.compaction(subagentCompaction)
.build();

List<SubagentEntry> entries =
HarnessAgent.builder()
.model(stubModel("ok"))
.workspace(workspace)
.disableCompaction()
.subagent(decl)
.buildSubagentEntries(workspace);

HarnessAgent child =
(HarnessAgent)
entries.stream()
.filter(e -> "compact-worker".equals(e.name()))
.findFirst()
.orElseThrow()
.factory()
.create(RuntimeContext.empty());

assertSame(subagentCompaction, decl.getCompactionConfig());
assertNotNull(
child.getCompactionHook(),
"declaration-level compaction must override the disabled parent");
}

@Test
void declaredSubagent_withoutCompactionOverrideInheritsDisabledParent() throws Exception {
Files.createDirectories(workspace);
SubagentDeclaration decl =
SubagentDeclaration.builder()
.name("non-compacting-worker")
.description("worker inheriting disabled compaction")
.inlineAgentsBody("You are a worker subagent.")
.build();

List<SubagentEntry> entries =
HarnessAgent.builder()
.model(stubModel("ok"))
.workspace(workspace)
.disableCompaction()
.subagent(decl)
.buildSubagentEntries(workspace);

HarnessAgent child =
(HarnessAgent)
entries.stream()
.filter(e -> "non-compacting-worker".equals(e.name()))
.findFirst()
.orElseThrow()
.factory()
.create(RuntimeContext.empty());

assertNull(decl.getCompactionConfig());
assertNull(
child.getCompactionHook(),
"subagent without an override must inherit disabled compaction");
}

// =========================================================================
// general-purpose mirroring
// =========================================================================
Expand Down
Loading