Complete Next.js 16 application with 13 fully implemented modules: Email Signature, Word XML Generator, Registratura, Dashboard, Tag Manager, IT Inventory, Address Book, Password Vault, Mini Utilities, Prompt Generator, Digital Signatures, Word Templates, and AI Chat. Includes core platform systems (module registry, feature flags, storage abstraction, i18n, theming, auth stub, tagging), 16 technical documentation files, Docker deployment config, and legacy HTML tool reference. Co-Authored-By: Claude Opus 4.6 <noreply@anthropic.com>
1095 lines
41 KiB
Markdown
1095 lines
41 KiB
Markdown
# Prompt Generator Module
|
|
|
|
> ArchiTools internal reference -- template-driven, parameterized, provider-agnostic prompt builder.
|
|
|
|
---
|
|
|
|
## Purpose
|
|
|
|
The Prompt Generator is a structured prompt composition tool for architecture, legal, technical, GIS, rendering, BIM, compliance, and administrative workflows. It replaces ad-hoc prompt writing with a template-driven system where prompts are assembled from typed variables, ordered blocks, conditional logic, and provider-specific formatting.
|
|
|
|
The module serves users who interact with AI systems (ChatGPT, Claude, Midjourney, Copilot, domain-specific models) as part of their professional work but lack the time or inclination to engineer prompts from scratch every time.
|
|
|
|
**What it is:**
|
|
- A prompt authoring and composition engine.
|
|
- A template library organized by professional domain.
|
|
- A provider-agnostic output formatter.
|
|
- A prompt version history and favorites system.
|
|
|
|
**What it is not:**
|
|
- An AI chat interface (that is the AI Chat module).
|
|
- An API proxy to AI providers.
|
|
- A prompt execution runtime.
|
|
|
|
---
|
|
|
|
## Core Concepts
|
|
|
|
### Template
|
|
|
|
A reusable prompt blueprint. Contains a sequence of blocks with variable placeholders, metadata (domain, category, target AI type), and optional safety blocks. Templates are the primary unit of reuse.
|
|
|
|
### Block
|
|
|
|
A composable section of a prompt. Each block has a type (role, context, task, constraints, format, etc.), content with `{{variable}}` placeholders, and ordering/visibility rules. Blocks are assembled sequentially by the composition engine.
|
|
|
|
### Variable
|
|
|
|
A typed input slot that gets injected into blocks at composition time. Variables have types (text, select, boolean, tag-selector, etc.), validation rules, and Romanian UI labels. The user fills variables via an auto-generated form.
|
|
|
|
### Domain Pack
|
|
|
|
A grouped bundle of templates for a specific professional domain (architecture visualization, legal review, urbanism/GIS, etc.). Domain packs provide curated starting points so users do not need to browse the full template catalog.
|
|
|
|
### Provider Profile
|
|
|
|
Output formatting rules for a specific AI system. Controls max length, verbosity, instruction style (direct vs. conversational vs. system-prompt), and formatting preference (markdown, plain, structured). The same template produces different output for different providers.
|
|
|
|
---
|
|
|
|
## Template Schema
|
|
|
|
```typescript
|
|
interface PromptTemplate {
|
|
id: string;
|
|
name: string;
|
|
category: PromptCategory;
|
|
domain: PromptDomain;
|
|
description: string;
|
|
targetAiType: 'text' | 'image' | 'code' | 'review' | 'rewrite';
|
|
blocks: PromptBlock[];
|
|
variables: PromptVariable[];
|
|
outputMode: OutputMode;
|
|
providerProfile?: string;
|
|
safetyBlocks?: SafetyBlock[];
|
|
tags: string[];
|
|
version: string;
|
|
author: string;
|
|
visibility: Visibility;
|
|
exampleOutputs?: string[];
|
|
metadata?: Record<string, unknown>;
|
|
}
|
|
|
|
type PromptCategory =
|
|
| 'architecture'
|
|
| 'legal'
|
|
| 'technical'
|
|
| 'administrative'
|
|
| 'gis'
|
|
| 'bim'
|
|
| 'rendering'
|
|
| 'procurement'
|
|
| 'general';
|
|
|
|
type PromptDomain =
|
|
| 'architecture-visualization'
|
|
| 'technical-documentation'
|
|
| 'legal-review'
|
|
| 'urbanism-gis'
|
|
| 'bim-coordination'
|
|
| 'procurement-bidding'
|
|
| 'administrative-writing'
|
|
| 'general';
|
|
|
|
type OutputMode =
|
|
| 'short'
|
|
| 'expanded-expert'
|
|
| 'step-by-step'
|
|
| 'chain-of-thought'
|
|
| 'structured-json'
|
|
| 'checklist';
|
|
|
|
type Visibility = 'all' | 'admin' | 'internal';
|
|
```
|
|
|
|
### Field Reference
|
|
|
|
| Field | Required | Description |
|
|
|---|---|---|
|
|
| `id` | Yes | Unique identifier. Format: `kebab-case`, e.g., `legal-contract-review`. |
|
|
| `name` | Yes | Romanian display name shown in template selectors. |
|
|
| `category` | Yes | Top-level grouping for navigation and filtering. |
|
|
| `domain` | Yes | Professional domain. Maps to a domain pack. |
|
|
| `description` | Yes | Romanian description of what the template produces. |
|
|
| `targetAiType` | Yes | What kind of AI output the prompt targets. |
|
|
| `blocks` | Yes | Ordered list of prompt blocks. At least one required block must exist. |
|
|
| `variables` | Yes | Variables referenced by blocks. Can be empty if template has no dynamic content. |
|
|
| `outputMode` | Yes | Default output structure. User can override in advanced mode. |
|
|
| `providerProfile` | No | Default provider profile ID. User can override. |
|
|
| `safetyBlocks` | No | Optional safety/compliance blocks appended to the prompt. |
|
|
| `tags` | Yes | Searchable tags (reuses the platform tagging system). |
|
|
| `version` | Yes | Semver string. Incremented when template content changes. |
|
|
| `author` | Yes | Creator identifier (user ID or name). |
|
|
| `visibility` | Yes | Access level. |
|
|
| `exampleOutputs` | No | Sample outputs for preview. Helps users understand what the template produces. |
|
|
| `metadata` | No | Extensible key-value store for domain-specific metadata. |
|
|
|
|
---
|
|
|
|
## Block System
|
|
|
|
### PromptBlock Interface
|
|
|
|
```typescript
|
|
interface PromptBlock {
|
|
id: string;
|
|
type: BlockType;
|
|
label: string; // Romanian UI label
|
|
content: string; // template string with {{variable}} placeholders
|
|
order: number;
|
|
required: boolean;
|
|
conditional?: {
|
|
variableId: string;
|
|
operator: 'equals' | 'notEquals' | 'truthy' | 'falsy';
|
|
value?: string;
|
|
};
|
|
}
|
|
|
|
type BlockType =
|
|
| 'role'
|
|
| 'context'
|
|
| 'task'
|
|
| 'constraints'
|
|
| 'format'
|
|
| 'checklist'
|
|
| 'validation'
|
|
| 'output-schema'
|
|
| 'custom';
|
|
```
|
|
|
|
### Block Types
|
|
|
|
| Type | Purpose | Typical Position |
|
|
|---|---|---|
|
|
| `role` | Defines the AI's persona, expertise, and perspective. | First |
|
|
| `context` | Provides background information, project details, domain context. | Second |
|
|
| `task` | The core instruction -- what the AI should do. | Third |
|
|
| `constraints` | Limitations, exclusions, things to avoid. | After task |
|
|
| `format` | Output format requirements (bullet list, table, structured sections). | After constraints |
|
|
| `checklist` | Itemized list of points the output must cover. | After format |
|
|
| `validation` | Criteria for self-checking the output quality. | Near end |
|
|
| `output-schema` | JSON schema or structured format definition for the expected output. | Last |
|
|
| `custom` | Free-form block for domain-specific content that does not fit other types. | Any position |
|
|
|
|
### Conditional Blocks
|
|
|
|
A block with a `conditional` property is only included in the output if the condition evaluates to true. This allows templates to adapt based on user input without requiring separate templates.
|
|
|
|
```typescript
|
|
// Example: include a "Normative References" block only if the user selects regulatory mode
|
|
{
|
|
id: 'block-normative-refs',
|
|
type: 'constraints',
|
|
label: 'Referinte normative',
|
|
content: 'Citeaza toate referintele normative aplicabile conform {{regulation_set}}. Utilizeaza formatarea standard de citare legislativa romaneasca.',
|
|
order: 4,
|
|
required: false,
|
|
conditional: {
|
|
variableId: 'include_regulations',
|
|
operator: 'truthy',
|
|
},
|
|
}
|
|
```
|
|
|
|
### Block Ordering
|
|
|
|
The `order` field determines the sequence of blocks in the final prompt. Blocks are sorted ascending by `order`. Gaps in numbering are allowed and encouraged (use increments of 10) to allow inserting blocks between existing ones.
|
|
|
|
---
|
|
|
|
## Variable System
|
|
|
|
### PromptVariable Interface
|
|
|
|
```typescript
|
|
interface PromptVariable {
|
|
id: string;
|
|
label: string; // Romanian UI label
|
|
type: VariableType;
|
|
required: boolean;
|
|
defaultValue?: unknown;
|
|
placeholder?: string;
|
|
helperText?: string; // Romanian helper text shown below the input
|
|
options?: SelectOption[]; // for select/multi-select types
|
|
validation?: {
|
|
min?: number;
|
|
max?: number;
|
|
pattern?: string;
|
|
};
|
|
}
|
|
|
|
type VariableType =
|
|
| 'text'
|
|
| 'number'
|
|
| 'select'
|
|
| 'multi-select'
|
|
| 'boolean'
|
|
| 'tag-selector'
|
|
| 'project-selector'
|
|
| 'company-selector'
|
|
| 'tone-selector'
|
|
| 'regulation-set-selector';
|
|
|
|
interface SelectOption {
|
|
value: string;
|
|
label: string; // Romanian
|
|
}
|
|
```
|
|
|
|
### Variable Types
|
|
|
|
| Type | UI Control | Value Type | Notes |
|
|
|---|---|---|---|
|
|
| `text` | Text input or textarea | `string` | `validation.max` controls max character length. |
|
|
| `number` | Number input | `number` | `validation.min` / `validation.max` for range. |
|
|
| `select` | Dropdown | `string` | Single selection from `options`. |
|
|
| `multi-select` | Multi-select / checkbox group | `string[]` | Multiple selections from `options`. |
|
|
| `boolean` | Toggle / checkbox | `boolean` | Drives conditional blocks via truthy/falsy. |
|
|
| `tag-selector` | Tag picker component | `string[]` | Integrates with the platform tagging system. |
|
|
| `project-selector` | Project dropdown | `string` | Pulls from a project list (future: from Registry/CRM). |
|
|
| `company-selector` | Company dropdown | `string` | Pre-populated with Beletage, Urban Switch, Studii de Teren. |
|
|
| `tone-selector` | Dropdown | `string` | Options: formal, neutral, technical, persuasive, diplomatic. |
|
|
| `regulation-set-selector` | Multi-select | `string[]` | Romanian building codes, urbanism laws, EU directives. |
|
|
|
|
### Variable Injection
|
|
|
|
Variables are referenced in block content using `{{variableId}}` syntax. The composition engine replaces placeholders with resolved values.
|
|
|
|
**Text/number:** Injected as-is.
|
|
|
|
**Select:** The selected option's `value` is injected. If the label is needed, use `{{variableId.label}}`.
|
|
|
|
**Multi-select / tag-selector:** Injected as a comma-separated list by default. The composition engine formats arrays according to the provider profile's preference (comma list, bullet list, numbered list).
|
|
|
|
**Boolean:** Drives conditional blocks via `truthy`/`falsy` operators. Not typically injected as text. If referenced directly, resolves to `"da"` / `"nu"`.
|
|
|
|
---
|
|
|
|
## Composition Engine
|
|
|
|
The composition engine is the core runtime that transforms a template + variable values + provider profile into a final prompt string.
|
|
|
|
### Pipeline
|
|
|
|
```
|
|
1. Collect variable values from the user form
|
|
|
|
|
2. Validate all required variables are filled
|
|
|
|
|
3. Evaluate conditional blocks
|
|
|
|
|
4. Sort blocks by order (ascending)
|
|
|
|
|
5. Filter out:
|
|
- Disabled conditional blocks
|
|
- Optional blocks with no variable content (all placeholders empty)
|
|
|
|
|
6. For each remaining block:
|
|
a. Replace {{variable}} placeholders with resolved values
|
|
b. Apply array formatting (comma list, bullet list, etc.)
|
|
c. Trim whitespace
|
|
|
|
|
7. Join blocks with separator (double newline by default)
|
|
|
|
|
8. Append safety blocks (if enabled)
|
|
|
|
|
9. Apply provider profile formatting:
|
|
- Truncate to maxLength (if set)
|
|
- Adjust verbosity (expand or compress instructions)
|
|
- Format for instruction style (direct, conversational, system-prompt)
|
|
- Apply formatting preference (markdown headers, plain text, structured tags)
|
|
|
|
|
10. Output final prompt string
|
|
```
|
|
|
|
### Implementation
|
|
|
|
```typescript
|
|
// src/modules/prompt-generator/services/composition-engine.ts
|
|
|
|
interface CompositionInput {
|
|
template: PromptTemplate;
|
|
values: Record<string, unknown>;
|
|
providerProfile?: ProviderProfile;
|
|
outputMode?: OutputMode;
|
|
}
|
|
|
|
interface CompositionResult {
|
|
prompt: string;
|
|
metadata: {
|
|
templateId: string;
|
|
templateVersion: string;
|
|
blockCount: number;
|
|
variableCount: number;
|
|
characterCount: number;
|
|
providerProfile: string | null;
|
|
outputMode: OutputMode;
|
|
timestamp: string;
|
|
};
|
|
warnings: string[];
|
|
}
|
|
|
|
function composePrompt(input: CompositionInput): CompositionResult {
|
|
const { template, values, providerProfile, outputMode } = input;
|
|
const warnings: string[] = [];
|
|
const resolvedMode = outputMode ?? template.outputMode;
|
|
|
|
// 1. Validate required variables
|
|
for (const variable of template.variables) {
|
|
if (variable.required && !hasValue(values[variable.id])) {
|
|
throw new CompositionError(`Required variable "${variable.id}" is missing.`);
|
|
}
|
|
}
|
|
|
|
// 2. Filter and sort blocks
|
|
const activeBlocks = template.blocks
|
|
.filter(block => evaluateCondition(block, values))
|
|
.filter(block => block.required || hasBlockContent(block, values))
|
|
.sort((a, b) => a.order - b.order);
|
|
|
|
// 3. Resolve blocks
|
|
const resolvedBlocks = activeBlocks.map(block =>
|
|
resolveBlock(block, values, template.variables)
|
|
);
|
|
|
|
// 4. Join
|
|
let prompt = resolvedBlocks.join('\n\n');
|
|
|
|
// 5. Append safety blocks
|
|
if (template.safetyBlocks?.length) {
|
|
const safetyContent = template.safetyBlocks
|
|
.filter(sb => sb.enabled)
|
|
.map(sb => sb.content)
|
|
.join('\n');
|
|
if (safetyContent) {
|
|
prompt += '\n\n' + safetyContent;
|
|
}
|
|
}
|
|
|
|
// 6. Apply provider profile
|
|
if (providerProfile) {
|
|
prompt = applyProviderProfile(prompt, providerProfile, warnings);
|
|
}
|
|
|
|
return {
|
|
prompt,
|
|
metadata: {
|
|
templateId: template.id,
|
|
templateVersion: template.version,
|
|
blockCount: activeBlocks.length,
|
|
variableCount: Object.keys(values).length,
|
|
characterCount: prompt.length,
|
|
providerProfile: providerProfile?.id ?? null,
|
|
outputMode: resolvedMode,
|
|
timestamp: new Date().toISOString(),
|
|
},
|
|
warnings,
|
|
};
|
|
}
|
|
```
|
|
|
|
### Variable Resolution
|
|
|
|
```typescript
|
|
function resolveBlock(
|
|
block: PromptBlock,
|
|
values: Record<string, unknown>,
|
|
variables: PromptVariable[]
|
|
): string {
|
|
let content = block.content;
|
|
|
|
// Replace all {{variableId}} placeholders
|
|
const placeholderPattern = /\{\{(\w+)(?:\.(\w+))?\}\}/g;
|
|
|
|
content = content.replace(placeholderPattern, (match, varId, property) => {
|
|
const variable = variables.find(v => v.id === varId);
|
|
if (!variable) return match; // leave unresolved placeholders as-is
|
|
|
|
const value = values[varId];
|
|
if (value === undefined || value === null || value === '') return '';
|
|
|
|
// Handle property access (e.g., {{variable.label}})
|
|
if (property === 'label' && variable.options) {
|
|
const option = variable.options.find(o => o.value === value);
|
|
return option?.label ?? String(value);
|
|
}
|
|
|
|
// Handle arrays (multi-select, tag-selector)
|
|
if (Array.isArray(value)) {
|
|
return value.join(', ');
|
|
}
|
|
|
|
// Handle booleans
|
|
if (typeof value === 'boolean') {
|
|
return value ? 'da' : 'nu';
|
|
}
|
|
|
|
return String(value);
|
|
});
|
|
|
|
return content.trim();
|
|
}
|
|
```
|
|
|
|
### Conditional Evaluation
|
|
|
|
```typescript
|
|
function evaluateCondition(
|
|
block: PromptBlock,
|
|
values: Record<string, unknown>
|
|
): boolean {
|
|
if (!block.conditional) return true;
|
|
|
|
const { variableId, operator, value: expectedValue } = block.conditional;
|
|
const actualValue = values[variableId];
|
|
|
|
switch (operator) {
|
|
case 'truthy':
|
|
return Boolean(actualValue);
|
|
case 'falsy':
|
|
return !actualValue;
|
|
case 'equals':
|
|
return String(actualValue) === String(expectedValue);
|
|
case 'notEquals':
|
|
return String(actualValue) !== String(expectedValue);
|
|
default:
|
|
return true;
|
|
}
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Output Modes
|
|
|
|
The output mode controls the structural framing of the composed prompt. It wraps or restructures the assembled blocks to match a desired reasoning style.
|
|
|
|
| Mode | Description | Use Case |
|
|
|---|---|---|
|
|
| `short` | Minimal instruction. No preamble, no step enumeration. | Quick queries, image prompts. |
|
|
| `expanded-expert` | Full expert-level prompt with detailed role, context, and constraints. | Complex professional tasks. |
|
|
| `step-by-step` | Wraps the task block in a numbered step sequence instruction. | Procedural workflows, checklists. |
|
|
| `chain-of-thought` | Adds "think step by step" framing, asks for reasoning before conclusion. | Analysis, review, decision-making. |
|
|
| `structured-json` | Requests output in a specific JSON schema, includes the schema in the prompt. | Data extraction, structured output. |
|
|
| `checklist` | Formats the output requirement as a checklist with pass/fail items. | Compliance review, QA checks. |
|
|
|
|
---
|
|
|
|
## Domain Packs
|
|
|
|
Domain packs are curated bundles of templates, safety blocks, and default provider profiles for a professional domain. They provide a starting point for users in a specific role.
|
|
|
|
### Available Domain Packs
|
|
|
|
#### Architecture Visualization
|
|
|
|
Templates for generating architectural renders, concept imagery, material studies, and presentation graphics.
|
|
|
|
| Template | Target AI | Description |
|
|
|---|---|---|
|
|
| Exterior render brief | image | Detailed brief for photorealistic exterior visualization. |
|
|
| Interior mood board | image | Style and material palette for interior spaces. |
|
|
| Concept sketch directive | image | Abstract/conceptual architectural sketch instructions. |
|
|
| Material study | image | Close-up material and texture specifications. |
|
|
| Site context rendering | image | Aerial/contextual rendering with surroundings. |
|
|
|
|
#### Technical Documentation
|
|
|
|
Templates for generating technical descriptions, specifications, and reports.
|
|
|
|
| Template | Target AI | Description |
|
|
|---|---|---|
|
|
| Technical memorandum | text | Structured technical memo for project documentation. |
|
|
| Specification writer | text | Material/system specification in Romanian standard format. |
|
|
| Site analysis summary | text | Site conditions and constraints synthesis. |
|
|
| Meeting minutes structurer | text | Meeting notes formatted to standard template. |
|
|
| Design brief elaborator | text | Expand a brief design intent into a full brief. |
|
|
|
|
#### Legal Review
|
|
|
|
Templates for legal document analysis, contract review, and regulatory compliance.
|
|
|
|
| Template | Target AI | Description |
|
|
|---|---|---|
|
|
| Contract clause reviewer | review | Analyze contract clauses for risks and missing provisions. |
|
|
| Regulatory compliance check | review | Check project documentation against specific regulations. |
|
|
| Legal response drafter | text | Draft formal legal responses in Romanian administrative style. |
|
|
| Permit application reviewer | review | Review building permit application for completeness. |
|
|
| Urban certificate analyzer | review | Analyze urbanism certificate conditions and constraints. |
|
|
|
|
#### Urbanism / GIS
|
|
|
|
Templates for urban planning analysis, GIS data interpretation, and regulatory land-use review.
|
|
|
|
| Template | Target AI | Description |
|
|
|---|---|---|
|
|
| PUZ/PUD analysis | text | Analyze zonal/detailed urban plan provisions. |
|
|
| Land use assessment | text | Evaluate land use compatibility and zoning constraints. |
|
|
| GIS data descriptor | text | Describe spatial data layers and their implications. |
|
|
| Urban indicators calculator | text | Calculate urban indicators (CUT, POT, regim de inaltime). |
|
|
|
|
#### BIM Coordination
|
|
|
|
Templates for BIM model review, clash detection reporting, and LOD specification.
|
|
|
|
| Template | Target AI | Description |
|
|
|---|---|---|
|
|
| Clash detection report | text | Structure clash detection results into actionable report. |
|
|
| LOD specification | text | Define level of development requirements per discipline. |
|
|
| Model audit checklist | checklist | QA checklist for BIM model compliance. |
|
|
| BEP section drafter | text | Draft sections of a BIM Execution Plan. |
|
|
|
|
#### Procurement / Bidding
|
|
|
|
Templates for preparing procurement documents, bid evaluations, and cost analyses.
|
|
|
|
| Template | Target AI | Description |
|
|
|---|---|---|
|
|
| Bid evaluation matrix | text | Structure criteria and scoring for bid evaluation. |
|
|
| Caiet de sarcini drafter | text | Draft technical specifications (caiet de sarcini) sections. |
|
|
| Cost estimate reviewer | review | Review cost estimates for completeness and reasonableness. |
|
|
| Procurement timeline | text | Generate procurement schedule with milestones. |
|
|
|
|
#### Formal Romanian Administrative Writing
|
|
|
|
Templates for official correspondence, institutional communication, and public administration documents.
|
|
|
|
| Template | Target AI | Description |
|
|
|---|---|---|
|
|
| Adresa oficiala | text | Formal letter to public institution. |
|
|
| Cerere/solicitare | text | Formal request document. |
|
|
| Nota interna | text | Internal memo in institutional format. |
|
|
| Raport de activitate | text | Activity report with standardized structure. |
|
|
| Proces verbal | text | Minutes/official record in Romanian administrative format. |
|
|
|
|
---
|
|
|
|
## Provider Profiles
|
|
|
|
### Interface
|
|
|
|
```typescript
|
|
interface ProviderProfile {
|
|
id: string;
|
|
name: string;
|
|
maxLength?: number;
|
|
formattingPreference: 'markdown' | 'plain' | 'structured';
|
|
instructionStyle: 'direct' | 'conversational' | 'system-prompt';
|
|
verbosityLevel: 'concise' | 'standard' | 'detailed';
|
|
}
|
|
```
|
|
|
|
### Default Profiles
|
|
|
|
```typescript
|
|
const defaultProfiles: ProviderProfile[] = [
|
|
{
|
|
id: 'chatgpt',
|
|
name: 'ChatGPT (GPT-4)',
|
|
maxLength: 8000,
|
|
formattingPreference: 'markdown',
|
|
instructionStyle: 'system-prompt',
|
|
verbosityLevel: 'standard',
|
|
},
|
|
{
|
|
id: 'claude',
|
|
name: 'Claude',
|
|
maxLength: 16000,
|
|
formattingPreference: 'markdown',
|
|
instructionStyle: 'direct',
|
|
verbosityLevel: 'detailed',
|
|
},
|
|
{
|
|
id: 'midjourney',
|
|
name: 'Midjourney',
|
|
maxLength: 500,
|
|
formattingPreference: 'plain',
|
|
instructionStyle: 'direct',
|
|
verbosityLevel: 'concise',
|
|
},
|
|
{
|
|
id: 'copilot',
|
|
name: 'GitHub Copilot',
|
|
maxLength: 4000,
|
|
formattingPreference: 'markdown',
|
|
instructionStyle: 'direct',
|
|
verbosityLevel: 'concise',
|
|
},
|
|
{
|
|
id: 'generic',
|
|
name: 'Generic / Other',
|
|
formattingPreference: 'markdown',
|
|
instructionStyle: 'direct',
|
|
verbosityLevel: 'standard',
|
|
},
|
|
];
|
|
```
|
|
|
|
### Provider Profile Application
|
|
|
|
```typescript
|
|
function applyProviderProfile(
|
|
prompt: string,
|
|
profile: ProviderProfile,
|
|
warnings: string[]
|
|
): string {
|
|
let result = prompt;
|
|
|
|
// Truncate if over maxLength
|
|
if (profile.maxLength && result.length > profile.maxLength) {
|
|
warnings.push(
|
|
`Prompt truncated from ${result.length} to ${profile.maxLength} characters for ${profile.name}.`
|
|
);
|
|
result = result.slice(0, profile.maxLength);
|
|
}
|
|
|
|
// Strip markdown for plain profiles
|
|
if (profile.formattingPreference === 'plain') {
|
|
result = stripMarkdown(result);
|
|
}
|
|
|
|
// Wrap in system-prompt format if needed
|
|
if (profile.instructionStyle === 'system-prompt') {
|
|
result = wrapAsSystemPrompt(result);
|
|
}
|
|
|
|
return result;
|
|
}
|
|
```
|
|
|
|
---
|
|
|
|
## Safety Blocks
|
|
|
|
Safety blocks are optional, toggleable sections appended to prompts to enforce professional standards.
|
|
|
|
### Interface
|
|
|
|
```typescript
|
|
interface SafetyBlock {
|
|
id: string;
|
|
label: string; // Romanian
|
|
content: string;
|
|
enabled: boolean; // default state; user can toggle
|
|
category: 'legal' | 'tone' | 'citation' | 'disclaimer';
|
|
}
|
|
```
|
|
|
|
### Default Safety Blocks
|
|
|
|
```typescript
|
|
const defaultSafetyBlocks: SafetyBlock[] = [
|
|
{
|
|
id: 'legal-tone',
|
|
label: 'Ton juridic formal',
|
|
content: 'Utilizeaza exclusiv limbaj juridic formal, conform practicii legislative si administrative romanesti. Evita formulari colocviale sau ambigue din punct de vedere juridic.',
|
|
enabled: false,
|
|
category: 'tone',
|
|
},
|
|
{
|
|
id: 'neutral-tone',
|
|
label: 'Ton neutru si obiectiv',
|
|
content: 'Mentine un ton neutru, obiectiv si profesional pe tot parcursul raspunsului. Evita formulari subiective, emotionale sau persuasive.',
|
|
enabled: false,
|
|
category: 'tone',
|
|
},
|
|
{
|
|
id: 'normative-refs',
|
|
label: 'Cerinta referinte normative',
|
|
content: 'Citeaza toate actele normative aplicabile (legi, hotarari de guvern, ordine, norme tehnice) cu numar, data si titlu complet. Indica articolele si alineatele relevante.',
|
|
enabled: false,
|
|
category: 'citation',
|
|
},
|
|
{
|
|
id: 'uncertainty-disclaimer',
|
|
label: 'Disclaimer incertitudine',
|
|
content: 'Semnaleaza explicit orice incertitudine, ambiguitate sau lipsa de informatii. Delimiteaza clar informatiile factuale de interpretari sau presupuneri. Indica cazurile in care este necesara verificarea de catre un specialist.',
|
|
enabled: false,
|
|
category: 'disclaimer',
|
|
},
|
|
{
|
|
id: 'source-citation',
|
|
label: 'Cerinta citare surse',
|
|
content: 'Citeaza sursa fiecarei informatii factuale prezentate. Pentru reglementari, indica actul normativ specific. Pentru standarde, indica codul si anul editiei. Pentru date tehnice, indica sursa si data accesarii.',
|
|
enabled: false,
|
|
category: 'citation',
|
|
},
|
|
];
|
|
```
|
|
|
|
### Usage
|
|
|
|
Safety blocks are toggleable per template. When a template is loaded, the form shows toggles for each safety block. The user can enable or disable them before composing the prompt. Enabled safety blocks are appended after all content blocks, separated by a delimiter line.
|
|
|
|
---
|
|
|
|
## UX Flow
|
|
|
|
### Primary Flow
|
|
|
|
```
|
|
1. User opens Prompt Generator module
|
|
|
|
|
2. Domain selector: user picks a professional domain
|
|
(architecture-visualization, legal-review, etc.)
|
|
|
|
|
3. Template list filters to show only templates in the selected domain
|
|
User can also search/filter by tags, category, or AI type
|
|
|
|
|
4. User selects a template
|
|
|
|
|
5. Variable form renders:
|
|
- Required variables marked with indicator
|
|
- Default values pre-filled
|
|
- Helper text shown below each input
|
|
- Selectors (tag, project, company, tone, regulation) render
|
|
appropriate picker components
|
|
|
|
|
6. Live preview panel updates as the user fills variables
|
|
- Shows the composed prompt in real time
|
|
- Conditional blocks appear/disappear as conditions change
|
|
- Character count and provider compatibility shown
|
|
|
|
|
7. Advanced mode (toggle):
|
|
- Output mode selector (short, expanded-expert, etc.)
|
|
- Provider profile selector
|
|
- Safety block toggles
|
|
- Block reordering (drag and drop)
|
|
- Custom block insertion
|
|
|
|
|
8. Actions:
|
|
- Copy to clipboard (primary action)
|
|
- Save to history
|
|
- Add to favorites
|
|
- Export as JSON (for sharing or backup)
|
|
- Send to AI Chat module (opens AI Chat with prompt pre-filled)
|
|
- Save as custom template (forks the template with current variable defaults)
|
|
```
|
|
|
|
### Layout
|
|
|
|
```
|
|
┌─────────────────────────────────────────────────────────────────────┐
|
|
│ Prompt Generator [Advanced] │
|
|
├──────────────────────┬──────────────────────────────────────────────┤
|
|
│ │ │
|
|
│ Domain: [dropdown] │ PREVIEW │
|
|
│ │ │
|
|
│ ┌────────────────┐ │ ┌────────────────────────────────────────┐ │
|
|
│ │ Template List │ │ │ │ │
|
|
│ │ │ │ │ Esti un arhitect specialist in │ │
|
|
│ │ > Exterior... │ │ │ proiectare rezidentiala cu 15 ani │ │
|
|
│ │ Interior... │ │ │ experienta in {{context}}... │ │
|
|
│ │ Concept... │ │ │ │ │
|
|
│ │ Material... │ │ │ Sarcina: Genereaza {{task_type}} │ │
|
|
│ │ │ │ │ pentru proiectul {{project_name}}... │ │
|
|
│ └────────────────┘ │ │ │ │
|
|
│ │ │ Constrangeri: │ │
|
|
│ VARIABLES │ │ - {{constraints}} │ │
|
|
│ ┌────────────────┐ │ │ │ │
|
|
│ │ Proiect: │ │ │ Format: {{output_format}} │ │
|
|
│ │ [__________] │ │ │ │ │
|
|
│ │ │ │ └────────────────────────────────────────┘ │
|
|
│ │ Tip sarcina: │ │ │
|
|
│ │ [dropdown ] │ │ Characters: 1,247 / 8,000 │
|
|
│ │ │ │ Provider: ChatGPT (GPT-4) │
|
|
│ │ Context: │ │ │
|
|
│ │ [__________] │ │ [Copy] [Save] [Send to AI Chat] [Export] │
|
|
│ │ [__________] │ │ │
|
|
│ └────────────────┘ │ │
|
|
│ │ │
|
|
├──────────────────────┴──────────────────────────────────────────────┤
|
|
│ Safety: [ ] Ton juridic [ ] Ton neutru [x] Disclaimer │
|
|
└─────────────────────────────────────────────────────────────────────┘
|
|
```
|
|
|
|
---
|
|
|
|
## Integration with Other Modules
|
|
|
|
### Tag Manager
|
|
|
|
The Prompt Generator uses the platform tagging system for:
|
|
- Template tagging (categorization, search, filtering).
|
|
- The `tag-selector` variable type, which renders the shared tag picker component.
|
|
- Prompt history entries can be tagged for organization.
|
|
|
|
Integration is through the shared tagging service (`src/core/tagging/`), not through direct module imports.
|
|
|
|
### AI Chat
|
|
|
|
Generated prompts can be sent directly to the AI Chat module. The flow:
|
|
1. User composes a prompt in Prompt Generator.
|
|
2. User clicks "Send to AI Chat."
|
|
3. The platform navigates to the AI Chat module with the prompt pre-filled in the input field.
|
|
|
|
Communication mechanism: URL query parameter (`/ai-chat?prompt=<encoded>`) or a shared transient state service in `src/lib/`. The Prompt Generator does not import from the AI Chat module directly.
|
|
|
|
### Registry (Registratura)
|
|
|
|
Prompts can be attached to registry entries as metadata. Use cases:
|
|
- Attach the prompt used to generate a document to the document's registry entry.
|
|
- Link prompt templates to specific project phases or document types.
|
|
|
|
Integration: The Prompt Generator exposes a "Link to Registry" action that stores a reference (prompt history ID) in the registry entry's metadata.
|
|
|
|
### Word Templates
|
|
|
|
Prompt output can feed into Word template generation:
|
|
1. User generates structured text via Prompt Generator (e.g., a technical memorandum).
|
|
2. User sends the output to the Word Template module for formatting into a `.docx` file.
|
|
3. The Word Template module receives the text as variable input.
|
|
|
|
Integration: Similar to AI Chat -- URL parameter or shared transient state. No direct module imports.
|
|
|
|
---
|
|
|
|
## Prompt History
|
|
|
|
### Storage
|
|
|
|
Prompt history is persisted via the platform storage abstraction under the `prompt-generator` namespace.
|
|
|
|
```typescript
|
|
interface PromptHistoryEntry {
|
|
id: string;
|
|
templateId: string;
|
|
templateName: string;
|
|
templateVersion: string;
|
|
values: Record<string, unknown>;
|
|
composedPrompt: string;
|
|
outputMode: OutputMode;
|
|
providerProfile: string | null;
|
|
safetyBlocks: string[]; // IDs of enabled safety blocks
|
|
tags: string[];
|
|
isFavorite: boolean;
|
|
createdAt: string; // ISO 8601
|
|
metadata?: Record<string, unknown>;
|
|
}
|
|
```
|
|
|
|
### Storage Keys
|
|
|
|
| Key Pattern | Content |
|
|
|---|---|
|
|
| `history::{id}` | Individual history entry. |
|
|
| `favorites` | Array of favorite history entry IDs. |
|
|
| `recent-templates` | Array of recently used template IDs (last 10). |
|
|
|
|
### Capabilities
|
|
|
|
- **Save:** Every composed prompt can be saved to history with one click.
|
|
- **Favorites:** Mark history entries as favorites for quick access.
|
|
- **Version comparison:** When a template version changes, compare the old composed output with a new composition using the same variable values.
|
|
- **Search:** Full-text search across history entries (prompt text, template name, tags).
|
|
- **Export:** Export history as JSON for backup or sharing.
|
|
|
|
---
|
|
|
|
## Module Structure
|
|
|
|
```
|
|
src/modules/prompt-generator/
|
|
components/
|
|
TemplateSelector.tsx # Domain filter + template list + search
|
|
VariableForm.tsx # Auto-generated form from template variables
|
|
BlockEditor.tsx # Block reordering, custom block insertion (advanced mode)
|
|
PromptPreview.tsx # Live preview panel with character count
|
|
DomainPackBrowser.tsx # Domain pack overview and template browsing
|
|
ProviderProfileSelector.tsx # Provider profile dropdown with profile details
|
|
PromptHistory.tsx # History list, favorites, search, version comparison
|
|
hooks/
|
|
usePromptComposer.ts # Core composition state: template, values, preview
|
|
useTemplateManager.ts # Template CRUD, custom template creation
|
|
usePromptHistory.ts # History persistence, favorites, search
|
|
useDomainPacks.ts # Domain pack loading and filtering
|
|
services/
|
|
composition-engine.ts # Template + values + profile --> final prompt
|
|
template-service.ts # Template loading, validation, custom template storage
|
|
variable-resolver.ts # Variable value resolution, validation, formatting
|
|
data/
|
|
default-templates.ts # Built-in template definitions
|
|
domain-packs.ts # Domain pack configurations
|
|
provider-profiles.ts # Default provider profiles
|
|
safety-blocks.ts # Default safety block definitions
|
|
types.ts # All TypeScript interfaces (PromptTemplate, PromptBlock, etc.)
|
|
config.ts # ModuleConfig for the registry
|
|
index.ts # Barrel export
|
|
```
|
|
|
|
### Component Responsibilities
|
|
|
|
| Component | Responsibility |
|
|
|---|---|
|
|
| `TemplateSelector` | Renders domain filter dropdown, template list with search, category badges, and AI type indicators. Emits selected template to parent. |
|
|
| `VariableForm` | Receives a `PromptVariable[]` array, renders the appropriate input control for each variable type, validates input, and emits value changes. Does not know about templates or composition. |
|
|
| `BlockEditor` | Advanced mode only. Shows block list with drag-and-drop reordering, inline content editing, and custom block insertion. |
|
|
| `PromptPreview` | Receives the composed prompt string and renders it with syntax highlighting, character count, provider compatibility indicator, and copy button. |
|
|
| `DomainPackBrowser` | Shows domain packs as cards with template counts. Clicking a pack filters the template list. |
|
|
| `ProviderProfileSelector` | Dropdown with provider profile details (max length, formatting, instruction style). |
|
|
| `PromptHistory` | Tabbed view: Recent, Favorites, All. Each entry shows template name, date, preview snippet, and actions (re-use, compare, delete). |
|
|
|
|
### Hook Responsibilities
|
|
|
|
| Hook | Responsibility |
|
|
|---|---|
|
|
| `usePromptComposer` | Central composition state. Manages selected template, variable values, output mode, provider profile, safety block toggles. Calls composition engine on value changes. Returns composed prompt and metadata. |
|
|
| `useTemplateManager` | Loads default and custom templates. Handles custom template creation (forking a default template with modified defaults). Persists custom templates to storage. |
|
|
| `usePromptHistory` | CRUD for prompt history entries. Favorites management. Search and filtering. Uses `useStorage('prompt-generator')`. |
|
|
| `useDomainPacks` | Loads domain pack configurations. Provides filtered template lists per domain. Tracks recently used domains. |
|
|
|
|
### Service Responsibilities
|
|
|
|
| Service | Responsibility |
|
|
|---|---|
|
|
| `composition-engine.ts` | Pure function: `composePrompt(template, values, profile) -> result`. No side effects, no state, no storage access. Fully testable. |
|
|
| `template-service.ts` | Template validation (required fields, block consistency, variable references). Custom template persistence via storage abstraction. Template versioning. |
|
|
| `variable-resolver.ts` | Variable value validation against type constraints. Default value resolution. Array formatting (comma list, bullet list). Boolean-to-text conversion. |
|
|
|
|
---
|
|
|
|
## Module Configuration
|
|
|
|
```typescript
|
|
// src/modules/prompt-generator/config.ts
|
|
|
|
import { ModuleConfig } from '@/types/modules';
|
|
|
|
export const promptGeneratorConfig: ModuleConfig = {
|
|
id: 'prompt-generator',
|
|
name: 'Generator Prompturi',
|
|
description: 'Generator structurat de prompturi pe baza sabloanelor parametrizate, organizate pe domenii profesionale.',
|
|
icon: 'wand-sparkles',
|
|
route: '/prompt-generator',
|
|
category: 'ai',
|
|
featureFlag: 'module.prompt-generator',
|
|
visibility: 'all',
|
|
version: '1.0.0',
|
|
dependencies: [],
|
|
storageNamespace: 'prompt-generator',
|
|
navOrder: 20,
|
|
tags: ['prompt', 'ai', 'generator', 'templates'],
|
|
};
|
|
```
|
|
|
|
---
|
|
|
|
## Anti-Patterns
|
|
|
|
### No Hardcoded Templates in UI Components
|
|
|
|
Templates live in `data/default-templates.ts` and custom templates in storage. Components render templates dynamically from the template list. A component must never contain a prompt template string directly.
|
|
|
|
**Wrong:**
|
|
```typescript
|
|
// Inside TemplateSelector.tsx
|
|
const templates = [
|
|
{ name: 'Legal Review', content: 'Esti un avocat specialist...' },
|
|
];
|
|
```
|
|
|
|
**Right:**
|
|
```typescript
|
|
// In data/default-templates.ts
|
|
export const defaultTemplates: PromptTemplate[] = [
|
|
{
|
|
id: 'legal-contract-review',
|
|
name: 'Revizuire contract',
|
|
// ... full template definition
|
|
},
|
|
];
|
|
|
|
// In TemplateSelector.tsx
|
|
function TemplateSelector({ templates }: { templates: PromptTemplate[] }) {
|
|
// render from props, never from inline data
|
|
}
|
|
```
|
|
|
|
### No Provider-Specific Logic in Templates
|
|
|
|
Templates are provider-agnostic. Provider-specific formatting (max length, instruction style, verbosity) is applied by the composition engine using the selected provider profile. A template must never contain conditional logic for specific providers.
|
|
|
|
**Wrong:**
|
|
```typescript
|
|
{
|
|
content: 'You are a legal expert. {{#if provider === "midjourney"}}Keep it under 500 chars.{{/if}}',
|
|
}
|
|
```
|
|
|
|
**Right:**
|
|
```typescript
|
|
// Template contains only the core instruction
|
|
{
|
|
content: 'Esti un expert juridic specializat in {{domain}}.',
|
|
}
|
|
// Provider profile controls length and formatting
|
|
```
|
|
|
|
### No Inline Romanian Text
|
|
|
|
All Romanian-language strings used in the UI (labels, placeholders, helper text, error messages) must come from the variable/block definitions or the platform i18n system. Components must not contain inline Romanian strings.
|
|
|
|
**Wrong:**
|
|
```typescript
|
|
<label>Selecteaza domeniul profesional:</label>
|
|
```
|
|
|
|
**Right:**
|
|
```typescript
|
|
<label>{variable.label}</label>
|
|
// where variable.label = 'Domeniu profesional' from the variable definition
|
|
```
|
|
|
|
Or through the i18n system:
|
|
```typescript
|
|
<label>{useLabel('prompt-generator.domainSelector')}</label>
|
|
```
|
|
|
|
---
|
|
|
|
## Data Flow
|
|
|
|
### Template Selection to Prompt Output
|
|
|
|
```
|
|
User selects domain
|
|
--> useDomainPacks filters templates
|
|
--> TemplateSelector renders filtered list
|
|
--> User selects template
|
|
--> usePromptComposer loads template
|
|
--> VariableForm renders from template.variables
|
|
--> User fills variables
|
|
--> usePromptComposer calls composePrompt()
|
|
--> composition-engine resolves blocks + variables
|
|
--> PromptPreview renders result
|
|
--> User copies / saves / exports
|
|
```
|
|
|
|
### Custom Template Creation
|
|
|
|
```
|
|
User fills variables on an existing template
|
|
--> User clicks "Save as custom template"
|
|
--> useTemplateManager.fork(templateId, currentValues)
|
|
--> Creates a new PromptTemplate with:
|
|
- New ID (uuid)
|
|
- Current variable values as new defaultValues
|
|
- Author set to current user
|
|
- Version "1.0.0"
|
|
--> template-service persists to storage (prompt-generator::custom-templates)
|
|
--> Custom template appears in the template list
|
|
```
|
|
|
|
### Prompt History Save
|
|
|
|
```
|
|
User composes a prompt
|
|
--> User clicks "Save"
|
|
--> usePromptHistory.save(compositionResult)
|
|
--> Creates PromptHistoryEntry with:
|
|
- Snapshot of template ID, version, values, composed prompt
|
|
- Timestamp
|
|
--> Persists to storage (prompt-generator::history::{id})
|
|
--> PromptHistory component updates
|
|
```
|