Fix OpenCode child auto accept inheritance

This commit is contained in:
Mohamed Boudra
2026-06-04 15:12:12 +07:00
parent 1b350ac09e
commit 3ecf86933f
3 changed files with 83 additions and 3 deletions
@@ -12,6 +12,7 @@ import type {
} from "./agent-sdk-types.js";
import type { ManagedAgent } from "./agent-manager.js";
import { ProviderSnapshotManager } from "./provider-snapshot-manager.js";
import { OpenCodeAgentClient } from "./providers/opencode-agent.js";
const TEST_CAPABILITIES = {
supportsStreaming: false,
@@ -449,6 +450,62 @@ describe("ProviderSnapshotManager public surface", () => {
manager.destroy();
}
});
test("treats an OpenCode parent with auto accept as unattended when resolving an explicit child mode", async () => {
const openCode = new OpenCodeAgentClient(createTestLogger());
const modes: AgentMode[] = [
{ id: "build", label: "Build" },
{ id: "base", label: "Base" },
{ id: "orchestrator", label: "Orchestrator" },
];
const manager = new ProviderSnapshotManager({
logger: createTestLogger(),
providerOverrides: {
claude: { enabled: false },
codex: { enabled: false },
copilot: { enabled: false },
pi: { enabled: false },
},
extraClients: {
opencode: createExtraClient("opencode", {
async isAvailable() {
return true;
},
async listModes() {
return modes;
},
resolveCreateConfig: openCode.resolveCreateConfig.bind(openCode),
isCreateConfigUnattended: openCode.isCreateConfigUnattended.bind(openCode),
}),
},
});
try {
const parent = {
id: "parent-agent",
provider: "opencode",
currentModeId: "orchestrator",
availableModes: modes,
config: {
provider: "opencode",
cwd: "/tmp/project",
featureValues: { auto_accept: true },
},
} as ManagedAgent;
const resolved = await manager.resolveCreateConfig({
cwd: "/tmp/project",
provider: "opencode",
requestedMode: "base",
featureValues: undefined,
parent,
unattended: false,
});
expect(resolved).toEqual({ modeId: "base", featureValues: { auto_accept: true } });
} finally {
manager.destroy();
}
});
});
describe("ProviderSnapshotManager applyMutableProviderConfig", () => {
@@ -206,6 +206,29 @@ describe("OpenCode auto_accept feature", () => {
).toEqual({ modeId: "paseo-custom", featureValues: { auto_accept: true } });
});
test("inherits auto accept from an OpenCode parent when the child chooses a mode", () => {
const client = new OpenCodeAgentClient(createTestLogger());
expect(
client.resolveCreateConfig({
provider: "opencode",
requestedMode: "base",
featureValues: undefined,
parent: {
provider: "opencode",
modeId: "orchestrator",
isUnattended: true,
},
unattended: true,
availableModes: [
{ id: "build", label: "Build" },
{ id: "base", label: "Base" },
{ id: "orchestrator", label: "Orchestrator" },
],
}),
).toEqual({ modeId: "base", featureValues: { auto_accept: true } });
});
test("auto-approves tool permissions when auto accept is enabled", async () => {
const { openCodeClient, runtime } = mockOpenCodeClient({
events: [toolPermissionEvent(), idleEvent()],
@@ -133,8 +133,8 @@ function resolveOpenCodeCreateConfig(
): ResolveAgentCreateConfigResult {
const legacyFullAccess = input.requestedMode === OPENCODE_LEGACY_FULL_ACCESS_MODE_ID;
const parent = input.parent;
const inheritsUnattended =
input.requestedMode === undefined && (input.unattended || parent?.isUnattended === true);
const isUnattendedCreate = input.unattended || parent?.isUnattended === true;
const inheritsUnattended = input.requestedMode === undefined && isUnattendedCreate;
const inheritedOpenCodeMode =
inheritsUnattended && parent?.provider === input.provider
? (parent.modeId ?? undefined)
@@ -144,7 +144,7 @@ function resolveOpenCodeCreateConfig(
: (input.requestedMode ?? inheritedOpenCodeMode);
const featureValues =
legacyFullAccess ||
(inheritsUnattended && input.featureValues?.[OPENCODE_AUTO_ACCEPT_FEATURE_ID] === undefined)
(isUnattendedCreate && input.featureValues?.[OPENCODE_AUTO_ACCEPT_FEATURE_ID] === undefined)
? withOpenCodeAutoAcceptFeature(input.featureValues, true)
: input.featureValues;