Skip to content

IQAIcom/prompt-weaver

Prompt Weaver Logo

Prompt Weaver

Craft Powerful, Type-Safe LLM Prompts with Ease

A powerful, extensible template engine built for the AI era. Prompt Weaver combines the flexibility of Handlebars with the safety of TypeScript and Zod/Standard Schema.

FeaturesQuick StartThe Two ApproachesTemplating SyntaxTransformersType Safety


📖 Introduction

Writing prompts for LLMs often involves messy string concatenation, zero type safety, and repetitive code. Prompt Weaver solves this by treating prompts like software artifacts.

It allows you to build dynamic prompts using templates, validate input data with schemas (Zod, Valibot, etc.), and transform data (dates, currency, arrays) directly within the prompt.

✨ Features

  • 🎨 Powerful Templating: Logic-rich templates with loops ({{#each}}), conditionals ({{#if}}), and switch/case logic.

  • ✅ Type Safety & Validation: First-class support for Standard Schema (Zod, ArkType, Valibot). Get automatic TypeScript type inference.

  • 🔧 Rich Toolset: Built-in transformers for Dates, Strings, JSON, Currencies, and Arrays.

  • 🏗️ Fluent Builder API: Construct prompts programmatically using a chainable JavaScript/TypeScript API with support for JSON, links, images, and checkboxes.

  • 🧩 Reusable Partials: Don't repeat yourself—compose prompts from reusable fragments (headers, footers, rules). Partials are pre-compiled for optimal performance.

  • ⚡ Performance Optimized: Template compilation caching and pre-compiled partials for faster rendering.

  • 🎯 Extensible: Create custom transformers and helpers to suit your specific domain.


📦 Installation

npm install @iqai/prompt-weaver

# or

pnpm add @iqai/prompt-weaver

# or

yarn add @iqai/prompt-weaver

🚀 Quick Start

1. The "Hello World"

Start simple. Define a template, inject data, and get a string.

import { PromptWeaver } from "@iqai/prompt-weaver";

// 1. Define a template with variables and a transformer
const template = "Hello {{name}}, your balance is {{currency balance}}.";

// 2. Initialize Weaver
const weaver = new PromptWeaver(template);

// 3. Render
const result = weaver.format({
  name: "Alice",
  balance: 1234.56
});

console.log(result);
// Output: "Hello Alice, your balance is $1,234.56."

2. The Feature Showcase

Here is a more complex example showing loops, conditionals, and formatting.

View Complex Example Code
const template = `
You are helping {{userName}}.

## Task Details

- **Deadline**: {{relativeTime deadline}} ({{formatDate deadline "MMM DD"}})
- **Status**: {{#if isPremium}}⭐ Premium{{else}}Standard{{/if}}

## Requirements

{{#each requirements}}
{{increment @index}}. {{this}}
{{/each}}
`;

const weaver = new PromptWeaver(template);

const output = weaver.format({
  userName: "Alice",
  isPremium: true,
  deadline: new Date(Date.now() + 7 * 24 * 60 * 60 * 1000), // 7 days from now
  requirements: ["Plan project", "Review code"]
});

Output:

You are helping Alice.

## Task Details

- **Deadline**: in 7 days (Dec 12)
- **Status**: ⭐ Premium

## Requirements

1. Plan project
2. Review code

⚖️ The Two Approaches: Builder vs. Weaver

Prompt Weaver offers two ways to create prompts. You can use them separately or together.

Feature PromptWeaver PromptBuilder
Best For... Static templates, recurring tasks, separating content from code. Dynamic logic, building prompts on the fly based on runtime conditions.
Input String template (Handlebars syntax). Method chaining (Fluent API).
Example new PromptWeaver("Hello {{name}}") new PromptBuilder().text("Hello").text(name)

Using the Builder (Fluent API)

Perfect for when you need to construct a prompt logically in your code.

import { PromptBuilder } from "@iqai/prompt-weaver";

const builder = new PromptBuilder()
  .heading(1, "User Profile")
  .section("Info", "Name: {{name}}")
  .list(["Rule 1", "Rule 2"])
  .conditional(true, "✅ Verified", "❌ Unverified")
  .json({ version: "1.0", status: "active" }) // Format JSON
  .link("Documentation", "https://example.com") // Add markdown link
  .checkboxes([
    { text: "Task 1", checked: true },
    { text: "Task 2", checked: false }
  ]); // Add task list

// Convert to Weaver to render data
const weaver = builder.toPromptWeaver();
const output = weaver.format({ name: "Alice" });

Output:

# User Profile

## Info

Name: Alice

- Rule 1
- Rule 2

✅ Verified

```json
{
  "version": "1.0",
  "status": "active"
}
```

[Documentation](https://example.com)

- [x] Task 1
- [ ] Task 2

When to Use Each Approach

Scenario Use Builder Use Weaver Use Both
Static template strings
Dynamic prompt construction
Template rendering with data
Reusable templates
Complex programmatic logic

Workflow: Build → Convert → Render

import { PromptBuilder } from "@iqai/prompt-weaver";

// Step 1: Build programmatically
const builder = new PromptBuilder()
  .heading(1, "User Dashboard")
  .section("Welcome", "Hello {{userName}}!")
  .section("Account Info", "Your balance is {{currency balance}}")
  .conditional(isPremium, "⭐ Premium Member", "Upgrade to Premium");

// Step 2: Convert to PromptWeaver for rendering
const weaver = builder.toPromptWeaver();

// Step 3: Render with data (can be called multiple times)
const output1 = weaver.format({ userName: "Alice", balance: 1000, isPremium: true });
const output2 = weaver.format({ userName: "Bob", balance: 500, isPremium: false });

// Output 1:
// # User Dashboard
//
// ## Welcome
//
// Hello Alice!
//
// ## Account Info
//
// Your balance is $1,000.00
//
// ⭐ Premium Member

// Output 2:
// # User Dashboard
//
// ## Welcome
//
// Hello Bob!
//
// ## Account Info
//
// Your balance is $500.00
//
// Upgrade to Premium

// Step 4: Optional - Validate with schema (TypeScript infers types automatically)
import { z } from 'zod';
const schema = z.object({
  userName: z.string(),
  balance: z.number(),
  isPremium: z.boolean(),
});

// TypeScript automatically infers types from the schema
const weaverWithSchema = builder.toPromptWeaver({ schema });

// format() automatically validates when schema is provided - TypeScript knows the exact shape
const validatedOutput = weaverWithSchema.format({ 
  userName: "Alice", 
  balance: 1000, 
  isPremium: true 
});

🎨 Templating Syntax

Prompt Weaver utilizes Handlebars syntax for control flow and data formatting.

Variable Interpolation & Transformers

Variables are interpolated using {{variableName}}. Format variables using transformers (Handlebars helpers): {{transformer variableName}} or {{transformer variableName arg1 arg2}}.

Basic examples:

Hello {{name}}!                        <!-- Simple variable -->
Hello {{capitalize name}}!             <!-- With transformer -->
Your balance is {{currency balance}}   <!-- Format as currency -->
Due {{relativeTime deadline}}         <!-- Relative time -->

Transformers allow you to format data directly within your templates without preprocessing. See the Built-in Transformers section below for available options.

View Detailed Examples

Transformers with arguments:

{{ellipsis text 50}}                  <!-- Truncate to 50 chars -->
{{formatDate date "YYYY-MM-DD"}}      <!-- Format date with pattern -->
{{formatDate date "MMMM DD, YYYY"}}  <!-- Full month name: December 25, 2023 -->
{{formatDate date "DDDD, MMM DD"}}    <!-- Day name: Monday, Dec 25 -->
{{replace text "old" "new"}}          <!-- Replace text -->
{{filter users "status" "active"}}    <!-- Filter by property equals value -->
{{reduce numbers 0 "sum"}}            <!-- Reduce with operation -->

Chaining transformers in expressions:

{{#each (sort (filter users "active") "name")}}
  {{increment @index}}. {{capitalize name}} - {{currency balance}}
{{/each}}

Loops

{{#each items}}
  {{increment @index}}. {{this}}
{{else}}
  No items found.
{{/each}}

Conditionals

{{#if isPremium}}
  Premium Content
{{else}}
  Standard Content
{{/if}}

Switch/Case

{{#switch role}}
  {{#case "admin"}} You are an Admin {{/case}}
  {{#case "user"}} You are a User {{/case}}
{{/switch}}

Context Switching

{{#with user}}
  Name: {{name}}
  Email: {{email}}
{{/with}}

Special Variables

  • @index - Current index in {{#each}} loops (0-based)
  • @key - Current key in {{#each}} loops over objects
  • @first - true on first iteration
  • @last - true on last iteration
  • @root - Access root context from nested contexts
  • this - Current context value in loops

Partials (Reusable Fragments)

Define reusable template fragments that can be included anywhere using {{> partialName}}. Perfect for headers, footers, user cards, or any repeated sections.

Basic usage:

const template = "{{> header}}\n{{content}}\n{{> footer}}";
const weaver = new PromptWeaver(template, {
  partials: {
    header: "# {{title}}\n---",
    footer: "---\nPlease respond in JSON format."
  }
});

// Or register programmatically:
weaver.setPartial("header", "# {{title}}\n---");

Partials inherit the parent context and can include other partials. They can be reused across multiple PromptWeaver instances, enabling DRY principles.

View Detailed Examples

Context Access & Nesting:

Partials inherit the parent context and can include other partials:

const template = "{{> pageLayout}}";
const weaver = new PromptWeaver(template, {
  partials: {
    pageLayout: `
{{> header}}
{{content}}
{{> footer}}
`,
    header: "# {{title}}\n---",
    footer: `---
Generated on {{formatDate date "YYYY-MM-DD"}}`
  }
});

const output = weaver.format({
  title: "My Page",
  content: "Main content here",
  date: new Date()
});

Real-World Example:

Compose complex prompts from reusable components:

const promptTemplate = `
{{> systemHeader}}
{{> taskSection}}
{{> outputFormat}}
`;

const weaver = new PromptWeaver(promptTemplate, {
  partials: {
    systemHeader: `You are {{role}}, an expert in {{domain}}.{{#if companyName}} Working for {{companyName}}.{{/if}}`,
    taskSection: `
## Task
{{taskDescription}}
{{#if requirements}}
## Requirements
{{#each requirements}}
- {{this}}
{{/each}}
{{/if}}
`,
    outputFormat: `{{#if jsonOutput}}Please respond in valid JSON format.{{else}}{{outputFormat}}{{/if}}`
  }
});

Reusability Example:

Partials can be reused across multiple PromptWeaver instances. Define a partial once and use it in different templates:

// Define a reusable partial template
const userCardPartial = `
## User Profile
- **Name**: {{name}}
- **Email**: {{email}}
- **Role**: {{role}}
{{#if isPremium}}⭐ Premium Member{{/if}}
---`;

// Use the same partial in multiple PromptWeaver instances
const emailTemplate = `{{> userCard}}\n\nYour account summary:\n{{summary}}`;
const reportTemplate = `{{> userCard}}\n\n## Activity Report\n{{report}}`;

const emailWeaver = new PromptWeaver(emailTemplate, {
  partials: { userCard: userCardPartial }
});

const reportWeaver = new PromptWeaver(reportTemplate, {
  partials: { userCard: userCardPartial }
});

// Both instances can use the same partial with different data
const emailOutput = emailWeaver.format({
  name: "Alice",
  email: "alice@example.com",
  role: "Developer",
  isPremium: true,
  summary: "You have 5 unread messages."
});

const reportOutput = reportWeaver.format({
  name: "Alice",
  email: "alice@example.com",
  role: "Developer",
  isPremium: true,
  report: "Last login: 2 hours ago"
});

Output:

## User Profile
- **Name**: Alice
- **Email**: alice@example.com
- **Role**: Developer
⭐ Premium Member
---

Your account summary:
You have 5 unread messages.

The same userCard partial is reused in both templates, demonstrating how partials enable DRY (Don't Repeat Yourself) principles across your prompt templates.


🛠️ Built-in Transformers

Prompt Weaver comes with a massive library of transformers to format data directly inside your prompt.

📝 String & Content

Expand String Transformers
Transformer Example Result
upper {{upper text}} HELLO
lower {{lower text}} hello
capitalize {{capitalize text}} Hello
ellipsis {{ellipsis text 10}} Hello w...
json {{json data}} {"a":1}
pluralize {{pluralize word}} apples

Also available: replace, replaceAll, regexReplace, trim, trimStart, trimEnd, slugify, kebabCase, camelCase, snakeCase, split, join, truncate, slice, substring, padStart, padEnd, singularize

📖 View all String Transformers →

📅 Date & Time

Expand Date Transformers
Transformer Example Result
formatDate {{formatDate date "YYYY-MM-DD"}} 2023-12-25
formatDate {{formatDate date "MMMM DD, YYYY"}} December 25, 2023
formatDate {{formatDate date "DDDD, MMM DD"}} Monday, Dec 25
relativeTime {{relativeTime date}} 2 hours ago
isToday {{isToday date}} true/false

Date format patterns: YYYY (4-digit year), YY (2-digit year), MMMM (full month), MMM (abbreviated month), MM (2-digit month), M (single digit month), DDDD (full day), DDD (abbreviated day), DD (2-digit day), D (single digit day), HH (hours), mm (minutes), ss (seconds)

Also available: formatTime, formatDateTime, isPast, isFuture, addDays, subtractDays, addHours, subtractHours, addMinutes, subtractMinutes, timestamp, unixTimestamp

📖 View all Date Transformers →

🔢 Math & Numbers

Expand Number Transformers
Transformer Example Result
currency {{currency price}} $1,234.56
percent {{percent val}} 12.34%
compact {{compact views}} 1.2M
add {{add 5 2}} 7

Also available: subtract, multiply, divide, increment, price, signedPercent, signedCurrency, integer, number

📖 View all Number Transformers →

📊 Collections (Arrays/Objects)

Expand Collection Transformers
Transformer Example Description
filter {{filter users "active"}} Filter array by property truthiness
filter {{filter users "status" "active"}} Filter array by property equals value
map {{map users "name"}} Extract property from objects
sort {{sort items "price"}} Sort array
reduce {{reduce numbers 0 "sum"}} Reduce array with operation (sum, multiply, max, min, concat)
first / last {{first items}} Get first/last item
pick {{pick user "name" "id"}} Pick specific object keys

Also available: find, findIndex, includes, reverse, nth, unique, groupBy, partition, chunk, flatten, arraySlice, length, reduce, get, has, keys, values, omit, merge, defaults, deepGet, isEmpty, isNotEmpty

📖 View all Collection Transformers →

🔀 Logic & Comparison

Expand Logic Transformers
{{#if (eq status "active")}} ... {{/if}}
{{#if (gt age 18)}} ... {{/if}}
{{coalesce value "fallback"}}
{{ifElse isPremium "Rich" "Poor"}}

Also available: ne (not equal), gte, lt, lte, and, or, default, exists, isDefined

📖 View all Logic & Comparison Transformers →

📚 Complete Reference: See TRANSFORMERS.md for the full list of all available transformers with detailed examples and usage.


✅ Validation & Type Safety

This is where Prompt Weaver shines. By integrating Standard Schema (Zod, Valibot, ArkType), you get runtime validation AND build-time TypeScript inference automatically.

The "Magic" of Inference

You don't need to manually define interfaces. Just pass a schema, and format() automatically validates and enforces type safety.

import { z } from 'zod';
import { PromptWeaver } from "@iqai/prompt-weaver";

// 1. Define Schema
const schema = z.object({
  username: z.string(),
  age: z.number().positive(),
  email: z.string().email().optional()
});

// 2. Pass schema to Weaver
const weaver = new PromptWeaver(template, { schema });

// 3. Type-Safe Formatting with Automatic Validation
// TypeScript will now ERROR if you miss 'username' or if 'age' is a string!
// format() automatically validates the data against the schema at runtime
const output = weaver.format({
  username: "Alice", 
  age: 30,
  // email is optional, so we can omit it safely
});

// ❌ This will give a TypeScript error AND throw at runtime
// weaver.format({}); // Missing required fields

Validation Methods

  • weaver.format(data): Automatically validates when a schema is provided, renders, and throws error if invalid. Type-safe!
  • weaver.formatAsync(data): Automatically validates asynchronously when a schema is provided (use for schemas with async refinements/transforms). Returns a Promise.
  • weaver.validateSchema(data): Just runs validation, returning a success/failure object (doesn't render).

Example:

import { SchemaValidationError } from "@iqai/prompt-weaver";

// format() automatically validates when schema is provided
try {
  const output = weaver.format({ username: "Alice", age: 30 });
  console.log("Rendered:", output);
} catch (error) {
  if (error instanceof SchemaValidationError) {
    console.error("Validation errors:", error.issues);
  }
}

// formatAsync() for schemas with async validation
const schema = z.object({
  email: z.string().email().refine(async (email) => {
    return await checkEmailExists(email);
  }),
  name: z.string(),
});

const weaver = new PromptWeaver(template, { schema });
const output = await weaver.formatAsync({ email: "alice@example.com", name: "Alice" });

// Or validate separately without rendering
const result = weaver.validateSchema({ username: "Alice", age: 30 });
if (result.success) {
  console.log("Valid data:", result.data); // ✅ TypeScript infers the output type
} else {
  console.error("Validation errors:", result.issues);
}

Async validation:

const result = await weaver.validateSchemaAsync({ username: "Alice", age: 30 });

Note

Prompt Weaver supports any Standard Schema-compatible validation library, including:

  • Zod (3.24+)
  • Valibot (1.0+)
  • ArkType (2.0+)
  • And other libraries that implement the Standard Schema specification

Template Validation

import { validateTemplate } from "@iqai/prompt-weaver";

const result = validateTemplate(templateSource);
if (!result.valid) {
  console.error("Template errors:", result.errors);
}

🧩 Advanced Usage

Composition

Merge multiple templates into one context. The compose method merges templates in the order they appear in the array, separated by two newlines (\n\n) by default.

const headerTemplate = "# {{title}}";
const bodyTemplate = "{{content}}";
const footerTemplate = "---\nGenerated on {{formatDate date}}";

// Templates are merged in order: header → body → footer
const composed = PromptWeaver.compose([headerTemplate, bodyTemplate, footerTemplate]);
const weaver = new PromptWeaver(composed);

const output = weaver.format({
  title: "My Document",
  content: "Main content here",
  date: new Date()
});

Output:

# My Document

Main content here

---
Generated on Dec 12, 2024

Custom Separator:

You can specify a custom separator between templates:

// Use a single newline instead of double newline
const composed = PromptWeaver.compose([headerTemplate, bodyTemplate], "\n");

// Use a custom separator
const composed = PromptWeaver.compose([headerTemplate, bodyTemplate], "\n---\n");

Direct Creation:

Or create a PromptWeaver instance directly from composed templates:

import { z } from 'zod';

const schema = z.object({
  title: z.string(),
  content: z.string(),
});

const weaver = PromptWeaver.composeAndCreate(
  [headerTemplate, bodyTemplate, footerTemplate],
  { schema }
);

Custom Transformers

Register your own logic globally or scoped to an instance.

Global Registration (Simple):

import { registerTransformer } from "@iqai/prompt-weaver";

// Simple transformer (no options)
registerTransformer("reverse", (str) => str.split("").reverse().join(""));
// Use: {{reverse text}}

// Transformer with options
registerTransformer("truncate", (value, maxLength) => {
  const str = String(value);
  const length = Number(maxLength) || 50;
  return str.length > length ? `${str.slice(0, length - 3)}...` : str;
});
// Use: {{truncate longText 100}}

Scoped Registry (Isolation):

import { TransformerRegistry } from "@iqai/prompt-weaver";

// Create isolated registry
const registry = TransformerRegistry.createScoped();
registry.registerTransformer("customHelper", (value, option1, option2) => {
  return `Custom: ${value} (${option1}, ${option2})`;
}, {
  description: "A custom helper with two options",
  version: "1.0.0"
});

// Only this instance uses this registry
const weaver = new PromptWeaver(template, { registry });

When to use which:

  • Global registration (registerTransformer()) - Use for shared transformers across your app
  • Scoped registry (TransformerRegistry.createScoped()) - Use for isolation, testing, or per-instance transformer sets

Core API Methods

PromptWeaver Class:

// Constructor
new PromptWeaver(templateSource, options?)

// Options
interface PromptWeaverOptions {
  registry?: TransformerRegistry; // Custom transformer registry (defaults to global)
  partials?: Record<string, string>; // Partial templates
  schema?: StandardSchemaV1; // Standard Schema validator (Zod, Valibot, ArkType, etc.)
  enableCache?: boolean; // Enable template compilation caching (default: true)
}

// Methods
weaver.format(data)                    // Render the template with data (automatically validates if schema provided)
weaver.formatAsync(data)               // Render asynchronously (use for schemas with async validation)
weaver.validateSchema(data)            // Validate data against schema (requires schema option)
weaver.extractVariables()              // Get required variables from template
weaver.setPartial(name, templateSource) // Register a partial template
weaver.getMetadata()                   // Get template metadata
PromptWeaver.compose(templateSources, separator?) // Compose multiple templates (static)

PromptBuilder Methods:

All methods return this for method chaining.

Content Methods:

  • .section(title?, content?) - Add a section (content can be string or function)
  • .text(text) - Add raw text content
  • .code(code, language?) - Add code block with optional language
  • .list(items, ordered?) - Add list (ordered or unordered)
  • .table(headers, rows) - Add markdown table
  • .heading(level, text) - Add heading (level 1-6)
  • .quote(text) - Add blockquote
  • .separator(char?) - Add separator line (default: "---")
  • .horizontalRule(char?) - Alias for separator
  • .json(data, indent?) - Format JSON data with indentation (default: 2 spaces)
  • .link(text, url) - Create markdown link
  • .image(alt, url, title?) - Create markdown image
  • .checkbox(text, checked?) - Add checkbox/task list item
  • .checkboxes(items) - Add multiple checkboxes (items can be strings or {text, checked} objects)

Control Flow Methods:

  • .conditional(condition, ifTrue, ifFalse?) - Add conditional content based on boolean
  • .loop(items, callback) - Add content by iterating over items

Utility Methods:

  • .build() - Build final prompt string
  • .toPromptWeaver(options?) - Convert to PromptWeaver instance for rendering
  • .clear() - Clear all content and start fresh

💡 Real-World Examples

🤖 Code Review Assistant

Generates a structured prompt for reviewing PRs, handling code blocks and arrays of criteria.

const codeFence = "```";
const codeReviewTemplate = `
You are an expert code reviewer specializing in {{language}}.

## Code to Review

${codeFence}{{language}}
{{code}}
${codeFence}

## Review Criteria

{{#each criteria}}
- {{this}}
{{/each}}

## Context

- Repository: {{repoName}}
- Pull Request: #{{prNumber}}
- Author: {{authorName}}
- Files Changed: {{filesChanged}}

Please provide a thorough code review focusing on:
1. Code quality and best practices
2. Potential bugs or security issues
3. Performance optimizations
4. Test coverage recommendations

{{#if includeExamples}}
## Example Review Format

Please structure your review as:
- **Critical Issues**: List any blocking issues
- **Suggestions**: Improvement recommendations
- **Questions**: Clarifications needed
{{/if}}
`;

const weaver = new PromptWeaver(codeReviewTemplate);
const reviewPrompt = weaver.format({
  language: "TypeScript",
  code: "function calculateTotal(items: Item[]) { return items.reduce((sum, item) => sum + item.price, 0); }",
  criteria: [
    "Type safety and error handling",
    "Performance and scalability",
    "Code readability and maintainability"
  ],
  repoName: "my-app",
  prNumber: 42,
  authorName: "John Doe",
  filesChanged: 3,
  includeExamples: true
});
📊 Data Analysis

Takes raw data numbers and dates, formats them readable, and adds warnings if outliers are detected.

const analysisTemplate = `
You are a data analyst with expertise in {{domain}}.

## Dataset Overview

- **Total Records**: {{integer totalRecords}}
- **Date Range**: {{formatDate startDate "YYYY-MM-DD"}} to {{formatDate endDate "YYYY-MM-DD"}}
- **Key Metrics**: {{#each metrics}}{{this}}{{#unless @last}}, {{/unless}}{{/each}}

## Data Summary

{{#if hasOutliers}}
⚠️ **Note**: This dataset contains {{outlierCount}} outliers that may need special handling.
{{/if}}

## Analysis Request

{{request}}

{{#if includeVisualizations}}
## Visualization Requirements

Please suggest appropriate visualizations for:
{{#each visualizationTypes}}
- {{this}}
{{/each}}
{{/if}}

## Expected Output Format

1. **Executive Summary**: High-level insights (2-3 sentences)
2. **Key Findings**: {{findingsCount}} main observations
3. **Recommendations**: Actionable next steps
4. **Data Quality Notes**: Any concerns or limitations
`;

const analysisWeaver = new PromptWeaver(analysisTemplate);
const analysisPrompt = analysisWeaver.format({
  domain: "e-commerce",
  totalRecords: 125000,
  startDate: new Date("2024-01-01"),
  endDate: new Date("2024-03-31"),
  metrics: ["Revenue", "Conversion Rate", "Customer Lifetime Value"],
  hasOutliers: true,
  outlierCount: 47,
  request: "Analyze sales trends and identify factors contributing to revenue growth in Q1 2024.",
  includeVisualizations: true,
  visualizationTypes: ["Time series", "Cohort analysis", "Funnel visualization"],
  findingsCount: 5
});
📞 Customer Support

Formats a customer ticket with history, deciding tone based on "Premium" status variables.

const supportTemplate = `
You are a customer support specialist for {{companyName}}.

## Customer Information

- **Name**: {{customerName}}
- **Account Type**: {{accountType}}
- **Member Since**: {{formatDate memberSince "MMMM YYYY"}}
{{#if isPremium}}
- ⭐ **Premium Member**
{{/if}}

## Issue Details

**Ticket ID**: {{ticketId}}
**Category**: {{category}}
**Priority**: {{upper priority}}
**Reported**: {{relativeTime reportedAt}}

**Description**:
{{issueDescription}}

{{#if previousTickets}}
## Previous Interactions

This customer has {{previousTickets.length}} previous {{pluralize "ticket" previousTickets.length}}:
{{#each previousTickets}}
- Ticket #{{ticketNumber}}: {{summary}} ({{status}})
{{/each}}
{{/if}}

{{#if orderHistory}}
## Recent Order History

{{#each orderHistory}}
- Order #{{orderNumber}}: {{productName}} - {{formatDate orderDate "MMM DD, YYYY"}} - {{capitalize status}}
{{/each}}
{{/if}}

## Response Guidelines

1. Acknowledge the customer's concern with empathy
2. Provide a clear, step-by-step solution
3. {{#if isPremium}}Offer priority escalation if needed{{else}}Suggest self-service options where appropriate{{/if}}
4. Set clear expectations for resolution timeline
5. End with a warm, helpful closing

Please draft a professional, helpful response that resolves their issue.
`;

const supportWeaver = new PromptWeaver(supportTemplate);
const supportPrompt = supportWeaver.format({
  companyName: "TechCorp",
  customerName: "Sarah Johnson",
  accountType: "Business",
  memberSince: new Date("2023-06-15"),
  isPremium: true,
  ticketId: "TC-2024-0847",
  category: "Billing",
  priority: "high",
  reportedAt: new Date(Date.now() - 2 * 60 * 60 * 1000), // 2 hours ago
  issueDescription: "I was charged twice for my subscription renewal. The charge appeared on both my credit card and PayPal account.",
  previousTickets: [
    { ticketNumber: "TC-2024-0721", summary: "Feature request", status: "resolved" }
  ],
  orderHistory: [
    { orderNumber: "ORD-1234", productName: "Pro Plan", orderDate: new Date("2024-03-01"), status: "completed" }
  ]
});
🏗️ Programmatic Prompt Building

Build prompts dynamically based on runtime conditions:

import { PromptBuilder } from "@iqai/prompt-weaver";

const builder = new PromptBuilder()
  .heading(1, "AI Code Assistant")
  .section("Role", "You are an expert software engineer specializing in {{language}}.")
  .section("Task", "{{taskDescription}}");

// Conditionally add context section
if (includeContext) {
  builder
    .heading(2, "Context")
    .text("Current codebase:")
    .code(existingCode, "typescript")
    .text(`\nRelated files: ${relatedFiles.join(", ")}`);
}

// Build requirements section
builder.section("Requirements", () => {
  const reqBuilder = new PromptBuilder().list(requirements);
  if (hasConstraints) {
    reqBuilder.heading(3, "Constraints").list(constraints);
  }
  return reqBuilder.build();
});

builder.section("Output Format", "Please provide:\n1. Complete code solution\n2. Brief explanation\n3. Testing recommendations");

// Convert to PromptWeaver and render with data
const weaver = builder.toPromptWeaver();
const output = weaver.format({
  language: "TypeScript",
  taskDescription: "Create a function to calculate Fibonacci numbers",
  // ... other data
});

Key Benefits:

  • Build prompts programmatically with full control flow
  • Use conditionals, loops, and dynamic content
  • Convert to PromptWeaver for template rendering with variables
  • Validate data against the built template

⚠️ Error Handling

Prompt Weaver provides specific error classes for debugging with enhanced error messages.

  • SchemaValidationError: Thrown when data doesn't match your Zod/Valibot schema. Includes detailed validation issues.
  • TemplateCompilationError: Thrown when your Handlebars syntax is broken (e.g., unclosed tags). Includes surrounding code context, line numbers, and helpful suggestions.

Example:

import { SchemaValidationError, TemplateCompilationError } from "@iqai/prompt-weaver";
import { z } from 'zod';

const schema = z.object({
  name: z.string(),
  age: z.number(),
});

try {
  const weaver = new PromptWeaver(template, { schema });
  // format() automatically validates when schema is provided
  const output = weaver.format({ name: "Alice", age: 30 });
} catch (error) {
  if (error instanceof SchemaValidationError) {
    console.error("Validation failed:", error.issues);
    console.error(error.getFormattedMessage());
    // Detailed validation error messages from your schema library
  } else if (error instanceof TemplateCompilationError) {
    console.error(error.getFormattedMessage());
    // Enhanced error message includes:
    // - Line and column numbers
    // - Surrounding code context
    // - Helpful suggestions for fixing common errors
  }
}

Built with 💙 by IQ AI Team

About

A powerful, extensible template engine for building prompts

Topics

Resources

License

Code of conduct

Contributing

Security policy

Stars

Watchers

Forks

Packages

No packages published

Contributors 3

  •  
  •  
  •