Creates a PromptOpsKit instance.
import { createPromptOpsKit } from 'promptopskit';
const kit = createPromptOpsKit();| Option | Type | Default | Description |
|---|---|---|---|
sourceDir |
string |
./prompts |
Path to prompt .md files |
compiledDir |
string |
./.generated-prompts/json |
Path to compiled artifacts |
mode |
'auto' | 'compiled-only' | 'source-only' |
'auto' |
Resolution strategy |
cache |
boolean |
true |
Enable LRU cache with mtime invalidation |
warnings.contextSize |
'auto' | 'off' | 'result-only' | 'console' | 'console-and-result' |
'auto' |
Control whether render-time context size warnings are returned, logged, both, or suppressed |
Example with overrides:
const kit = createPromptOpsKit({
sourceDir: './prompts',
compiledDir: './.generated-prompts/json',
mode: 'auto',
cache: true,
warnings: {
contextSize: 'auto',
},
});| Mode | Behavior |
|---|---|
auto |
Prefer compiled artifacts when available, fall back to source. Warns if compiled artifact is older than source. |
compiled-only |
Only load from compiledDir. Throws if artifact is missing. |
source-only |
Only parse from sourceDir. Ignores compiled artifacts. |
Renders a prompt for a specific provider. Returns { resolved, request?, returnMessage?, warnings }.
const result = await kit.renderPrompt({
path: 'support/reply',
provider: 'openai',
variables: { user_message: 'How do I reset my password?' },
environment: 'prod',
tier: 'pro',
history: [
{ role: 'user', content: 'Hello' },
{ role: 'assistant', content: 'Hi!' },
],
strict: false,
});| Option | Type | Description |
|---|---|---|
path |
string |
Prompt path (no extension), e.g. 'support/reply' |
source |
string |
Inline prompt source (alternative to path) |
provider |
string |
'openai', 'openai-responses', 'anthropic', 'gemini', 'openrouter' (required) |
variables |
Record<string, string> |
Template variables |
onContextOverflow |
(info) => string |
Optional callback to transform an oversized context value before rendering |
environment |
string |
Environment override name |
tier |
string |
Tier override name |
history |
Array<{ role, content }> |
Conversation history |
toolRegistry |
Record<string, unknown> |
Tool definitions for resolving string tool references |
strict |
boolean |
Fail on missing variables (default false) |
openaiResponses |
object |
Optional Responses API extras (previous_response_id, conversation, instructions, parallel_tool_calls, max_tool_calls, store, metadata, include, background) |
Either path or source must be provided.
interface RenderResult {
resolved: ResolvedPromptAsset; // Fully resolved asset
request?: ProviderRequest; // { body, provider, model } when rendering continues
returnMessage?: string; // Short-circuit message from context validation when configured
warnings: string[]; // Non-fatal provider and render-time warnings
}warnings may include provider adapter warnings and render-time POK030 context size warnings when configured to be included in results.
If a context validator fails and that validator declares return_message, renderPrompt() returns returnMessage and omits request instead of throwing.
Load a prompt asset from compiled or source (based on mode). Returns a PromptAsset.
const asset = await kit.loadPrompt('support/reply');Load, resolve includes, and apply overrides. Returns a ResolvedPromptAsset.
const resolved = await kit.resolvePrompt('support/reply', {
environment: 'dev',
tier: 'pro',
});Validate a prompt file. Returns a PromptValidationResult.
const result = await kit.validatePrompt('support/reply');
// { valid: boolean, errors: ValidationError[], warnings: ValidationError[] }validatePrompt() covers schema, include-graph, variable declaration issues, and context regex compilation. Render-time context size warnings are produced by renderPrompt(), not validation.
Clear the internal LRU cache.
kit.clearCache();All core functions are available as standalone imports for use without a PromptOpsKit instance:
import {
parsePrompt,
loadPromptFile,
extractSections,
interpolate,
extractVariables,
resolveIncludes,
applyOverrides,
validateAsset,
validateAssetWithIncludes,
getAdapter,
} from 'promptopskit';Parse a prompt Markdown string into a validated PromptAsset.
const { asset, raw } = parsePrompt(markdownString, '/path/to/file.md');
// asset: PromptAsset — validated and structured
// raw.frontMatter: Record<string, unknown> — original YAML keys
// raw.body: string — markdown bodyLoad a prompt from disk, parse it, and apply inherited defaults.md values.
const { asset } = await loadPromptFile('/path/to/prompts/support/reply.md', {
defaultsRoot: '/path/to/prompts',
});options.defaultsRoot (optional) limits defaults discovery to a specific directory tree. When omitted, defaults to the prompt file's own directory (only the local defaults.md is checked). Pass the prompts root directory to enable full ancestor traversal.
Note:
includesare resolved withparsePrompt, notloadPromptFile, so included files do not inherit folder defaults. This prevents double-applying system instructions.
Replace {{ variable }} placeholders with values.
const result = interpolate('Hello {{ name }}!', { name: 'World' });
// 'Hello World!'
// Strict mode throws on missing variables
interpolate('{{ missing }}', {}, { strict: true });
// Error: Missing required variable: "missing"Extract all variable names from a template string.
const vars = extractVariables('{{ name }} works at {{ company }}');
// ['name', 'company']Resolve includes by reading and inlining referenced files.
const resolved = await resolveIncludes(asset, '/path/to/prompt.md');Apply environment, tier, and runtime overrides.
const result = applyOverrides(asset, {
environment: 'dev',
tier: 'pro',
runtime: { model: 'gpt-5.4-mini' },
});Validate a parsed prompt asset.
const result = validateAsset(asset, ['id', 'schema_version', 'model'], 'hello.md');
// { valid: boolean, errors: ValidationError[], warnings: ValidationError[] }validateAsset() reports malformed allow_regex and deny_regex values before runtime, including the prompt id, variable name, field name, and raw configured value in the error message.
Validate a prompt asset including its include graph (checks for missing files and circular includes).
const result = await validateAssetWithIncludes(asset, '/path/to/prompt.md', ['id', 'model']);Get a provider adapter by name.
const adapter = getAdapter('openai');
const validation = adapter.validate(resolvedAsset, { environment: 'dev' });
const request = adapter.render(resolvedAsset, {
environment: 'dev',
tier: 'pro',
variables: { name: 'World' },
});RuntimeRenderOptions for direct adapter rendering supports environment, tier, runtime, variables, onContextOverflow, history, toolRegistry, and strict.
A convenience wrapper that creates a temporary PromptOpsKit instance:
import { renderPrompt } from 'promptopskit';
const result = await renderPrompt({
source: '---\nid: inline\nschema_version: 1\n---\n\nHello {{ name }}!',
provider: 'openai',
variables: { name: 'World' },
sourceDir: './prompts', // defaults to ./prompts
warnings: { contextSize: 'result-only' },
});Key types exported from promptopskit:
import type {
PromptAsset,
ResolvedPromptAsset,
ProviderInlinePromptSource,
ProviderPromptInput,
ProviderPromptLookup,
ProviderRequest,
RuntimeRenderOptions,
ProviderAdapter,
ValidationResult,
PromptValidationResult,
ValidationError,
RenderedSections,
RenderOptions,
ParseResult,
OverrideOptions,
} from 'promptopskit';Provider helper types:
ProviderPromptLookup—{ path, sourceDir?, compiledDir?, mode?, cache? }for adapter-managed source or compiled lookupProviderInlinePromptSource—{ source }for adapter-managed inline prompt sourceProviderPromptInput— union ofResolvedPromptAsset,ProviderPromptLookup, andProviderInlinePromptSource