🧠 omp Integration

All text and image generation goes through the locally installed omp binary. Since D-479g, text calls inherit the host’s global default with no app model pin; PWIZ_OMP_TEXT_MODEL is an optional explicit operator override, unset in production unit/env files. Timings distinguish requested (host default normally) from the resolved provider/model reported by the final OMP message, or unknown. Image calls use the configured image tool. The app does not add provider SDKs, API keys or a user-facing model selector; a target-platform setting changes wording only.

Non-negotiable invariants

  • binary:
    • default: the server uses the hardcoded operator install path, written here as $HOME/.local/bin/omp
    • override: OMP_BIN
    • never import the stale source checkout
  • model:
    • D-479g removes the earlier built-in xai-oauth/grok-4.7 default and forced --model; with an unset/empty PWIZ_OMP_TEXT_MODEL, text calls use OMP’s host default
    • only an explicitly supplied non-empty operator override adds --model; none is configured in the production unit/env files
    • OMP-reported final assistant provider/model is recorded as resolved, not inferred from the requested route; absent metadata remains unknown
  • process context:
    • runtime app root: $HOME/dev/pwiz
    • scratch directory: $HOME/dev/pwiz/data/omp-scratch
    • pass --cwd "$HOME/dev/pwiz/data/omp-scratch"
    • image overlay config: $HOME/dev/pwiz/server/omp-image-overlay.yml
    • disable sessions, skills, rules, extensions, LSP, and title updates
    • text mode also disables tools
  • 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 omp child processes
    • later requests wait in queue
  • 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.

PWIZ_ROOT="$HOME/dev/pwiz"
OMP_BIN="${OMP_BIN:-$HOME/.local/bin/omp}"
mkdir -p "$PWIZ_ROOT/data/omp-scratch"
SYSTEM_PROMPT="$(mktemp "$PWIZ_ROOT/data/omp-scratch/.omp-system-prompt.XXXXXX.txt")"
printf '%s\n' 'Reply briefly and exactly.' > "$SYSTEM_PROMPT"
 
"$OMP_BIN" -p \
  --no-session \
  --no-tools \
  --no-skills \
  --no-rules \
  --no-extensions \
  --no-lsp \
  --no-title \
  --cwd "$PWIZ_ROOT/data/omp-scratch" \
  --system-prompt "$SYSTEM_PROMPT" \
  'user: say ok'
 
rm -f "$SYSTEM_PROMPT"
  • message flattening:
    • one turn: role: content
    • multiple turns:
      • ### Previous turns
      • prior role: content lines
      • ### Current request
      • final role: content
  • JSON mode:
    • the server adds an object-only instruction unless the system already demands valid JSON
    • leading code fences are stripped, then the reply is parsed as a non-array object
    • local repair strips surrounding prose, extracts a balanced object and drops trailing commas before the existing single rerun
    • kind: "ideas" additionally requires {ideas: [...]} with 5 or 6 title/description entries; both direct parsing and local repair validate this shared caller contract
    • invalid output after the rerun returns 502; provider failures return an error without JSON repair/rerun
  • 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, system }) enables the generate_image tool for this run only. The user’s global omp config is not edited. Cover and wizard-image flows may pass an interpolated admin prompt as system; when system is absent, the bridge uses the safe built-in default.

generate_image:
  enabled: true
PWIZ_ROOT="$HOME/dev/pwiz"
OMP_BIN="${OMP_BIN:-$HOME/.local/bin/omp}"
mkdir -p "$PWIZ_ROOT/data/omp-scratch"
SYSTEM_PROMPT="$(mktemp "$PWIZ_ROOT/data/omp-scratch/.omp-system-prompt.XXXXXX.txt")"
printf '%s\n' 'You generate images. Call the generate_image tool exactly once, using the user message as the subject. Then reply with only DONE.' > "$SYSTEM_PROMPT"
 
"$OMP_BIN" --mode json \
  --no-session \
  --no-skills \
  --no-rules \
  --no-extensions \
  --no-lsp \
  --no-title \
  --auto-approve \
  --cwd "$PWIZ_ROOT/data/omp-scratch" \
  --config "$PWIZ_ROOT/server/omp-image-overlay.yml" \
  --tools generate_image \
  --system-prompt "$SYSTEM_PROMPT" \
  'a small purple wizard hat icon, flat vector. Aspect ratio: 1:1.'
 
rm -f "$SYSTEM_PROMPT"

System prompt default when no admin image prompt is supplied:

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:1
    • 3:4
    • 4:3
    • 9:16
    • 16:9
  • compatibility mapping:
    • archive square maps to 1:1
  • subject shaping:
    • append Aspect ratio: <value>. to the subject text
  • approval boundary:
    • --auto-approve is acceptable because --tools generate_image restricts 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.provider
    • result.details.model
  • file handling:
    • copy the temporary WebP to data/uploads/<uuid>.webp
    • return /uploads/<uuid>.webp
  • 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, requestId?, thoughtsTab? }
    • response: { content, timing }
    • successful text AI calls are stored in llm_logs (admin-only), including kind/template key, submitted context and final response
  • POST /api/ai/image:
    • body: { subject, aspectRatio, kind, system }
    • system is optional; absent values use the built-in safe image system prompt
    • response: { url, provider, model }
    • successful image AI calls are stored in llm_logs (admin-only) through the same server-side logging path

Actual calls and telemetry boundary

Architect, Specialist and Formatter are concatenated roles in one generation system prompt, not three independently running agents. Normally one text call produces the sequence; malformed JSON can use the existing rerun. Optional Mermaid generation is a separate blocking text call, and enhancement, brainstorm, ideas and images have their own calls. Agentic Trace records local prompt fragments, not independent agent execution.

Content crosses from the app into OMP’s configured generation route; this is not fully local AI. Text execution disables tools, skills, rules, extensions and sessions. No app-owned external analytics sender was found in this code path; OMP-core behavior, upstream telemetry and provider retention were not audited. See api > Logging, retention and public storage for stored content and the absence of an app TTL.

Fidelity gaps versus archive behavior

  • temperature and max tokens:
    • archive calls supplied temperature and max_tokens
    • installed omp CLI 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
  • wizard transparency:
    • archive requested transparent wizard avatars
    • generate_image exposes 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 omp exit returns 502
    • invalid JSON after retry returns 502
    • timeout returns 504
  • image generation failure:
    • invalid ratio returns 400
    • non-zero omp exit 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 🔒 Private runbook (login) for live smoke checks.