Configuration File Reference¶
This guide provides a comprehensive reference for all the configuration files used in VIBE. Understanding these files is key to building, customizing, and managing both the system and individual templates.
Table of Contents¶
- System Configuration (
config.yml)- Core application and web server settings.
- Template Configuration (
config.yml)- Defines the questions, logic, and metadata for a single interview template.
- Component Configuration (
component.yml)- Defines the interface and logic for a reusable component.
System Configuration (config.yml)¶
This file is located in the root directory of the VIBE application. It controls the overall behavior of the system, including server settings, session management, and paths to template/component source directories.
| Key | Type | Required | Description |
|---|---|---|---|
secret_key |
string | Yes | A long, random string used for cryptographic signing, such as session cookies. |
session_storage_key |
string | Yes | A long, random string used to sign saved interview states (.vibestate files). Auto-generated if not present. |
template_sources |
mapping | Yes | Maps a unique template_id to its source directory path. |
component_sources |
list | No | A list of paths to directories containing reusable components. |
llm_endpoints |
mapping | No | Assistant extension: Central registry of available Large Language Models. |
assistant_logging_enabled |
boolean | No | Assistant extension: Enables writing assistant request/response/SSE logs to the data directory. Defaults to true. Set to false to disable assistant logging. |
embedding_providers |
mapping | No | Review extension: Defines embedding models for similarity search. See Embedding Providers. |
rerank_providers |
mapping | No | Review extension: Defines reranking models for search refinement. See Rerank Providers. |
review_backends |
mapping | No | Review extension: Configures OCR and other document processing backends. See Review Backends. |
dev_settings |
mapping | No | Development-time settings used when running in debug mode without a PASETO token. Contains user info, session_context data, and grants. See Development Settings and Session Context for details. |
template_validation |
boolean | No | If false, disables the initial validation run on startup. Defaults to true. |
session_file_system_dir |
string | No | Path to the directory for storing session files. Defaults to ./.flask_session. |
mount_path |
string | No | Optional URL path prefix where the application should be mounted. When set, all routes and static files are served under this prefix. For example, setting mount_path: "vibe" mounts the app at /vibe/ so the main page is at http://localhost:5001/vibe/. Leave empty (default) to mount at the root path. |
locale |
string | No | Sets the default locale for the entire application (e.g., 'en', 'sv'). Affects translations, date/number/currency formatting. Can be overridden by template-level config. |
# Example system config.yml
# --- Security ---
secret_key: a-very-long-and-random-string-for-sessions
session_storage_key: another-super-secret-key-for-state-files
# --- Application Mounting (optional) ---
# Leave empty or omit to mount at root path
# Set to a path like "vibe" to mount at http://localhost:5001/vibe/
mount_path: ""
# --- Template and Component Paths ---
template_sources:
nda_template:
path: ./templates/nda
service_agreement:
path: ./templates/sa
component_sources:
- ./components/shared
- ./components/legal_clauses
# --- LLM Configuration (for Administrators) ---
llm_endpoints:
default:
provider: vibe.llm_providers.openai.OpenAIProvider
config:
api_key: "{{ env('OPENAI_API_KEY') }}"
model: gpt-4-turbo-preview
# --- Assistant Logging (optional) ---
assistant_logging_enabled: true
# --- Embedding and Rerank Providers (for VIBE Review) ---
embedding_providers:
local:
provider: vibe.embedding_providers.local.LocalEmbeddingProvider
config:
model: multilingual-large
rerank_providers:
local:
provider: vibe.rerank_providers.local.LocalRerankProvider
config: {}
# --- Review Backends (for VIBE Review scanned PDF support) ---
review_backends:
ocr:
backend: tesseract_docker
text_layer_min_chars: 10
tesseract:
oem: 1
psm: 4
user_words: null
pdf:
backend: pdfplumber
docx:
backend: libreoffice_docker
# --- Development Settings ---
# Used when running in debug mode without a PASETO token.
# In production, this data comes from the authentication system.
dev_settings:
user:
name: Development User
email: dev@example.com
session_context:
organization:
name: Development Corp
org_number: "123456-7890"
settings:
default_currency: USD
grants: []
# --- Internationalization ---
locale: en
LLM Endpoint Configuration (llm_endpoints)¶
This section is for System Administrators and applies to the Assistant extension. It provides a central, secure registry of Large Language Model (LLM) services that can be used by AI Drafting Assistants in templates. By defining endpoints here, you control which models are available, manage API keys securely, and can enforce cost and governance policies.
Template authors can then select from these predefined endpoints by referencing their key (e.g., claude-opus) in their template's assistants configuration.
Each entry in the llm_endpoints mapping consists of a unique alias and two keys: provider and config.
- Alias (e.g.,
default,claude-opus): A unique, friendly name for the endpoint. Template authors will use this name. It is recommended to always have an endpoint nameddefault. provider: The full Python path to the VIBE LLM Provider class that handles communication with the specific AI service.config: A dictionary of parameters passed directly to the provider. This is where you set API keys, model names, and other service-specific options.
Available Providers:
vibe.llm_providers.openai.OpenAIProvider: For OpenAI models (e.g., GPT-5) and any OpenAI-compatible API endpoint.vibe.llm_providers.anthropic.AnthropicProvider: For Anthropic's Claude models.vibe.llm_providers.gemini.GeminiProvider: For Google's Gemini models.vibe.llm_providers.mistral.MistralProvider: For Mistral AI's models.vibe.llm_providers.ollama. OllamaProvider: For connecting to a local Ollama instance.vibe.llm_providers.mock.ConfigurableMockProvider: A simple provider for development and testing that returns a fixed response.
Security Note: API keys should always be loaded from environment variables using the env() function for security, as shown in the example below.
# Detailed llm_endpoints example in system config.yml
llm_endpoints:
# The default model used when a template author does not specify one.
default:
provider: vibe.llm_providers.openai.OpenAIProvider
config:
# Securely load the API key from an environment variable.
api_key: "{{ env('OPENAI_API_KEY') }}"
model: gpt-4-turbo-preview
# An alias for a more powerful, potentially more expensive model.
claude-opus:
provider: vibe.llm_providers.anthropic.AnthropicProvider
config:
api_key: "{{ env('ANTHROPIC_CLAUDE_API_KEY') }}"
model: claude-3-opus-20240229
# An endpoint for a local model served via Ollama.
local-llama:
provider: vibe.llm_providers.ollama.OllamaProvider
config:
# No API key needed for local Ollama.
model: llama3
base_url: http://localhost:11434
# The mock provider for development and testing.
mock_drafter:
provider: vibe.llm_providers.mock.MockProvider
config: {}
Configurable Mock Provider (vibe.llm_providers.mock.ConfigurableMockProvider)¶
Use this provider when you need a deterministic assistant workflow (for demos, documentation, or local QA). Each entry in config.responses represents one AssistantMessage. Responds are expressed as a list:
nullmeans the assistant emits an empty message (no tool calls).- A nested list describes the tool calls for that turn. Each tool can be defined as either:
- A scalar tool name (
- finalize) - A mapping from tool name to arguments (
- update_chat: {content: ...}) - The provider auto-generates tool-call IDs and follows the order of the list, matching the behavior of
COMPLETE_WORKFLOW_RESPONSES(seetests/assistant/integration/browser.pyfor the equivalent Python fixture).
You can also control streaming behavior:
chunk_size(characters) splits tool arguments/text when streaming tool calls.chunk_delay(milliseconds) pauses between each chunk whenchunk_size > 0.
llm_endpoints:
demo_configurable_mock:
label: "Demo provider"
provider: vibe.llm_providers.mock.ConfigurableMockProvider
config:
chunk_size: 5
chunk_delay: 80
responses:
- null
- - update_chat:
content: Draft introduction placeholder
- - finalize
- null
- - insert_blocks:
position:
at: end
blocks:
- id: intro
content: |
# Project Goals
This document will outline the goals and objectives for the project.
reason: Creating initial project structure
OpenAI Provider (vibe.llm_providers.openai.OpenAIProvider)¶
Use this provider for OpenAI-hosted models (gpt-5-*, gpt-4.1*, o4-*, gpt-oss-*) and other services that expose the OpenAI Responses API. Set the following keys inside the endpoint’s config block:
- api_key (required) – API credential; load it via
{{ env('OPENAI_API_KEY') }}or a similar environment binding. - model (required) – Model identifier. The provider automatically selects the Responses API path for the latest OpenAI families listed above.
- base_url – Override the API host for OpenAI-compatible vendors (e.g. Berget). Defaults to
https://api.openai.com/v1. - timeout – Request timeout in seconds (default
60). - tools – Enable tool calling and streaming tool arguments (default
true). Setfalsefor plain text interactions. - remove_empty_content – Controls handling of empty content in assistant messages with tool calls. When
true(default), omits thecontentfield entirely for OpenAI/Mistral compatibility. Whenfalse, includescontent: nullfor third-party providers that require the field to be present. Only relevant when using tools. - max_tokens – Upper bound for generated tokens (
max_output_tokenswhen using Responses models). - temperature – Sampling temperature. Forwarded only when tools are disabled; omit it for Responses-first models where
reasoning.effortis preferred. - reasoning_effort – Sets
reasoning.effort(low,medium, orhigh) on Responses requests. Defaults tomediumwhen omitted. - text_verbosity – Sets
text.verbosity(low,medium, orhigh) for Responses models. Defaults tomediumand must match an allowed value. - playback_from_file / playback_session_id – Optional debug settings that replay logged provider output during local troubleshooting.
reasoning_effort and text_verbosity are ignored for legacy chat-completions models; they only apply when the provider opts into the Responses API pathway.
Example: Third-party provider requiring content: null
llm_endpoints:
third_party_provider:
provider: vibe.llm_providers.openai.OpenAIProvider
config:
api_key: "{{ env('THIRD_PARTY_API_KEY') }}"
model: third-party-model-name
base_url: https://api.thirdparty.com/v1
remove_empty_content: false # This provider requires content: null in tool call messages
Embedding Provider Configuration (embedding_providers)¶
This section defines embedding models used for similarity search in VIBE Review. Embeddings convert text into vector representations for similarity matching.
Each entry in the embedding_providers mapping consists of a unique alias and two keys: provider and config.
- Alias (e.g.,
local,berget): A unique name for the provider. Review templates reference this in theirreview.embeddingsetting. provider: The full Python path to the embedding provider class.config: A dictionary of parameters passed to the provider.
Available Providers:
vibe.embedding_providers.local.LocalEmbeddingProvider: Local inference using fastembed (multilingual by default). No API key required.vibe.embedding_providers.berget.BergetEmbeddingProvider: Cloud API using intfloat/multilingual-e5-large model.vibe.embedding_providers.mock.ConfigurableMockEmbeddingProvider: For testing.
# Embedding providers in system config.yml
embedding_providers:
# Local inference (default) - no API key needed
local:
provider: vibe.embedding_providers.local.LocalEmbeddingProvider
config:
model: multilingual-large # or: e5-large, multilingual-small
# Cloud API
berget:
provider: vibe.embedding_providers.berget.BergetEmbeddingProvider
config:
api_key: "{{ env('BERGET_API_KEY') }}"
Rerank Provider Configuration (rerank_providers)¶
This section defines reranking models used to refine search results in VIBE Review. Rerankers use cross-encoder models to score document-query relevance more accurately than embeddings alone.
Each entry in the rerank_providers mapping consists of a unique alias and two keys: provider and config.
- Alias (e.g.,
local,berget): A unique name for the provider. Review templates reference this in theirreview.rerankingsetting. provider: The full Python path to the rerank provider class.config: A dictionary of parameters passed to the provider.
Available Providers:
vibe.rerank_providers.local.LocalRerankProvider: Local inference using sentence-transformers cross-encoder. No API key required.vibe.rerank_providers.berget.BergetRerankProvider: Cloud API reranking service.vibe.rerank_providers.mock.ConfigurableMockRerankProvider: For testing.
# Rerank providers in system config.yml
rerank_providers:
# Local inference (default) - no API key needed
local:
provider: vibe.rerank_providers.local.LocalRerankProvider
config:
model: cross-encoder/ms-marco-MiniLM-L-6-v2
# Cloud API
berget:
provider: vibe.rerank_providers.berget.BergetRerankProvider
config:
api_key: "{{ env('BERGET_API_KEY') }}"
Using Providers in Review Templates¶
Extension note: This section applies only when the Review extension is enabled.
Review templates reference these providers by their alias in the review configuration block:
# In a review template's config.yml
interview_mode: review
review:
embedding: local # Key from embedding_providers
reranking: berget # Key from rerank_providers
evaluation: claude # Key from llm_endpoints
If not specified, templates default to local for embedding and reranking.
Review Backends Configuration (review_backends)¶
Extension note: Review backends are only used by the Review extension.
The review_backends section configures document processing backends for VIBE Review. This includes OCR (Optical Character Recognition) for processing scanned PDFs and DOCX conversion for viewing Word documents.
Structure:
| Key | Type | Default | Description |
|---|---|---|---|
ocr |
mapping | {} |
OCR backend configuration for scanned PDF processing. |
ocr.backend |
string | tesseract_docker |
OCR backend type. Set to none to disable OCR. |
ocr.text_layer_min_chars |
integer | 10 |
Minimum non-whitespace characters required to treat a page as text-layer. Pages below this threshold and dominated by a single large image (>80% of page area) are OCR'd. |
ocr.tesseract |
mapping | {} |
Tesseract-specific configuration overrides. |
ocr.tesseract.oem |
integer | 1 |
Tesseract OCR Engine Mode. Typical values: 0 (legacy), 1 (LSTM), 2 (legacy+LSTM), 3 (default). |
ocr.tesseract.psm |
integer | 4 |
Tesseract Page Segmentation Mode. Typical values: 4 (single column), 6 (single block), 11 (sparse text). |
ocr.tesseract.user_words |
string or mapping | null |
Optional wordlist file path (single list) or a mapping of language codes to file paths. Paths are resolved relative to the current working directory. |
docx |
mapping | {} |
DOCX to PDF conversion backend configuration for viewing DOCX files. |
docx.backend |
string | libreoffice_docker |
DOCX converter backend type. libreoffice_docker_volume uses a shared volume mount. Set to none to disable DOCX viewing. |
pdf |
mapping | {} |
PDF text extraction backend configuration. |
pdf.backend |
string | pdfplumber |
PDF text extraction backend. pymupdf is faster but may produce different text extraction results. |
Example (showing defaults explicitly):
review_backends:
ocr:
backend: tesseract_docker
text_layer_min_chars: 10
tesseract:
oem: 1
psm: 4
user_words: null
pdf:
backend: pdfplumber
docx:
backend: libreoffice_docker
Prerequisites for tesseract_docker backend:
- Docker must be installed and running
- Tesseract container must be running:
docker compose up -d tesseract
When a scanned PDF is uploaded without OCR configured, VIBE Review will display an actionable error message explaining how to enable OCR support.
Prerequisites for libreoffice_docker backend:
- Docker must be installed and running
- LibreOffice container must be running:
docker compose up -d libreoffice
The libreoffice_docker_volume variant uses a shared volume mount instead of docker cp for file transfer, which can be more reliable in some environments (e.g., WSL with Docker Desktop).
Development Settings (dev_settings)¶
The dev_settings section provides a convenient way to simulate PASETO token data during local development. When running in debug mode (debug: true) and no PASETO token is present, VIBE uses these settings to populate the session.
Structure:
| Key | Type | Description |
|---|---|---|
user |
mapping | User information that would normally come from the authentication system. |
user.name |
string | The user's display name. |
user.email |
string | The user's email address. |
session_context |
mapping | Pre-filled data that templates can declare as requirements. This is the development equivalent of the vibe_config payload in a PASETO token. |
grants |
list | A list of permission grants (empty list for most development scenarios). |
How it works:
- When a user starts an interview, VIBE checks for a PASETO token first.
- If no token is found and
debug: trueis set, VIBE usesdev_settingsinstead. - If neither is available, the session starts with an empty context (which is fine as long as the template doesn't require session context).
Session Context Validation:
If a template declares session_context requirements (using definition-only components), VIBE validates the dev_settings.session_context against those requirements at session start. Missing or incorrectly typed values will result in a 400 error.
# Example dev_settings configuration
dev_settings:
user:
name: Fred Bloggs
email: fred@initrode.se
session_context:
organization:
name: Initrode AB
org_number: "556123-4567"
ramavtal:
svarsfrist:
antal: 10
enhet: arbetsdagar
grants: []
Production Note: In production, dev_settings is ignored entirely. All user information and session context must come from a valid PASETO token provided by your authentication system.
Template Configuration (config.yml)¶
This file is located inside each template's source directory (as defined in TEMPLATE_SOURCES). It is the brain of the interview, defining all questions, reusable data structures, and computed logic.
| Key | Type | Required | Description |
|---|---|---|---|
title |
string | No | A human-readable title for the template, shown on the main listing page. |
description |
string | No | A brief description of the template's purpose. |
template_file |
string | No | The name of the main document file (e.g., main.docx). Defaults to template.md or template.docx. |
interview_mode |
string | No | Controls the interview UI mode. Options: standard (traditional forms with live preview, default), assistant (Assistant extension), review (Review extension). |
session_context |
list | No | Declares external data requirements using definition-only components. See Session Context Requirements below. |
assistants |
mapping | No | Assistant extension: Defines AI Drafting Assistants available in this template. |
questions |
mapping | Yes | The master list of all possible questions for the interview. See Question Types Reference for available types including text, number, bool, tristate, date, amount, enum, multichoice, list, structured, computable, and assisted (Assistant extension). |
pages |
mapping | No | Divides questions into logical pages for long interviews. Each page (keyed by page ID) has title and questions (question definitions). See Paged Interviews. |
definitions |
mapping | No | Defines reusable data structures that can be used in structured and list questions. See Reusable Data with definitions. |
computables |
mapping | No | Defines variables whose values are calculated from other answers. See Automated Calculations with Computable Variables. |
component_defaults |
mapping | No | Provides default values for component inputs, reducing repetition in insert() calls. See Building with Components. |
locale |
string | No | Overrides the system-wide locale for this specific template. |
imports |
mapping | No | Adds custom functions or global variables to the template's Jinja environment. |
filters |
mapping | No | Adds custom filters to the template's Jinja environment. |
ui |
mapping | No | Customizes the interview UI (template overrides, stylesheet, preview, layout). See Customizing the Interview UI. |
_insert_questions_* |
null | No | A special marker key to insert a component's questions into the main question order at this position. The * should be the component's alias. |
# Example template config.yml in templates/my_template/
title: Service Agreement Template
description: Generates a standard service agreement for new clients.
template_file: agreement.docx
locale: en_US
assistants:
scope_drafter:
label: "AI: Draft Scope of Work"
model: default
imports:
get_signer_title: my_helpers.get_title_for_signer
filters:
euros: shared_filters.format_euros
component_defaults:
company_name: My Awesome Company Inc.
default_currency: USD
questions:
client_name:
type: text
label: Client's Full Legal Name
contract_value:
type: number
label: Total Contract Value
_insert_questions_signature_block: null
include_nda:
type: bool
label: Include a Non-Disclosure Agreement?
default: false
required: false
definitions:
person_definition:
first_name:
type: text
label: First Name
last_name:
type: text
label: Last Name
UI Customization (ui block)¶
Use the optional ui block when you need to change how the interview itself looks (as opposed to how the generated document renders). All paths are relative to the template directory and are sandboxed so they cannot escape the bundle.
| Key | Type | Required | Description |
|---|---|---|---|
templates |
string | null | No | Directory containing override templates/widgets. When provided, VIBE checks this folder before the built-ins. Set to null (or omit the key) to disable overrides entirely. |
css |
string | No | Path to a CSS file that should be injected into the interview <head>. When present it is served at /interview/<template_id>/ui.css (respecting the selected version). |
preview |
boolean | No | Show the live preview panel (default true). Set to false for a single-column interview. |
layout |
string | No | Group layout for templates using groups:. Options: paged, accordion, tabs, flat. Defaults to paged when groups are present. |
Example:
ui:
templates: ui
css: ui/theme.css
Put individual overrides under the configured directory using the same relative path as VIBE's built-in templates (for example ui/question_types/bool.html or ui/layout/fragments/site_header.html). The CSS file is optional; when configured it loads after VIBE's default stylesheet so you can safely override variables and component styles.
Session Context Requirements (uses)¶
Templates can declare that they require certain external data to be provided at session start. This data typically comes from a PASETO token (in production) or from dev_settings (during development).
Declaring Requirements:
The uses key is a list of references to definition-only components. Each item can be:
- A simple string (component ID and alias are the same):
- organization - A mapping for aliasing:
- ramavtal: framework(component "ramavtal" is aliased as "framework" in the template)
# Template config.yml
uses:
- organization # Use component "organization" as "organization"
- ramavtal: framework # Use component "ramavtal" as "framework"
questions:
contract_title:
type: text
label: Contract Title
Definition-Only Components:
A definition-only component provides data structure definitions without a template file. Create one by adding definition_only: true to its component.yml:
# components/organization/component.yml
definition_only: true
definitions:
namn:
type: text
label: Organization Name
required: true
orgnr:
type: text
label: Organization Number
required: true
settings:
type: structured
fields:
feature_enabled:
type: bool
required: false
default: false
Using Session Context in Templates:
Once declared, session context values are available directly in your template:
# Contract for {{ organization.namn }}
Organization number: {{ organization.orgnr }}
{% if organization.settings.feature_enabled %}
Premium features are enabled.
{% endif %}
Validation:
At session start, VIBE validates that all required session context values are present and correctly typed. If validation fails, the user sees a 400 error explaining which values are missing or invalid.
Type Coercion:
Session context values from PASETO tokens are strings. VIBE automatically coerces them to the correct type based on the definition:
bool: "true"/"false" →True/Falsenumber: "42" or "3.14" →intorfloattext: Passed through as-is
Component Configuration (component.yml)¶
This file is located inside a component's directory. It defines a component's interface (inputs), its internal logic (questions, computables), and its relationship to other data structures (uses).
Component Defaults Configuration (defaults.yml)¶
This file is optionally located inside a file-drop component's directory (alongside the component template file). It provides a lightweight way to declare input expectations for simple file-drop components without requiring a full component.yml configuration.
| Key | Type | Required | Description |
|---|---|---|---|
inputs |
mapping | Yes | Declares the data the file-drop component expects to receive. Each input follows the same field definition syntax as component.yml inputs. |
Purpose and Usage:
- Documentation: Clearly documents which variables a file-drop component expects from its host template
- Validation: Enables VIBE to validate that required inputs are provided when the component is used
- Component Defaults Integration: Inputs declared here can automatically receive values from the host template's
component_defaultsconfiguration - Optional Input Handling: Allows marking specific inputs as optional using
required: false
Input Field Options:
Each input in the inputs mapping can include:
required(boolean): Whether this input must be provided. Defaults totrue.type(string): The expected data type (text, number, bool, etc.). Optional but recommended for validation.description(string): Human-readable description of the input's purpose.
# Example defaults.yml in components/signature_block/
inputs:
# Required inputs that must be provided by host
signer_name:
type: text
description: Full name of the person signing the document
signer_title:
type: text
description: Job title or role of the signer
# Optional input with explicit marking
signing_date:
type: date
required: false
description: Date of signing (optional, can be filled later)
# Input that will use component_defaults if available
company_name:
type: text
description: Company name (will use component_defaults value if set)
Integration with Component Defaults:
Inputs declared in defaults.yml automatically integrate with the host template's component_defaults. If a component default exists with a matching key, it will be used as the input value unless explicitly overridden in the insert() call.
Validation Behavior:
- Required inputs (default) must either be provided in the
insert()call or available through component defaults - Optional inputs (
required: false) can be omitted without causing validation errors - Type validation is performed if a
typeis specified for the input
| Key | Type | Required | Description |
|---|---|---|---|
definition_only |
boolean | No | When true, marks this as a definition-only component that provides data structure definitions for session context validation. These components don't require a template file. |
label |
string | No | A human-readable label for the component. Especially important for appendices. |
description |
string | No | A brief description of the component's purpose. |
uses |
string | No | The ID of a definition from the host template. The component inherits all fields from this definition as its inputs. See Building with Components. |
inputs |
mapping | No | Declares the data the component expects to receive. Each input is a field definition (like a mini-question). |
questions |
mapping | No | Defines questions that are internal to this component and only become relevant when it is inserted. |
computables |
mapping | No | Defines computed variables that are scoped to this component. |
output |
string | No | If present, marks this component as an Appendix. The string is a Jinja template for the output filename. See Generating Appendices and Annexes. |
encapsulation |
string | No | If set to strict, prevents the component from accessing host template variables that are not explicitly passed as inputs. |
# Example component.yml in components/contact_card/
# This component links to a data structure defined in the host template
uses: person_definition
# It adds one additional input field of its own
inputs:
department:
type: text
label: Department
description: The contact's department, e.g., 'Sales'.
required: false
# It also has its own internal question
questions:
show_department:
label: Show department on the contact card?
type: bool
default: true
required: false
# Example appendix component.yml in components/pricing_schedule/
# Marks this as an appendix and defines the output filename pattern
output: "Appendix-{{ ref.numbering }}-{{ ref.label|slugify }}.docx"
label: Pricing Schedule
description: A detailed breakdown of pricing for all services.
# Defines questions that will appear in the UI when this appendix is included
questions:
unit_price:
type: number
label: Price per unit
min: 0
currency:
type: select
label: Currency
options:
- USD
- EUR
- GBP
default: USD