OpenAI Integration
This guide shows how to use VersionR alongside the OpenAI Node.js SDK. The pattern is the same regardless of which OpenAI model you use.
Installation
npm install versionr openaiSetup
import OpenAI from 'openai'
import { VersionR } from 'versionr'
const openai = new OpenAI({ apiKey: process.env.OPENAI_API_KEY })
const pd = new VersionR({ apiKey: process.env.VERSIONR_API_KEY })Basic usage with pd.get()
Fetch the prompt and pass it directly to the Chat Completions API:
const startTime = Date.now()
const prompt = await pd.get('support-responder', { env: 'production' })
const response = await openai.chat.completions.create({
model: prompt.model, // versioned model name
temperature: prompt.temperature,
messages: [
{ role: prompt.role, content: prompt.content },
{ role: 'user', content: userMessage },
],
})
const output = response.choices[0]?.message.content ?? ''
await pd.log({
promptId: prompt.promptId,
promptSlug: prompt.promptSlug,
versionId: prompt.versionId,
versionNumber: prompt.versionNumber,
environment: 'production',
renderedPrompt: prompt.content,
output,
latencyMs: Date.now() - startTime,
tokens: {
prompt: response.usage?.prompt_tokens ?? 0,
completion: response.usage?.completion_tokens ?? 0,
},
})With variable substitution
Use pd.render() when your prompt has {{variable}} slots:
const startTime = Date.now()
const rendered = await pd.render('onboarding-email', {
env: 'production',
variables: {
user_name: user.name,
plan_name: user.plan,
trial_days: String(user.trialDays),
},
})
const response = await openai.chat.completions.create({
model: rendered.model,
temperature: rendered.temperature,
messages: [
{ role: rendered.role, content: rendered.content },
],
})
const output = response.choices[0]?.message.content ?? ''
await pd.log({
promptId: rendered.promptId,
promptSlug: rendered.promptSlug,
versionId: rendered.versionId,
versionNumber: rendered.versionNumber,
environment: 'production',
renderedPrompt: rendered.rendered,
output,
latencyMs: Date.now() - startTime,
tokens: {
prompt: response.usage?.prompt_tokens ?? 0,
completion: response.usage?.completion_tokens ?? 0,
},
})Streaming
VersionR works with OpenAI streaming — fetch the prompt first, then stream the response:
const rendered = await pd.render('chat-assistant', {
env: 'production',
variables: { context: pageContext },
})
const stream = await openai.chat.completions.create({
model: rendered.model,
temperature: rendered.temperature,
stream: true,
messages: [
{ role: rendered.role, content: rendered.content },
{ role: 'user', content: userMessage },
],
})
let fullOutput = ''
const startTime = Date.now()
for await (const chunk of stream) {
const delta = chunk.choices[0]?.delta.content ?? ''
fullOutput += delta
process.stdout.write(delta)
}
// Log after stream completes
await pd.log({
promptId: rendered.promptId,
promptSlug: rendered.promptSlug,
versionId: rendered.versionId,
versionNumber: rendered.versionNumber,
environment: 'production',
renderedPrompt: rendered.rendered,
output: fullOutput,
latencyMs: Date.now() - startTime,
// Note: usage is not available mid-stream with all models
})Structured outputs
VersionR is compatible with OpenAI’s structured output / response format feature:
const rendered = await pd.render('data-extractor', {
env: 'production',
variables: { document: rawText },
})
const response = await openai.chat.completions.create({
model: rendered.model,
temperature: rendered.temperature,
response_format: { type: 'json_object' },
messages: [
{ role: rendered.role, content: rendered.content },
],
})
const data = JSON.parse(response.choices[0]?.message.content ?? '{}')