Fix OpenCode child auto accept inheritance
This commit is contained in:
@@ -12,6 +12,7 @@ import type {
|
|||||||
} from "./agent-sdk-types.js";
|
} from "./agent-sdk-types.js";
|
||||||
import type { ManagedAgent } from "./agent-manager.js";
|
import type { ManagedAgent } from "./agent-manager.js";
|
||||||
import { ProviderSnapshotManager } from "./provider-snapshot-manager.js";
|
import { ProviderSnapshotManager } from "./provider-snapshot-manager.js";
|
||||||
|
import { OpenCodeAgentClient } from "./providers/opencode-agent.js";
|
||||||
|
|
||||||
const TEST_CAPABILITIES = {
|
const TEST_CAPABILITIES = {
|
||||||
supportsStreaming: false,
|
supportsStreaming: false,
|
||||||
@@ -449,6 +450,62 @@ describe("ProviderSnapshotManager public surface", () => {
|
|||||||
manager.destroy();
|
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", () => {
|
describe("ProviderSnapshotManager applyMutableProviderConfig", () => {
|
||||||
|
|||||||
@@ -206,6 +206,29 @@ describe("OpenCode auto_accept feature", () => {
|
|||||||
).toEqual({ modeId: "paseo-custom", featureValues: { auto_accept: true } });
|
).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 () => {
|
test("auto-approves tool permissions when auto accept is enabled", async () => {
|
||||||
const { openCodeClient, runtime } = mockOpenCodeClient({
|
const { openCodeClient, runtime } = mockOpenCodeClient({
|
||||||
events: [toolPermissionEvent(), idleEvent()],
|
events: [toolPermissionEvent(), idleEvent()],
|
||||||
|
|||||||
@@ -133,8 +133,8 @@ function resolveOpenCodeCreateConfig(
|
|||||||
): ResolveAgentCreateConfigResult {
|
): ResolveAgentCreateConfigResult {
|
||||||
const legacyFullAccess = input.requestedMode === OPENCODE_LEGACY_FULL_ACCESS_MODE_ID;
|
const legacyFullAccess = input.requestedMode === OPENCODE_LEGACY_FULL_ACCESS_MODE_ID;
|
||||||
const parent = input.parent;
|
const parent = input.parent;
|
||||||
const inheritsUnattended =
|
const isUnattendedCreate = input.unattended || parent?.isUnattended === true;
|
||||||
input.requestedMode === undefined && (input.unattended || parent?.isUnattended === true);
|
const inheritsUnattended = input.requestedMode === undefined && isUnattendedCreate;
|
||||||
const inheritedOpenCodeMode =
|
const inheritedOpenCodeMode =
|
||||||
inheritsUnattended && parent?.provider === input.provider
|
inheritsUnattended && parent?.provider === input.provider
|
||||||
? (parent.modeId ?? undefined)
|
? (parent.modeId ?? undefined)
|
||||||
@@ -144,7 +144,7 @@ function resolveOpenCodeCreateConfig(
|
|||||||
: (input.requestedMode ?? inheritedOpenCodeMode);
|
: (input.requestedMode ?? inheritedOpenCodeMode);
|
||||||
const featureValues =
|
const featureValues =
|
||||||
legacyFullAccess ||
|
legacyFullAccess ||
|
||||||
(inheritsUnattended && input.featureValues?.[OPENCODE_AUTO_ACCEPT_FEATURE_ID] === undefined)
|
(isUnattendedCreate && input.featureValues?.[OPENCODE_AUTO_ACCEPT_FEATURE_ID] === undefined)
|
||||||
? withOpenCodeAutoAcceptFeature(input.featureValues, true)
|
? withOpenCodeAutoAcceptFeature(input.featureValues, true)
|
||||||
: input.featureValues;
|
: input.featureValues;
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user