mirror of
https://github.com/openclaw/openclaw.git
synced 2026-05-05 15:00:21 +00:00
fix: harden subagent control boundaries
This commit is contained in:
@@ -67,6 +67,22 @@ function supportsSpawnLineage(storeKey: string): boolean {
|
||||
return isSubagentSessionKey(storeKey) || isAcpSessionKey(storeKey);
|
||||
}
|
||||
|
||||
function normalizeSubagentRole(raw: string): "orchestrator" | "leaf" | undefined {
|
||||
const normalized = raw.trim().toLowerCase();
|
||||
if (normalized === "orchestrator" || normalized === "leaf") {
|
||||
return normalized;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
function normalizeSubagentControlScope(raw: string): "children" | "none" | undefined {
|
||||
const normalized = raw.trim().toLowerCase();
|
||||
if (normalized === "children" || normalized === "none") {
|
||||
return normalized;
|
||||
}
|
||||
return undefined;
|
||||
}
|
||||
|
||||
export async function applySessionsPatchToStore(params: {
|
||||
cfg: OpenClawConfig;
|
||||
store: Record<string, SessionEntry>;
|
||||
@@ -134,6 +150,48 @@ export async function applySessionsPatchToStore(params: {
|
||||
}
|
||||
}
|
||||
|
||||
if ("subagentRole" in patch) {
|
||||
const raw = patch.subagentRole;
|
||||
if (raw === null) {
|
||||
if (existing?.subagentRole) {
|
||||
return invalid("subagentRole cannot be cleared once set");
|
||||
}
|
||||
} else if (raw !== undefined) {
|
||||
if (!supportsSpawnLineage(storeKey)) {
|
||||
return invalid("subagentRole is only supported for subagent:* or acp:* sessions");
|
||||
}
|
||||
const normalized = normalizeSubagentRole(String(raw));
|
||||
if (!normalized) {
|
||||
return invalid('invalid subagentRole (use "orchestrator" or "leaf")');
|
||||
}
|
||||
if (existing?.subagentRole && existing.subagentRole !== normalized) {
|
||||
return invalid("subagentRole cannot be changed once set");
|
||||
}
|
||||
next.subagentRole = normalized;
|
||||
}
|
||||
}
|
||||
|
||||
if ("subagentControlScope" in patch) {
|
||||
const raw = patch.subagentControlScope;
|
||||
if (raw === null) {
|
||||
if (existing?.subagentControlScope) {
|
||||
return invalid("subagentControlScope cannot be cleared once set");
|
||||
}
|
||||
} else if (raw !== undefined) {
|
||||
if (!supportsSpawnLineage(storeKey)) {
|
||||
return invalid("subagentControlScope is only supported for subagent:* or acp:* sessions");
|
||||
}
|
||||
const normalized = normalizeSubagentControlScope(String(raw));
|
||||
if (!normalized) {
|
||||
return invalid('invalid subagentControlScope (use "children" or "none")');
|
||||
}
|
||||
if (existing?.subagentControlScope && existing.subagentControlScope !== normalized) {
|
||||
return invalid("subagentControlScope cannot be changed once set");
|
||||
}
|
||||
next.subagentControlScope = normalized;
|
||||
}
|
||||
}
|
||||
|
||||
if ("label" in patch) {
|
||||
const raw = patch.label;
|
||||
if (raw === null) {
|
||||
|
||||
Reference in New Issue
Block a user