# Schema Guide

Human-readable guide to PromptPack entities and their properties. For the auto-generated technical reference, see [Schema Reference](./schema-reference).

## Root Properties

The root object of every PromptPack file. Required fields are `id`, `name`, `version`, `template_engine`, and `prompts`.

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `$schema` | string | No | JSON Schema reference for validation and IDE support. Default: `https://promptpack.org/schema/v1/promptpack.schema.json` |
| `id` | string | **Yes** | Unique identifier for the pack. Lowercase with hyphens only. Pattern: `^[a-z][a-z0-9-]*$` (1--100 chars). |
| `name` | string | **Yes** | Human-readable display name for the pack (1--200 chars). |
| `version` | string | **Yes** | Pack version following [Semantic Versioning 2.0.0](https://semver.org/). Optional `v` prefix. Examples: `"1.0.0"`, `"v2.1.3"`. |
| `description` | string | No | Detailed description of the pack's purpose. Supports markdown (max 5000 chars). |
| `template_engine` | [TemplateEngine](#template-engine) | **Yes** | Template engine configuration shared across all prompts. |
| `prompts` | object&lt;string, [Prompt](#prompt)&gt; | **Yes** | Map of task type keys to prompt definitions. Must contain at least one entry. |
| `fragments` | object&lt;string, string&gt; | No | Shared template fragments. Keys are fragment names, values are fragment content strings. |
| `tools` | object&lt;string, [Tool](#tool)&gt; | No | Tool definitions that prompts can reference. Keys are tool names, values are tool specs. |
| `metadata` | [Metadata](#metadata) | No | Optional pack-level metadata for categorization and discovery. |
| `compilation` | [Compilation](#compilation) | No | Information about when and how the pack was compiled. Generated by `packc`. |

:::note[Collections are keyed maps, not arrays]
`prompts`, `fragments`, and `tools` are all **objects** (keyed maps), not arrays. Each key serves as the identifier for the entry. For example, `prompts` maps task type strings like `"support"` or `"billing"` to their Prompt definitions.
:::

### Minimal Example

```json
{
  "$schema": "https://promptpack.org/schema/v1/promptpack.schema.json",
  "id": "my-pack",
  "name": "My Pack",
  "version": "1.0.0",
  "template_engine": {
    "version": "v1",
    "syntax": "{{variable}}"
  },
  "prompts": {
    "greeting": {
      "id": "greeting",
      "name": "Greeter",
      "version": "1.0.0",
      "system_template": "You are a friendly assistant for {{company}}."
    }
  }
}
```

---

## Template Engine

Configuration for how variables are substituted and fragments are resolved across all prompts.

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `version` | string | **Yes** | Template engine version (e.g., `"v1"`). |
| `syntax` | string | **Yes** | Variable substitution syntax pattern (e.g., `"{{variable}}"`). |
| `features` | string[] | No | Supported template features. Allowed values: `"basic_substitution"`, `"fragments"`, `"conditionals"`, `"loops"`, `"filters"`. |

```json
"template_engine": {
  "version": "v1",
  "syntax": "{{variable}}",
  "features": ["basic_substitution", "fragments"]
}
```

---

## Prompt

A single prompt configuration within a pack. Each prompt represents a specific task type (e.g., `"support"`, `"sales"`) with its own template, variables, tools, and validation rules. Prompts can evolve independently with their own version numbers.

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `id` | string | **Yes** | Unique identifier, typically matching the map key. Pattern: `^[a-z][a-z0-9_-]*$`. |
| `name` | string | **Yes** | Human-readable name. |
| `version` | string | **Yes** | Prompt version following Semantic Versioning, independent from the pack version. |
| `system_template` | string | **Yes** | The system prompt template. Use template syntax (e.g., `{{variable}}`) for variable substitution. |
| `description` | string | No | Detailed description of the prompt's purpose and behavior. |
| `variables` | [Variable](#variable)[] | No | Variable definitions for template placeholders. |
| `tools` | string[] | No | List of tool names this prompt can use. Tools must be defined in the pack-level `tools` map. |
| `tool_policy` | [ToolPolicy](#tool-policy) | No | Policy governing how tools can be used. |
| `pipeline` | [PipelineConfig](#pipeline-config) | No | Pipeline configuration defining processing stages and middleware. |
| `parameters` | [Parameters](#parameters) | No | LLM generation parameters (temperature, max_tokens, etc.). |
| `validators` | [Validator](#validator)[] | No | Validation rules (guardrails) applied to LLM responses. |
| `tested_models` | [TestedModel](#tested-model)[] | No | Model testing results documenting performance across different models. |
| `model_overrides` | object&lt;string, [ModelOverride](#model-override)&gt; | No | Model-specific template modifications. Keys are model names (e.g., `"claude-3-opus"`, `"gpt-4"`). |
| `media` | [MediaConfig](#media-config) | No | Multimodal content configuration. Defines supported media types and constraints. *(v1.1+)* |

```json
"prompts": {
  "support": {
    "id": "support",
    "name": "Support Bot",
    "version": "1.0.0",
    "system_template": "You are a {{role}} assistant for {{company}}.\n\nHelp resolve their issue.",
    "variables": [
      { "name": "role", "type": "string", "required": true, "example": "support agent" },
      { "name": "company", "type": "string", "required": true, "default": "TechCo" }
    ],
    "tools": ["lookup_order", "create_ticket"],
    "parameters": { "temperature": 0.7, "max_tokens": 1500 }
  }
}
```

---

## Variable

A template variable definition with type information and validation rules.

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `name` | string | **Yes** | Variable name used in templates (e.g., `{{name}}`). Pattern: `^[a-zA-Z_][a-zA-Z0-9_]*$`. |
| `type` | string | **Yes** | Data type. One of: `"string"`, `"number"`, `"boolean"`, `"object"`, `"array"`. |
| `required` | boolean | **Yes** | Whether this variable must be provided at runtime. |
| `default` | any | No | Default value when the variable is not provided. |
| `description` | string | No | Human-readable description of the variable's purpose. |
| `example` | any | No | Example value showing expected format and content. |
| `validation` | [Validation](#validation) | No | Validation rules applied to the variable value at runtime. |

### Validation

Rules applied to variable values at runtime.

| Field | Type | Description |
|-------|------|-------------|
| `pattern` | string | Regular expression pattern (for string types). |
| `min_length` | integer | Minimum string length. Minimum value: 0. |
| `max_length` | integer | Maximum string length. Minimum value: 1. |
| `minimum` | number | Minimum numeric value (for number types). |
| `maximum` | number | Maximum numeric value (for number types). |
| `enum` | any[] | List of allowed values. |

```json
{
  "name": "priority",
  "type": "string",
  "required": true,
  "description": "Support ticket priority level",
  "validation": {
    "enum": ["low", "medium", "high", "urgent"]
  }
}
```

---

## Tool

A tool definition following the function calling convention. Tools enable the LLM to call external functions. Tools are defined at the pack level and referenced by name in each prompt's `tools` array.

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `name` | string | **Yes** | Tool name. Pattern: `^[a-zA-Z_][a-zA-Z0-9_]*$`. |
| `description` | string | **Yes** | What the tool does. The LLM uses this to decide when to call it. |
| `parameters` | object | No | JSON Schema object defining the tool's input parameters (see below). |

### Tool Parameters (JSON Schema Format)

Tool parameters use standard JSON Schema format. The `parameters` object must have `type: "object"` with a `properties` map and an optional `required` array.

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `type` | string | **Yes** | Must be `"object"`. |
| `properties` | object | **Yes** | Map of parameter names to their JSON Schema definitions. |
| `required` | string[] | No | List of required parameter names. |

```json
"tools": {
  "create_ticket": {
    "name": "create_ticket",
    "description": "Create a support ticket with title, description, and priority",
    "parameters": {
      "type": "object",
      "properties": {
        "title": {
          "type": "string",
          "description": "Ticket title"
        },
        "priority": {
          "type": "string",
          "enum": ["low", "medium", "high", "urgent"]
        }
      },
      "required": ["title"]
    }
  }
}
```

---

## Tool Policy

Governance policy for tool usage. Controls when and how tools can be called by the LLM.

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `tool_choice` | string | No | `"auto"` (LLM decides), `"required"` (must use tools), or `"none"` (tools disabled). Default: `"auto"`. |
| `max_rounds` | integer | No | Maximum number of LLM-tool-LLM cycles per turn. Minimum: 1. Default: 5. |
| `max_tool_calls_per_turn` | integer | No | Maximum tool calls allowed in a single turn. Minimum: 1. Default: 10. |
| `blocklist` | string[] | No | Tool names that are not allowed for this prompt (overrides the `tools` list). |

---

## Parameters

LLM generation parameters controlling the model's behavior and output characteristics.

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `temperature` | number | No | Sampling temperature (0--2). Higher values increase randomness. |
| `max_tokens` | integer | No | Maximum number of tokens to generate. Minimum: 1. |
| `top_p` | number | No | Nucleus sampling parameter (0--1). Alternative to temperature. |
| `top_k` | integer or null | No | Top-k sampling. `null` means no limit. Minimum: 1. |
| `frequency_penalty` | number | No | Penalty for token frequency (-2 to 2). Positive values reduce repetition. |
| `presence_penalty` | number | No | Penalty for token presence (-2 to 2). Positive values encourage new topics. |

```json
"parameters": {
  "temperature": 0.7,
  "max_tokens": 1500,
  "top_p": 0.9
}
```

---

## Validator

A validation rule (guardrail) applied to LLM responses.

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `type` | string | **Yes** | Validation type. One of: `"banned_words"`, `"max_length"`, `"min_length"`, `"regex_match"`, `"json_schema"`, `"sentiment"`, `"toxicity"`, `"pii_detection"`, `"custom"`. |
| `enabled` | boolean | **Yes** | Whether this validator is active. |
| `fail_on_violation` | boolean | No | If true, violations cause an error. Default: false. |
| `params` | object | No | Validator-specific parameters (e.g., word lists, character limits). |

```json
"validators": [
  {
    "type": "banned_words",
    "enabled": true,
    "fail_on_violation": true,
    "params": {
      "words": ["impossible", "can't help"]
    }
  },
  {
    "type": "pii_detection",
    "enabled": true,
    "fail_on_violation": true
  }
]
```

---

## Tested Model

Documents which models have been tested with a prompt and their performance metrics.

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `provider` | string | **Yes** | LLM provider name (e.g., `"openai"`, `"anthropic"`). |
| `model` | string | **Yes** | Specific model identifier (e.g., `"gpt-4"`, `"claude-3-opus"`). |
| `date` | string | **Yes** | Date tested in `YYYY-MM-DD` format. |
| `success_rate` | number | No | Success rate from test runs (0--1). |
| `avg_tokens` | number | No | Average tokens used per response. |
| `avg_cost` | number | No | Average cost per execution in USD. |
| `avg_latency_ms` | number | No | Average response latency in milliseconds. |
| `notes` | string | No | Additional observations about model performance. |

---

## Model Override

Model-specific template modifications. Allows customizing prompts for specific models without changing the base template.

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `system_template_prefix` | string | No | Text prepended to the system template for this model. |
| `system_template_suffix` | string | No | Text appended to the system template for this model. |
| `system_template` | string | No | Complete replacement system template (overrides the base template entirely). |
| `parameters` | [Parameters](#parameters) | No | Model-specific parameter overrides. |

```json
"model_overrides": {
  "claude-3-opus": {
    "system_template_prefix": "<thinking>\n",
    "parameters": { "temperature": 0.5 }
  }
}
```

---

## Pipeline Config

Pipeline configuration defining processing stages and middleware.

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `stages` | string[] | **Yes** | Ordered list of pipeline stages (e.g., `["template", "provider", "validator"]`). |
| `middleware` | [MiddlewareConfig](#middleware-config)[] | No | Middleware components applied in order. |

### Middleware Config

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `type` | string | **Yes** | Middleware type identifier (e.g., `"template"`, `"provider"`, `"validator"`). |
| `config` | object | No | Type-specific configuration. |

---

## Metadata

Optional pack-level metadata for categorization and discovery.

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `domain` | string | No | Domain or category (e.g., `"customer-service"`, `"healthcare"`). |
| `language` | string | No | Primary language code (ISO 639-1, e.g., `"en"`). Pattern: `^[a-z]{2}$`. |
| `tags` | string[] | No | Tags for categorization and discovery. |
| `cost_estimate` | object | No | Cost estimation with `min_cost_usd`, `max_cost_usd`, and `avg_cost_usd`. |

---

## Compilation

Compiler-generated information about when and how the pack was built.

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `compiled_with` | string | **Yes** | Version of the packc compiler (e.g., `"packc-v0.1.0"`). |
| `created_at` | string | **Yes** | ISO 8601 timestamp when the pack was compiled. |
| `schema` | string | **Yes** | Pack format schema version (e.g., `"v1"`). |
| `source` | string | No | Source configuration file path. |

---

## Fragments

Fragments are shared, reusable template text blocks defined at the pack level. They are simple string values keyed by name.

```json
"fragments": {
  "customer_context": "Customer: {{customer_name}}\nAccount Type: {{account_type}}",
  "greeting": "Hello! How can I help you today?",
  "escalation_notice": "I'm going to connect you with a specialist."
}
```

Prompts reference fragments in their `system_template` using template syntax: `{{fragments.customer_context}}`.

---

## Multimodal Support *(v1.1+)*

PromptPack v1.1 adds multimodal content support through media configuration on individual prompts.

### Media Config

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `enabled` | boolean | **Yes** | Whether multimodal content is enabled for this prompt. |
| `supported_types` | string[] | No | Supported media types (e.g., `"image"`, `"audio"`, `"video"`, `"document"`). Custom types allowed. |
| `image` | [ImageConfig](#image-config) | No | Image-specific constraints. |
| `audio` | [AudioConfig](#audio-config) | No | Audio-specific constraints. |
| `video` | [VideoConfig](#video-config) | No | Video-specific constraints. |
| `document` | [DocumentConfig](#document-config) | No | Document-specific constraints. |
| `examples` | [MultimodalExample](#multimodal-example)[] | No | Example multimodal messages. |

### Image Config

| Field | Type | Description |
|-------|------|-------------|
| `max_size_mb` | integer | Maximum file size in MB. |
| `allowed_formats` | string[] | Allowed formats: `"jpeg"`, `"jpg"`, `"png"`, `"webp"`, `"gif"`, `"bmp"`. |
| `default_detail` | string | Detail level: `"low"`, `"high"`, or `"auto"` (default: `"auto"`). |
| `require_caption` | boolean | Whether captions are required (default: false). |
| `max_images_per_msg` | integer | Maximum images per message. |

### Audio Config

| Field | Type | Description |
|-------|------|-------------|
| `max_size_mb` | integer | Maximum file size in MB. |
| `allowed_formats` | string[] | List of allowed audio format strings (open list, e.g. `"mp3"`, `"wav"`, `"ogg"`, `"webm"`). |
| `max_duration_sec` | integer | Maximum duration in seconds. |
| `require_metadata` | boolean | Whether metadata is required (default: false). |

### Video Config

| Field | Type | Description |
|-------|------|-------------|
| `max_size_mb` | integer | Maximum file size in MB. |
| `allowed_formats` | string[] | Allowed formats: `"mp4"`, `"webm"`, `"mov"`, `"avi"`, `"mkv"`. |
| `max_duration_sec` | integer | Maximum duration in seconds. |
| `require_metadata` | boolean | Whether metadata is required (default: false). |

### Document Config

| Field | Type | Description |
|-------|------|-------------|
| `max_size_mb` | integer | Maximum file size in MB. |
| `allowed_formats` | string[] | Allowed formats (e.g., `"pdf"`, `"docx"`, `"csv"`). |
| `max_pages` | integer | Maximum pages/sheets. |
| `require_metadata` | boolean | Whether metadata is required (default: false). |
| `extraction_mode` | string | Content extraction: `"text"`, `"structured"`, or `"raw"` (default: `"text"`). |

### Generic Media Type Config

For custom media types not covered by the specific configs above.

| Field | Type | Description |
|-------|------|-------------|
| `max_size_mb` | integer | Maximum file size in MB. |
| `allowed_formats` | string[] | Allowed file formats/extensions. |
| `require_metadata` | boolean | Whether metadata is required (default: false). |
| `validation_params` | object | Custom validation parameters specific to this media type. |

### Multimodal Example

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `name` | string | **Yes** | Name identifying this example. |
| `description` | string | No | What this example demonstrates. |
| `role` | string | **Yes** | Message role: `"user"`, `"assistant"`, or `"system"`. |
| `parts` | [ContentPart](#content-part)[] | **Yes** | Message content parts (text and/or media). |

### Content Part

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `type` | string | **Yes** | Part type (e.g., `"text"`, `"image"`, `"audio"`). |
| `text` | string | No | Text content (when type is `"text"`). |
| `media` | [MediaReference](#media-reference) | No | Media reference (when type is a media type). |

### Media Reference

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `mime_type` | string | **Yes** | MIME type (e.g., `"image/jpeg"`, `"audio/mp3"`). |
| `file_path` | string | No | Path to media file. |
| `url` | string | No | URL to media file. |
| `base64` | string | No | Base64-encoded media data. |
| `detail` | string | No | Detail level for images: `"low"`, `"high"`, or `"auto"`. |
| `caption` | string | No | Caption or description for the media. |

```json
"media": {
  "enabled": true,
  "supported_types": ["image"],
  "image": {
    "max_size_mb": 20,
    "allowed_formats": ["jpeg", "png", "webp"],
    "default_detail": "high",
    "max_images_per_msg": 5
  }
}
```

---

## Data Types

### Supported Variable Types

- **string** -- Text data
- **number** -- Numeric values (integers and floats)
- **boolean** -- True/false values
- **array** -- Ordered lists of values
- **object** -- Key-value maps

### Template Variables

Variables in templates use the syntax defined in `template_engine.syntax`. With the default `{{variable}}` syntax:

```
{{variable_name}}
```

Fragments are referenced similarly:

```
{{fragments.fragment_name}}
```
