@bismawy/pi-auto-compat1.6.0
Automated model compat flags & context/metadata sync. In-process self-healing. Zero session restart. Patches models.json on session start, model select and file events.
Untested on omp
This is a pi package. No one has reported whether it works on omp yet. If you try it, add your result below.
Reports 0
No reports yet.
Readme
Auto Compat
Automated model compat flags. In-process self-healing. Zero session restart.

Overview
pi-auto-compat inspects active models and patches missing compatibility flags in models.json in-process.
- Auto-Heal: Patches missing flags on
session_start,model_select, andmodels.jsonfile events. - Metadata Sync: Probes each custom channel's
GET /modelsand syncs the realcontextWindow/maxTokens(a 1M-token model no longer runs on Pi's 128k default). Rejects unit anomalies, clamps an output cap to the window, and stamps every network value with provenance. - In-Process Refresh: Invokes
modelRegistry.refresh()immediately upon write without session restart. - Cache-Optimizer Parity: Mirrors 1-hour cache retention, adaptive generation, proxy anthropic cache control, and session affinity.
- Thinking Map Synthesis: Synthesizes the standard
{ low, medium, high, xhigh }thinkingLevelMaponly for reasoning models that declare none. - Thinking-Effort Probe: Discovers which
reasoning_effortnames a channel actually accepts (one tiny completion per level; 7 requests per model) and remaps the rejected ones to the nearest accepted value, so/thinkingnever sends a level the upstream 400s on. - Windows Lock Resilience: Wraps
writeStatsShardV7inpi-cache-optimizerwith retry and copy fallback against NTFSEPERM/EBUSY. - Credential-Safe: Touches only
compat,modelOverrides,thinkingLevelMap, and thecontextWindow/maxTokensmodel limits. API keys and base URLs are never modified.
Install
pi install npm:@bismawy/pi-auto-compat
To test locally without installing:
pi -e ./extensions/index.ts
Commands
| Command | Scope | Action |
|---|---|---|
/auto-compat |
Global | Audit active models, patch missing flags in models.json, force a full metadata re-probe, probe every thinking-effort level, and refresh the registry |
Notes:
- Zero-Config Background Run: Fixes are applied automatically on session launch and when switching models.
- Explicit Settings Honored: If you have explicitly configured a compat flag (even
false), pi-auto-compat will never overwrite it.
Architecture
Compatibility Rules
| Category | Conditions | Applied Flags |
|---|---|---|
| Universal Cache Retention | All models where unset (except built-in llama.cpp) | supportsLongCacheRetention: true (Anthropic & official OpenAI), false (third-party OpenAI-compatible) |
| Developer Role Opt-Out | Reasoning models on OpenAI-compatible channels except official OpenAI / OpenRouter | supportsDeveloperRole: false — sends the instruction prompt as system instead of developer, fixing routers that 400 on messages.0.role |
| Adaptive Generation | anthropic-messages + Opus/Sonnet ≥ 4.6, Fable ≥ 5, Kimi K3 |
forceAdaptiveThinking: true, allowEmptySignature: true (Kimi K3) |
| DeepSeek Reasoning | openai-completions / openai-responses matching DeepSeek |
requiresReasoningContentOnAssistantMessages: true, thinkingFormat: "deepseek", session affinity |
| Claude on Proxies | Claude models on OpenAI-compatible proxies | cacheControlFormat: "anthropic" |
| OpenAI-Compatible Proxies | Custom openai-completions endpoints |
sendSessionAffinityHeaders: true (when undefined) |
| Unmapped Reasoning | Reasoning models without declared thinking maps | Declares standard { low, medium, high, xhigh } thinkingLevelMap |
| Thinking Effort | Reasoning models on an OpenAI-compatible channel (not first-party / OpenRouter / llama.cpp, and expected to send reasoning_effort) |
Rejected levels are remapped to the nearest accepted value (up first, ties down), e.g. medium: "high" — discovered by probing, provenance-stamped, 24h TTL |
| Metadata Sync | Custom channels with a baseUrl exposing GET /models |
contextWindow from the widest context field; maxTokens from the output cap — network values only, provenance-stamped, anomaly-guarded |
Metadata Sync (contextWindow / maxTokens)
- Detection: Reads the first matching context field in priority order (
context_length,context_window,max_model_len,max_input_tokens, …) and the output cap (max_output_tokens,max_completion_tokens,max_tokens, …). A genericmax_tokensequal to the window is the context length, not an output cap. - Conservative: Rejects unit anomalies (a per-request number an order of magnitude below the current window); keeps a real API shrink but ignores noise. Output caps above the window are clamped to it.
- Provenance: Each network value is stamped in
pi-auto-compat-sync.json. A hand-edited value is detected as a manual override and never overwritten twice; a real API correction still applies. Flips both values at once (a manual lower output cap does not freeze the window). - TTL & Signature: Non-forced runs re-probe a channel only when its
baseUrl+ model-id signature changed or the 6-hour TTL expired;/auto-compatforces a full re-probe. - Credentials: Resolved from
models.json($ENV,!command, or literal) without logging. Unreachable channels are reported, never silently mis-detected.
Thinking-Effort Probe
- Why: Pi sends
thinkingLevelMap[level] ?? levelasreasoning_effort, so an unsupported level reaches the upstream and returns 400 — surfaced by routers as502 provider_errorwhen the body carries the hint (Enclave → Together rejectsmediumfordeepseek-v4.1-flash).GET /modelsdoes not advertise the accepted subset. - Discovery: One tiny completion per level (
max_tokens: 16, carrying the samethinking/reasoningpayload Pi would send) — 7 requests per model per probe. A level is only marked accepted on success; a 400 gets one confirmation retry, so a single upstream flake cannot rewrite the map. - Remap: A rejected level maps to the nearest accepted value in Pi's clamp order — up first, ties down (a failed request is worse than a slightly weaker answer). Pi assumes support for unmapped levels, so identity mappings still have to be written once a sibling is dropped; the entry is only written when it carries information.
- Opt-in levels:
off,xhigh, andmaxare only adjusted where the model already declares them, and only when the probe tested the value it currently sends. A deliberate opt-out (null) stays an opt-out. - User wins: A map the user shaped deliberately (a remap, or an explicit
null) is skipped and not even probed — not by the background pass, not by/auto-compat. Delete the entry to opt back in. - Provenance & TTL: Outcomes are stamped in
pi-auto-compat-sync.jsontogether with the effective map. Untouched models are re-probed after 24 hours, or immediately when the model's map no longer matches the recorded one. A channel that answered nothing is retried after 1 hour instead. - Triggers:
session_start,model_select, themodels.jsonwatcher (/better-custom,/login), and a reactive pass onmessage_endthat probes the model from the registry when an inference error carries the parameter-rejection hint./auto-compatforces a full re-probe. - Scope:
reasoningmodels onopenai-completions/openai-responseschannels that are not first-party (official OpenAI, OpenRouter, built-in llama.cpp) and are expected to sendreasoning_effort—supportsReasoningEffort: falseand theopenrouter/chat-template/qwen-chat-template/ant-lingformats are excluded.
Placement Strategy
- Provider Settings: Writes channel-wide parameters (session affinity, cache retention) directly to provider blocks.
- Model Overrides: Writes model-specific flags under
models[].compat, ormodelOverridesfor dynamic extension providers.
Windows Resilience
- Shard Lock Protection: Wraps
writeStatsShardV7inpi-cache-optimizerwithsafeAtomicRename(retry with backoff + copy fallback) against NTFSEPERM/EBUSY. - Orphan Cleanup: Unlinks stale
.tmpfiles inpi-cache-optimizer-stats.d/shards/automatically on session start.
Safety & Backups
- Credential-Safe: Only writes
compat,modelOverrides,thinkingLevelMap, andcontextWindow/maxTokens. The metadata probe readsbaseUrlandapiKeyfrommodels.jsonto authenticate; neither is ever written back or logged. - Rotating Backups: Retains up to 3 timestamped backups (
models.json.bak-auto-compat-*) before saving.
Development
npm test # Run the unit suites: compat flags, placement, metadata sync, thinking effort, Windows patch
npm run dev # Launch local Pi instance with auto-compat active
License
Distributed under the MIT license.