Before / after — Vercel AI SDK
A real multi-variable system prompt: {{userName}}, {{planTier}}, {{locale}}. Same data
flow, same model call. The only difference is when the typo gets caught.
Before Vanilla string template
import { generateText } from 'ai';
import { openai } from '@ai-sdk/openai';
const userName = 'alice';
const planTier = 'pro';
const locale = 'en-US';
// Typo intended to be {{userName}} — silently ships to the model.
const system = 'You are a support agent for {{usrName}} on plan {{planTier}}, locale {{locale}}.'
.replace('{{userName}}', userName)
.replace('{{planTier}}', planTier)
.replace('{{locale}}', locale);
const { text } = await generateText({
model: openai('gpt-4o-mini'),
system,
prompt: 'How do I upgrade my plan?'
});
// system is:
// "You are a support agent for {{usrName}} on plan pro, locale en-US."
// ^^^^^^^ leaks to the model The replace for {{userName}} doesn't match
anything (the template has {{usrName}}), so the literal {{usrName}} reaches the model. The runtime works; the
prompt is silently broken.
After tprompt
import { generateText } from 'ai';
import { openai } from '@ai-sdk/openai';
import { prompt } from '@nkwib/tprompt';
const supportSystem = prompt(
'You are a support agent for {{usrName}} on plan {{planTier}}, locale {{locale}}.'
);
const { text } = await generateText({
model: openai('gpt-4o-mini'),
system: supportSystem.with({
userName: 'alice',
// ^^^^^^^^ TS error: Property 'usrName' is missing in type
// '{ readonly userName: string; readonly planTier: string;
// readonly locale: string; }', but the call expects
// '{ readonly usrName: string; readonly planTier: string;
// readonly locale: string; }'.
planTier: 'pro',
locale: 'en-US'
}),
prompt: 'How do I upgrade my plan?'
}); tsc rejects this file before node ever runs.
Either fix the template ({{userName}}) or fix the call
site (usrName: 'alice') — the typo cannot land in
production.
The wedge, in three lines of diff
-const system = 'You are a support agent for {{usrName}}...'
- .replace('{{userName}}', userName)
+const supportSystem = prompt('You are a support agent for {{usrName}}...');
+supportSystem.with({ userName: 'alice', planTier, locale });
+// ~~~~~~~~ tsc: Property 'usrName' is missingTry it
The Playground has the after-snippet pre-loaded. Rename {{usrName}} back to {{userName}} in the
template literal — the error clears.