Skip to content

Commit 5f3e98c

Browse files
committed
fix: unwrap label-as-key option objects in ask_user
1 parent 55ea894 commit 5f3e98c

2 files changed

Lines changed: 23 additions & 0 deletions

File tree

source/utils/type-helpers.spec.ts

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -144,6 +144,13 @@ test('toOptionString extracts content-shaped options', t => {
144144
);
145145
});
146146

147+
test('toOptionString uses the lone key when value is empty (label-as-key shape)', t => {
148+
t.is(
149+
toOptionString({'Playfair Display - elegant, high-contrast, editorial': ''}),
150+
'Playfair Display - elegant, high-contrast, editorial',
151+
);
152+
});
153+
147154
test('toOptionString falls back to JSON for unlabeled objects', t => {
148155
t.is(toOptionString({foo: 1}), JSON.stringify({foo: 1}));
149156
});

source/utils/type-helpers.ts

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -238,6 +238,22 @@ export function toOptionString(option: unknown): string {
238238
return candidate;
239239
}
240240
}
241+
// Some models emit each option as a single-entry map where the KEY is
242+
// the display text and the value is empty, e.g.
243+
// `{"Playfair Display - elegant, high-contrast, editorial": ""}`. None
244+
// of the known keys match, so fall back to the lone key as the label.
245+
// Guarded on an empty value so genuinely-keyed objects like `{foo: 1}`
246+
// still serialize to JSON.
247+
const entries = Object.entries(option);
248+
if (entries.length === 1) {
249+
const [key, value] = entries[0];
250+
if (
251+
key.trim() !== '' &&
252+
(value === '' || value === null || value === undefined)
253+
) {
254+
return key;
255+
}
256+
}
241257
}
242258
return ensureString(option);
243259
}

0 commit comments

Comments
 (0)