# ─── Proxy Server ────────────────────────────────────────────────────────────── # Port the proxy listens on MOEPT_PORT=8080 # ─── Lemonade / Backend Server ──────────────────────────────────────────────── # Base URL of the OpenAI-compatible chat-completions server API MOEPT_SERVER__URL=http://localhost:13305/api/v1 # API key forwarded to the LLM server. MOEPT_SERVER__LLM_API_KEY=lemonade # Base URL of the OpenAI-compatible embedding server. # Defaults to the same API as the chat server; set separately if embeddings are hosted elsewhere. MOEPT_SERVER__EMBED_URL=http://localhost:13305/api/v1 # API key forwarded to the embeddings server. MOEPT_SERVER__EMBED_API_KEY=lemonade # LLM model identifier used for chat completions MOEPT_SERVER__LLM_MODEL=Qwen3.6-35B-A3B-MTP-GGUF # Embedding model identifier used for semantic search MOEPT_SERVER__EMBED_MODEL=embed-gemma-300m-FLM # Tokenizer used for budget/counting. 'auto' tries a LOCAL Qwen HF tokenizer and # only falls back to tiktoken cl100k_base (GPT-4 BPE, approximate for Qwen) if # none is present. For exact Qwen counts, set this to a HuggingFace repo id or a # local path to the model's tokenizer.json, e.g.: # MOEPT_SERVER__TOKENIZER=Qwen/Qwen2.5-Coder-32B-Instruct # MOEPT_SERVER__TOKENIZER=/models/qwen3.6-35b-a3b-mtp/tokenizer.json # Runtime calibration from the backend's real prompt_tokens still corrects the # residual ratio each turn regardless of this setting. MOEPT_SERVER__TOKENIZER=auto # Request timeout in seconds for long context conversations MOEPT_SERVER__TIMEOUT=300.0 # ─── Agentic Loop Tuning ────────────────────────────────────────────────────── # Last N user-assistant pairs kept in full detail for immediate reasoning context. # Older complete turns are evicted from the top; middle-history content is never mutated. MOEPT_AGENTIC__KEEP_FULL_STEPS=3 # Steps before this index are archived/compressed MOEPT_AGENTIC__ARCHIVE_THRESHOLD=3 # Character fallback cap for optimized context; token budget takes precedence when positive. # Should be a meaningful fraction of the backend window, not ~1% of it. MOEPT_AGENTIC__MAX_OPTIMIZED_CHARS=400000 # Token budget cap. With the adaptive budget ON this is the BASE / last-resort # floor; the effective budget grows with the conversation horizon up to a fraction # of the backend window (see adaptive flags below). With adaptive OFF it is the # fixed hard cap on optimized context. MOEPT_AGENTIC__MAX_OPTIMIZED_TOKENS=100000 # Adaptive budget (review §4.2.2): replace the fixed cap with a GROWING ceiling so # the immutable zones always fit (reserved < budget), the eviction governors stop # fighting, and the rolling-summary fold fires far less often — raising prefix-cache # reuse and retaining more verbatim context. Disable to restore the legacy fixed cap. MOEPT_AGENTIC__ADAPTIVE_BUDGET_ENABLED=true # Tokens added to the adaptive budget per conversation turn (horizon term). MOEPT_AGENTIC__ADAPTIVE_HORIZON_GROWTH_TOKENS=800 # Ceiling on the adaptive budget as a fraction of the live backend context window # (0.15 = 15%). Lets a long session grow toward a sane fraction of the window # instead of over-compacting against an idle one. MOEPT_AGENTIC__ADAPTIVE_WINDOW_FRACTION=0.15 # Task-complexity term of the adaptive budget: the budget grows by this fraction of # the code tokens in the current request, so a code-heavy turn keeps more verbatim # code (and folds less often). 0 disables the term. MOEPT_AGENTIC__ADAPTIVE_CODE_DENSITY_FACTOR=0.25 # Hard ceiling on per-turn OPTIMIZED-context GROWTH (tokens). Bounds one turn from # jumping to the full budget and forcing a mid-body rewrite that breaks prefix-cache # reuse. 0 disables the cap. MOEPT_AGENTIC__MAX_CONTEXT_GROWTH_PER_TURN=1500 # Hard floor on per-turn OPTIMIZED-context SHRINK (tokens). Symmetric to the growth # ceiling: bounds one-shot front-eviction so the backend's cached KV for the body # head stays valid. 0 = AUTO (derive from current_size * shrink_context_fraction, # floored by max_context_growth_per_turn and shrink_min_tokens). MOEPT_AGENTIC__MAX_CONTEXT_SHRINK_PER_TURN=0 # Fraction of the CURRENT lean context size used to derive the AUTO per-turn shrink # cap when max_context_shrink_per_turn=0. The cap scales with what we are actually # carrying (a lean context), not the model's full window. MOEPT_AGENTIC__SHRINK_CONTEXT_FRACTION=0.15 # Absolute floor on the AUTO per-turn shrink cap (tokens). Guarantees even a tiny # lean context still has a bounded, non-trivial shrink rate. MOEPT_AGENTIC__SHRINK_MIN_TOKENS=800 # Append the quality anchor (original request + accumulated constraints) to the # trailing volatile turn on over-budget turns. The anchor is a redundant 3rd copy # of the original request (also in the frozen prefix + rolling-summary head); set # false to drop it (review §4.2.6) once benchmark quality confirms no regression. MOEPT_AGENTIC__VOLATILE_QUALITY_ANCHOR_ENABLED=true # Ratio of max tokens where proactive top-only trimming starts (base default; # the balanced profile raises this to 0.6) MOEPT_AGENTIC__PROACTIVE_TRIM_RATIO=0.45 # Ratio of max tokens where compaction/compression starts (base default; # the balanced profile raises this to 0.85) MOEPT_AGENTIC__COMPACTION_TRIGGER_RATIO=0.75 # Keep full thinking content for last N steps MOEPT_AGENTIC__THINKING_PROTECT_RECENT=2 # Session inactivity timeout in seconds before cleanup MOEPT_AGENTIC__SESSION_TIMEOUT=3600 # Hard cap on concurrently tracked sessions (LRU eviction over the cap; 0 disables) MOEPT_AGENTIC__MAX_SESSIONS=256 # Use token-based budget enforcement MOEPT_AGENTIC__USE_TOKEN_BUDGET=true # Bypass expensive transformations for contexts already under budget MOEPT_AGENTIC__FAST_PATH_ENABLED=true # Enable state-based RAG injection for long/over-budget sessions MOEPT_AGENTIC__RAG_ENABLED=true # Run tree-sitter code-block optimization (chunk dedup); budget-gated so it # only fires when the context exceeds the proactive trim threshold. MOEPT_AGENTIC__OPTIMIZE_CODE_BLOCKS=true # Compress large code blocks to skeletons under context pressure. Base default is # true, but the balanced quality profile (the default) sets it false so the model # keeps full code to edit; only the aggressive profile enables skeletonization. MOEPT_AGENTIC__CODE_SKELETON_ENABLED=false # Max code-signature lines carried forward into the evicted-turn code ledger. When # front-eviction drops a code-bearing turn, its signatures accumulate into a compact # [Evicted-turn code index] system message so the model keeps code awareness. MOEPT_AGENTIC__CODE_LEDGER_MAX_SIGS=40 # Apply task-template specialization to rewrite the user prompt (OFF: risks # changing the client's exact wording in agentic coding) MOEPT_AGENTIC__PROMPT_TEMPLATE_ENABLED=false # Replace full re-read file bodies with a unified diff vs the prior snapshot. # ON by default, but injection is decided dynamically per re-read: it only fires # when the prior version is already in context (so the model can apply the diff); # on first read or when the prior was evicted, the full code is kept verbatim. MOEPT_AGENTIC__DELTA_ENCODE_INJECT=true # Inject reasoning scaffolding into user messages MOEPT_AGENTIC__REASONING_PRESEED_ENABLED=false # Boundary-compress large user code pastes (file dumps pasted into a user turn). # Same cheap transforms as tool-output compression; frozen into the stable prefix # so the backend prefix cache stays valid. Disable only if you need verbatim pastes. MOEPT_AGENTIC__USER_PASTE_COMPRESSION_ENABLED=true MOEPT_AGENTIC__USER_PASTE_COMPRESSION_MAX_CHARS=4000 # Reversible compression (review §4.1.2 / Forward plan B1). When a tool output is # compressed, keep the original in a per-session content-addressed store and embed # its handle in the placeholder, so it is retrievable (GET # /v1/agent/sessions/{id}/content/{handle}) instead of lost forever. OFF by default: # the model-facing expand(id) retrieval tool is not yet wired into the protocol. MOEPT_AGENTIC__REVERSIBLE_COMPRESSION_ENABLED=false MOEPT_AGENTIC__REVERSIBLE_COMPRESSION_MIN_CHARS=2000 # Whole-file tool-output dedup (review §4.1.3/§4.5.2 / Forward plan B2). Keep the # FIRST occurrence of a repeated tool output (e.g. a file read) full and collapse # later identical occurrences to a handle reference (original retained in the # per-session content store). Stateless + idempotent => cache-stable. OFF by default: # it rewrites context and should be benchmarked before enabling. MOEPT_AGENTIC__TOOL_OUTPUT_DEDUP_ENABLED=false MOEPT_AGENTIC__TOOL_OUTPUT_DEDUP_MIN_CHARS=200 # Query-aware syntactic code slicing (review §4.5.3 / Forward plan B4). For a message # containing fenced code, keep the imports header plus the top-level definitions named # in the session's original request, collapsing the rest (tree-sitter). Strictly # fail-open + never-expands + idempotent => cache-stable. OFF by default: it is # context-dependent and should be benchmarked before enabling. MOEPT_AGENTIC__CODE_SLICING_ENABLED=false # Live config reload without restart (review §11.5 / C9). SIGUSR2 or # POST /v1/config/reload re-reads AppConfig from the environment. New sessions # pick up the new config; existing sessions keep their optimizer (no mid-turn race). MOEPT_AGENTIC__CONFIG_HOT_RELOAD_ENABLED=true # ─── Code Chunking ───────────────────────────────────────────────────────────── # Maximum characters per code chunk for semantic indexing MOEPT_CODE_CHUNKING__CHUNK_MAX_CHARS=1500 # Number of top relevant chunks to retrieve during optimization MOEPT_CODE_CHUNKING__TOP_K_CHUNKS=5 # Minimum embedding similarity score to include a chunk (0.2 drops low-relevance chunks) MOEPT_CODE_CHUNKING__MIN_CHUNK_SCORE=0.2 # Embedding vector dimension MOEPT_CODE_CHUNKING__EMBEDDING_DIM=384 # ─── Cache ───────────────────────────────────────────────────────────────────── # Maximum number of embeddings to keep in memory cache MOEPT_CACHE__EMBED_CACHE_MAX=512 # Path to LanceDB vector database data directory MOEPT_CACHE__LANCEDB_PATH=~/.moeptimizer/lancedb # ─── Speculative Decoding ───────────────────────────────────────────────────── # NOTE: client-proxy speculative decoding is non-functional (review03.md §2.1); # the only effective path is a backend with native MTP support, enabled via # MOEPT_V050__NATIVE_MTP_PASSTHROUGH (auto-detected by MOEPT_V050__NATIVE_MTP_AUTODETECT). # The old MOEPT_SPECULATIVE__* variables were removed. # ─── v0.5.x Optimizations ───────────────────────────────────────────────────── # Static Prefix KV-Cache Reuse MOEPT_V050__STATIC_PREFIX_KV_ENABLED=true MOEPT_V050__STATIC_PREFIX_KV_MAX_ENTRIES=64 # Token-Aware Truncation MOEPT_V050__TOKEN_AWARE_TRUNCATION_ENABLED=true # Chunk Fingerprinting & Reuse MOEPT_V050__CHUNK_FINGERPRINT_ENABLED=true MOEPT_V050__CHUNK_FINGERPRINT_MAX_ENTRIES=2048 # Embedding batching MOEPT_V050__EMBEDDING_BATCH_SIZE=32 # Lightweight Hit-Prediction Model MOEPT_V050__HIT_PREDICTION_ENABLED=true MOEPT_V050__HIT_PREDICTION_RETRAIN_THRESHOLD=50 # Hierarchical Summarization # The cache-stable rolling-summary path (cache_stable_summary_enabled) is the SAFE # summarization mode: older dynamic turns are folded into an append-only block # placed right after the frozen prefix and protected from front-eviction, so the # backend's prefix cache stays valid. It only fires under budget pressure with # cache_stable_mode on. Enabled by default (review §1/§3/§5, #7). The legacy # hierarchical_summary_enabled flag is an alias for the same safe path. MOEPT_V050__CACHE_STABLE_SUMMARY_ENABLED=true MOEPT_V050__HIERARCHICAL_SUMMARY_ENABLED=false MOEPT_V050__HIERARCHICAL_SUMMARY_MAX_FULL_TURNS=5 # DRIFT fold margin: the live zone may drift this many turns past the keep window # before a batch fold pulls it back. 0 = use the keep window. Larger => rarer folds # (better prefix-cache reuse) but a larger context between folds. Only used when # FOLD_WINDOW_FRACTION is 0. MOEPT_V050__FOLD_MARGIN_TURNS=0 # Space-based folding (compaction-geometry redesign, review §4.7 / Forward plan # A1-lite). When > 0, the turn-count DRIFT trigger is disabled and the rolling summary # folds only once the context exceeds this fraction of the live backend window — so on # a huge window the conversation is near append-only and cache-breaking folds become # rare/absent (at low utilization append-and-reuse beats compact-and-break for TTFT). # Default 0.25 = zero prefix breaks in the opencode/30 dry-run at ~5% of a 262K window, # with folds still kicking in near ~65K for long sessions. 0 = keep turn-count folding. MOEPT_V050__FOLD_WINDOW_FRACTION=0.25 # Delta-Encoding of Code MOEPT_V050__DELTA_ENCODING_ENABLED=true MOEPT_V050__DELTA_ENCODING_MAX_SNAPSHOTS=100 # Async I/O for Heavy Stages MOEPT_V050__ASYNC_IO_ENABLED=true MOEPT_V050__ASYNC_IO_MAX_THREAD_WORKERS=4 MOEPT_V050__ASYNC_IO_MAX_CONCURRENCY=16 # ─── Prefix-Cache Reuse & Native MTP (target: llama.cpp / Qwen3-MTP) ────────── # These are the settings that make the backend actually reuse the conversation # prefix across turns (the "cached_tokens" signal) and use the model's own MTP # speculative decoding. By default the proxy AUTO-DETECTS what the live backend # supports (per active device, NPU<->GPU aware) and enables the right features # without manual flags; the explicit flags below are force-on overrides. # Live, device-aware capability auto-detection. When on (default), the proxy # probes the backend's own metadata (/health device + backend_url, native /slots, # native /tokenize, model checkpoint/labels) on a TTL and drives slot pinning, # MTP passthrough, and tokenizer selection from what the ACTIVE device actually # supports. Best-effort: probe failures never block startup or requests. MOEPT_V050__CAPABILITY_AUTODETECT=true # How long (seconds) a capability snapshot is trusted before a live re-check. # Re-checks are cheap (cached between TTLs) and let device hot-swaps be picked up # without restarting the proxy. MOEPT_V050__CAPABILITY_PROBE_TTL_SECONDS=30.0 # Prefer the backend's exact native /tokenize for authoritative token counts when # the active device supports it (gated behind fingerprint caches; never on the # per-fragment hot path). Falls back to the local/tiktoken counter otherwise. MOEPT_V050__REMOTE_TOKENIZE_ENABLED=true # Force-on override for slot pinning. Leave FALSE to let auto-detect enable it # only on devices that expose llama.cpp `/slots` (e.g. GPU); setting it true pins # a session `id_slot` unconditionally, which is wrong for a device (e.g. NPU) that # has no slots. id_slot is sent via extra_body so non-llama.cpp backends ignore it. MOEPT_V050__SLOT_PINNING_ENABLED=false # Freeze a stable prefix block (system + first user + early turns) verbatim and # never front-evict from it, so the frozen prefix stays byte-identical across # turns and the backend's automatic prefix cache reuses it. MOEPT_V050__CACHE_STABLE_MODE=true # Number of early complete user-assistant turns (after the first user message) # to freeze verbatim as part of the stable prefix when cache_stable_mode is on. MOEPT_V050__FROZEN_PREFIX_TURNS=2 # Force-on override for MTP passthrough. Leave FALSE to let auto-detect enable it # from backend metadata (labels contains "mtp", a speculative slot, or # --spec-type ...mtp launch args); the chat-probe below is only a last-resort # fallback when metadata is inconclusive. MOEPT_V050__NATIVE_MTP_PASSTHROUGH=false # Last-resort chat-probe for native MTP when metadata was inconclusive. Best-effort: # a probe failure never blocks startup and leaves non-MTP backends untouched. MOEPT_V050__NATIVE_MTP_AUTODETECT=true