Show free-write answers for OpenCode questions

This commit is contained in:
Mohamed Boudra
2026-06-04 15:13:47 +07:00
parent 3ecf86933f
commit 88d44ab2c5
3 changed files with 76 additions and 1 deletions
@@ -76,4 +76,27 @@ describe("question form card core", () => {
Response: "custom",
});
});
test("shows text input for questions that allow other answers", () => {
const questions = parseQuestionFormQuestions({
questions: [
{
question: "Pick or type",
header: "Response",
options: [{ label: "A" }],
allowOther: true,
multiSelect: false,
},
],
});
if (!questions) throw new Error("questions did not parse");
const [question] = questions;
if (!question) throw new Error("question missing");
expect(questionShowsTextInput(question)).toBe(true);
expect(areQuestionsAnswered(questions, {}, { 0: "custom" })).toBe(true);
expect(buildQuestionFormAnswers(questions, {}, { 0: "custom" })).toEqual({
Response: "custom",
});
});
});
@@ -40,7 +40,7 @@ function toolPermissionEvent(): unknown {
};
}
function questionEvent(): unknown {
function questionEvent(questionOverrides: Record<string, unknown> = {}): unknown {
return {
type: "question.asked",
properties: {
@@ -51,6 +51,7 @@ function questionEvent(): unknown {
question: "Which option should OpenCode use?",
header: "Decision",
options: [{ label: "Proceed", description: "Continue with the change" }],
...questionOverrides,
},
],
tool: {
@@ -299,4 +300,54 @@ describe("OpenCode auto_accept feature", () => {
await session.close();
});
test("surfaces OpenCode questions with a free-write answer option", async () => {
const { openCodeClient, runtime } = mockOpenCodeClient({
events: [questionEvent({ custom: false }), idleEvent()],
});
const receivedEvents: AgentStreamEvent[] = [];
const client = new OpenCodeAgentClient(createTestLogger(), undefined, { runtime });
const session = await client.createSession({
provider: "opencode",
cwd: "/tmp/project",
});
session.subscribe((event) => receivedEvents.push(event));
await session.run("Ask a question");
expect(receivedEvents.filter((event) => event.type === "permission_requested")).toEqual([
expect.objectContaining({
request: expect.objectContaining({
id: "question-1",
kind: "question",
input: {
questions: [
{
question: "Which option should OpenCode use?",
header: "Decision",
options: [{ label: "Proceed", description: "Continue with the change" }],
allowOther: true,
},
],
},
}),
}),
]);
await session.respondToPermission("question-1", {
behavior: "allow",
updatedInput: { answers: { Decision: "Use another answer" } },
});
expect(openCodeClient.calls.questionReply).toEqual([
{
requestID: "question-1",
directory: "/tmp/project",
answers: [["Use another answer"]],
},
]);
await session.close();
});
});
@@ -2521,6 +2521,7 @@ function appendOpenCodeQuestionAsked(
header: q.header,
options,
...(q.multiple === true ? { multiSelect: true } : {}),
allowOther: true,
},
];
});