Skip to content

Variable Injection ​

Learn how to inject variables into content with Mustache-style syntax, variable precedence, and environment variable filtering.

How It Works ​

Variables are injected into content using Mustache-style syntax:

This is a {{ VARIABLE_NAME }} example.

Variable resolution follows this precedence (highest to lowest):

  1. Variables passed in method call
  2. Variables from constructor options
  3. Environment variables matching allowed prefixes
  4. Replaced by an empty string if not found

Environment Variables ​

Environment variables are filtered by prefix for security. Only environment variables matching the allowed prefixes will be injected.

Default Prefixes ​

By default, these prefixes are allowed:

  • CARNET_
  • PUBLIC_

Custom Prefixes ​

Specify custom prefixes when creating a Carnet instance:

typescript
const carnet = new Carnet(manifest, {
  envPrefixes: ['MYAPP_', 'PUBLIC_'],
})

Examples ​

Setup ​

typescript
// Setup with variables
const carnet = new Carnet(manifest, {
  variables: { userFullName: 'John Doe' },
  envPrefixes: ['MYAPP_'],
})

// Environment variable (MYAPP_KEY)
process.env.MYAPP_KEY = 'secret'

Content Retrieval ​

typescript
// Content with variables
const content = carnet.getSkillContent('mySkill')

// Override for specific call
const custom = carnet.getSkillContent('mySkill', {
  variables: { userFullName: 'John Doe' }
})
// {{ userFullName }} gets replaced with "John Doe" in all content

Precedence Example ​

When a variable is defined in multiple places:

typescript
const carnet = new Carnet(manifest, {
  variables: { ENV: 'production' }
})

process.env.CARNET_ENV = 'development'

// Method call override takes precedence
const content = carnet.getSkillContent('mySkill', {
  variables: { ENV: 'staging' }
})
// Result: "staging" (from method call)

// Without method override, constructor vars take precedence
const content2 = carnet.getSkillContent('mySkill')
// Result: "production" (from constructor)

// Env vars are used only as fallback

Use Cases ​

Configuration Management ​

typescript
const carnet = new Carnet(manifest, {
  variables: {
    API_BASE: process.env.API_BASE || 'https://api.example.com',
    APP_VERSION: packageJson.version,
  },
})

const skillContent = carnet.getSkillContent('apiIntegration')
// All content has {{ API_BASE }} and {{ APP_VERSION }} injected

Environment-Specific Content ​

typescript
const carnet = new Carnet(manifest, {
  envPrefixes: ['APP_'],
})

process.env.APP_ENVIRONMENT = 'production'
process.env.APP_DEBUG = 'false'

const prompt = carnet.generateAgentPrompt('coder')
// Prompt will contain environment-specific configuration

Runtime Overrides ​

typescript
const basePrompt = carnet.generateAgentPrompt('coder', {
  variables: { THEME: 'dark' }
})

// Get alternative version with different theme
const lightPrompt = carnet.generateAgentPrompt('coder', {
  variables: { THEME: 'light' }
})

Dynamic Prompt Adaptation ​

The most powerful use case for variables is dynamic prompt adaptation. By passing variables to getSystemPrompt(), you can customize prompts at runtime based on user context:

typescript
// Example: Customer support agent with dynamic context
const carnet = new Carnet(manifest, {
  variables: { COMPANY_NAME: 'Acme Corp' }
})

// Adapt prompt based on customer tier
const premiumPrompt = carnet.getSystemPrompt('support', {
  variables: {
    CUSTOMER_TIER: 'premium',
    RESPONSE_STYLE: 'detailed and personalized'
  }
})

const basicPrompt = carnet.getSystemPrompt('support', {
  variables: {
    CUSTOMER_TIER: 'basic',
    RESPONSE_STYLE: 'concise and efficient'
  }
})

// Each call generates a customized prompt for the specific context

Benefits of Dynamic Variables:

  • Context-aware agents: Adapt behavior based on user, session, or request context
  • A/B testing: Test different prompt variations dynamically
  • Multi-tenant systems: Customize prompts per tenant without duplicating content
  • Personalization: Inject user-specific data into prompts at runtime

Security Considerations ​

Environment variable filtering by prefix is a security measure:

typescript
// This configuration is INSECURE - allows all env vars
// ❌ DON'T DO THIS:
const carnet = new Carnet(manifest, {
  envPrefixes: [''] // Empty prefix matches everything
})

// This is SECURE - only allows specific prefixes
// ✅ DO THIS:
const carnet = new Carnet(manifest, {
  envPrefixes: ['MYAPP_', 'PUBLIC_']
})

See Also ​

Released under the MIT License.