mirror of
https://github.com/google-gemini/gemini-cli.git
synced 2026-06-01 14:42:51 -07:00
feat(core): add fallback support and falsy value normalization to PromptSection
This commit is contained in:
@@ -284,6 +284,60 @@ const tests: TestCase[] = [
|
||||
context: {},
|
||||
expect: '# Lines List\n\nLine 1\nLine 2\nLine 3',
|
||||
},
|
||||
{
|
||||
desc: 'renders fallback when content is falsy (boolean)',
|
||||
content: {
|
||||
heading: 'Fallback Boolean',
|
||||
content: false,
|
||||
fallback: 'This is the fallback',
|
||||
},
|
||||
context: {},
|
||||
expect: '# Fallback Boolean\n\nThis is the fallback',
|
||||
},
|
||||
{
|
||||
desc: 'renders fallback when content is falsy (empty string via short-circuit)',
|
||||
content: {
|
||||
heading: 'Fallback Empty String',
|
||||
content: String('') && 'something',
|
||||
fallback: 'Fallback for empty string',
|
||||
},
|
||||
context: {},
|
||||
expect: '# Fallback Empty String\n\nFallback for empty string',
|
||||
},
|
||||
{
|
||||
desc: 'renders fallback when content is an array that filters down to empty',
|
||||
content: {
|
||||
heading: 'Fallback Empty Array',
|
||||
content: [false, null, '', undefined],
|
||||
fallback: 'Fallback for empty array',
|
||||
},
|
||||
context: {},
|
||||
expect: '# Fallback Empty Array\n\nFallback for empty array',
|
||||
},
|
||||
{
|
||||
desc: 'renders normal content and ignores fallback when content is present',
|
||||
content: {
|
||||
heading: 'No Fallback',
|
||||
content: 'Primary content',
|
||||
fallback: 'Should not see this',
|
||||
},
|
||||
context: {},
|
||||
expect: '# No Fallback\n\nPrimary content',
|
||||
},
|
||||
{
|
||||
desc: 'does not render section if both content and fallback are falsy',
|
||||
content: [
|
||||
'Visible start',
|
||||
{
|
||||
heading: 'Double Falsy',
|
||||
content: '',
|
||||
fallback: null,
|
||||
},
|
||||
'Visible end',
|
||||
],
|
||||
context: {},
|
||||
expect: 'Visible start\n\nVisible end',
|
||||
},
|
||||
];
|
||||
|
||||
describe('renderPrompt', () => {
|
||||
|
||||
@@ -34,6 +34,8 @@ export type PromptSection<C, Sync extends boolean = false> = {
|
||||
/** Condition that must evaluate to true for the section to be rendered. */
|
||||
condition?: boolean | ((ctx: C) => MaybePromise<boolean, Sync>);
|
||||
content: PromptContent<C, Sync>;
|
||||
/** Alternate content to render if the primary content resolves to a falsy value. */
|
||||
fallback?: PromptContent<C, Sync>;
|
||||
};
|
||||
|
||||
// The core recursive type.
|
||||
@@ -189,7 +191,8 @@ export async function renderPrompt<C = SystemPromptOptions>({
|
||||
return null;
|
||||
}
|
||||
if (typeof c === 'string' || typeof c === 'number') {
|
||||
return String(c);
|
||||
const val = String(c);
|
||||
return val === '' ? null : val;
|
||||
}
|
||||
if (Array.isArray(c)) {
|
||||
const resolved = await Promise.all(c.map((item) => resolveToBasic(item)));
|
||||
@@ -212,7 +215,18 @@ export async function renderPrompt<C = SystemPromptOptions>({
|
||||
: section.condition;
|
||||
if (!shouldRender) return null;
|
||||
}
|
||||
const resolvedInner = await resolveToBasic(section.content);
|
||||
let resolvedInner = await resolveToBasic(section.content);
|
||||
|
||||
if (
|
||||
resolvedInner === null ||
|
||||
resolvedInner === '' ||
|
||||
(Array.isArray(resolvedInner) && resolvedInner.length === 0)
|
||||
) {
|
||||
if (section.fallback !== undefined) {
|
||||
resolvedInner = await resolveToBasic(section.fallback);
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
resolvedInner === null ||
|
||||
resolvedInner === '' ||
|
||||
@@ -294,7 +308,8 @@ export function renderPromptSync<C = SystemPromptOptions>({
|
||||
return null;
|
||||
}
|
||||
if (typeof c === 'string' || typeof c === 'number') {
|
||||
return String(c);
|
||||
const val = String(c);
|
||||
return val === '' ? null : val;
|
||||
}
|
||||
if (Array.isArray(c)) {
|
||||
const resolved = c.map((item) => resolveToBasicSync(item));
|
||||
@@ -324,7 +339,18 @@ export function renderPromptSync<C = SystemPromptOptions>({
|
||||
}
|
||||
if (!shouldRender) return null;
|
||||
}
|
||||
const resolvedInner = resolveToBasicSync(section.content);
|
||||
let resolvedInner = resolveToBasicSync(section.content);
|
||||
|
||||
if (
|
||||
resolvedInner === null ||
|
||||
resolvedInner === '' ||
|
||||
(Array.isArray(resolvedInner) && resolvedInner.length === 0)
|
||||
) {
|
||||
if (section.fallback !== undefined) {
|
||||
resolvedInner = resolveToBasicSync(section.fallback);
|
||||
}
|
||||
}
|
||||
|
||||
if (
|
||||
resolvedInner === null ||
|
||||
resolvedInner === '' ||
|
||||
@@ -366,6 +392,5 @@ export function renderPromptSync<C = SystemPromptOptions>({
|
||||
export function prompt<C = SystemPromptOptions, Sync extends boolean = false>(
|
||||
...content: Array<PromptContent<C, Sync>>
|
||||
): PromptContent<C, Sync> {
|
||||
|
||||
return (content.length === 1 ? content[0] : content);
|
||||
return content.length === 1 ? content[0] : content;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user