🧠 omp Integration
This is the load-bearing page for Prompt Wizard. All text and image generation goes through the locally installed omp binary using the user’s configured omp model roles and settings. The app must not add provider SDKs, API keys, direct provider endpoints, or app-level model selection.
Non-negotiable invariants
- binary:
- default: resolve
ompfrom the servicePATH - override:
OMP_BIN - never import the stale source checkout
- default: resolve
- model:
- do not pass
--model - omission is intentional
- the configured
defaultrole in the user’sompconfig selects provider and model
- do not pass
- process context:
- run in
data/omp-scratch - pass
--cwd data/omp-scratch - disable sessions, skills, rules, extensions, LSP, and title updates
- text mode also disables tools
- run in
- stdin:
- must be ignored
- inherited or piped-but-open stdin can hang print mode without a TTY
- output parsing:
- read stdout only for completion payloads
- log stderr but do not parse it as data
- stderr can contain routine status notes such as print-mode startup warnings and progress text
- concurrency:
- module semaphore: maximum two concurrent
ompchild processes - later requests wait in queue
- module semaphore: maximum two concurrent
- timeout:
- text: 240 seconds
- image: 420 seconds
- timeout kills the process tree and returns gateway timeout
Text command
ompText({ system, messages, json }) writes the system prompt to a temporary file, normalizes messages into one user prompt, and runs print mode.
omp -p \
--no-session \
--no-tools \
--no-skills \
--no-rules \
--no-extensions \
--no-lsp \
--no-title \
--cwd data/omp-scratch \
--system-prompt data/omp-scratch/.omp-system-prompt-<uuid>.txt \
'<user message>'- message flattening:
- one turn:
role: content - multiple turns:
### Previous turns- prior
role: contentlines ### Current request- final
role: content
- one turn:
- JSON mode:
- system prompt appends:
Respond with ONLY a single valid JSON object. No prose, no explanation, no markdown code fences. - leading JSON code fences are stripped defensively
- response is parsed with
JSON.parse - invalid JSON retries once with a stricter repair instruction
- second parse failure returns a 502 and exposes raw text for debugging
- system prompt appends:
- non-JSON mode:
- response content is trimmed stdout
- measured contract from plan:
- small text generation: approximately 18 to 21 seconds
Image command
ompImage({ subject, aspectRatio }) enables the generate_image tool for this run only. The user’s global omp config is not edited.
generate_image:
enabled: trueomp --mode json \
--no-session \
--no-skills \
--no-rules \
--no-extensions \
--no-lsp \
--no-title \
--auto-approve \
--cwd data/omp-scratch \
--config server/omp-image-overlay.yml \
--tools generate_image \
--system-prompt data/omp-scratch/.omp-system-prompt-<uuid>.txt \
'<subject>'System prompt:
You generate images. Call the generate_image tool exactly once, using the user message as the subject. Then reply with only DONE.- allowed aspect ratios:
1:13:44:39:1616:9
- compatibility mapping:
- archive
squaremaps to1:1
- archive
- subject shaping:
- append
Aspect ratio: <value>.to the subject text
- append
- approval boundary:
--auto-approveis acceptable because--tools generate_imagerestricts the session to the one image tool
- measured contract from plan:
- verified image run: approximately 43 seconds
- provider:
openai-codex - model:
gpt-5.6-sol - output: non-empty WebP copied into
data/uploads/
JSONL image event contract
The image command emits JSONL on stdout. The bridge scans events until it finds the tool completion event.
{
"type": "tool_execution_end",
"toolName": "generate_image",
"result": {
"details": {
"imagePaths": ["<temporary-webp-path>"],
"provider": "openai-codex",
"model": "gpt-5.6-sol"
}
}
}- required fields:
type === "tool_execution_end"toolName === "generate_image"result.details.imagePaths[0]result.details.providerresult.details.model
- file handling:
- copy the temporary WebP to
data/uploads/<uuid>.webp - return
/uploads/<uuid>.webp
- copy the temporary WebP to
- retry behavior:
- if no usable image event exists, retry once
- after the retry, return 502 with captured output context
API bridge
POST /api/ai/text:- body:
{ system, messages, json, kind, templateKey } - response:
{ content } - logs
kind,template_key,system_prompt,user_message, andresponse_json
- body:
POST /api/ai/image:- body:
{ subject, aspectRatio, kind } - response:
{ url, provider, model } - logs outcome through the same server-side logging path
- body:
Fidelity gaps versus archive behavior
- temperature and max tokens:
- archive calls supplied
temperatureandmax_tokens - installed
ompCLI has no such flags - the port does not fake them
- intent is encoded in the system prompt when needed:
- enhancement: precise and conservative wording
- idea generation: inventive and varied wording
- Mermaid: strict syntax and no improvisation
- archive calls supplied
- wizard transparency:
- archive requested transparent wizard avatars
generate_imageexposes no transparency parameter- verified image output used a solid background
- UI compensation is a circular mask with object-fit cover for wizard images
Failure policy
- text generation failure:
- non-zero
ompexit returns 502 - invalid JSON after retry returns 502
- timeout returns 504
- non-zero
- image generation failure:
- invalid ratio returns 400
- non-zero
ompexit returns 502 - missing image event after retry returns 502
- timeout returns 504
- no fabricated successes:
- archive fallback behavior could invent a fake project on JSON failure
- local bridge fails loudly instead
See api for route details and verification for live smoke checks.