fix question options rendering permanently disabled
AskUserQuestion has no answer channel: it resolves itself the moment it is called, returning "The user did not answer the questions." before the buttons have painted. QuestionActivity gated its options on `message.output === undefined`, so that self-resolve disabled every option on every question, always. Reported from real use — muted text, no-entry cursor, nothing clickable. The output means the tool call is over, which is true and irrelevant. The answer travels back as an ordinary chat message. `sent` is the only real latch. The test was the worse half: it asserted the greyed-out state was correct, using the literal self-resolve string as its fixture. Code and test were wrong in the same direction, so a green suite sat on top of a feature that had never once worked. Inverted it, and verified it fails against the old logic rather than just passing against the new. Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
@@ -106,8 +106,14 @@ describe('the escape hatch', () => {
|
||||
});
|
||||
});
|
||||
|
||||
describe('a question the harness already resolved', () => {
|
||||
test('is read-only — its answer cannot be changed', () => {
|
||||
// The regression that made this component dead on arrival, pinned from both sides.
|
||||
//
|
||||
// AskUserQuestion has no answer channel: it resolves ITSELF, immediately, with the string below — so a
|
||||
// real question always carries an output by the time it renders. The component gated on that output, and
|
||||
// the test here asserted the resulting greyed-out state was correct. Both were wrong in the same
|
||||
// direction, so the suite passed and every question in the product was unclickable.
|
||||
describe('a question the SDK has already self-resolved', () => {
|
||||
test('is still answerable — the output ends the tool call, not the conversation', () => {
|
||||
const answers: string[] = [];
|
||||
const resolved = {
|
||||
...ask([{ question: 'Which?', header: 'Store', options: OPTIONS }]),
|
||||
@@ -115,6 +121,19 @@ describe('a question the harness already resolved', () => {
|
||||
} as never;
|
||||
render(<QuestionActivity message={resolved} onAnswer={(t) => answers.push(t)} />);
|
||||
fireEvent.click(screen.getByText('Postgres'));
|
||||
expect(answers).toEqual([]);
|
||||
expect(answers).toEqual(['Postgres']);
|
||||
});
|
||||
|
||||
test('but answering twice is refused — the latch is what we sent, not what the tool returned', () => {
|
||||
const answers: string[] = [];
|
||||
render(
|
||||
<QuestionActivity
|
||||
message={{ ...ask([{ question: 'Which?', header: 'Store', options: OPTIONS }]), output: 'x' } as never}
|
||||
onAnswer={(t) => answers.push(t)}
|
||||
/>,
|
||||
);
|
||||
fireEvent.click(screen.getByText('Postgres'));
|
||||
fireEvent.click(screen.getByText('SQLite'));
|
||||
expect(answers).toEqual(['Postgres']);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -67,9 +67,16 @@ export const QuestionActivity = ({ message, onAnswer }: QuestionActivityProps) =
|
||||
const questions = input.questions;
|
||||
if (!questions || questions.length === 0) return null;
|
||||
|
||||
// A tool call with an output has already been resolved by the harness; nothing here can change it.
|
||||
const pending = message.output === undefined;
|
||||
const isDisabled = sent || !pending;
|
||||
// Deliberately NOT gated on `message.output`.
|
||||
//
|
||||
// AskUserQuestion resolves itself the instant it is called — the SDK has no answer channel, so it
|
||||
// returns "The user did not answer the questions." before these buttons have painted. Gating on the
|
||||
// output therefore disabled every option on every question, always: the tool was rendered, greyed out,
|
||||
// and unanswerable. A test asserted that as correct, so the suite stayed green over a dead feature.
|
||||
//
|
||||
// The output says the TOOL CALL is over, which is true and irrelevant. The answer travels back as an
|
||||
// ordinary chat message, and a message can always be sent. `sent` is the only real latch.
|
||||
const isDisabled = sent;
|
||||
|
||||
/**
|
||||
* Record one answer, and send once EVERY question has one.
|
||||
|
||||
Reference in New Issue
Block a user