Skip to content

Backend configuration and environment variables ​

Afterglow uses pydantic-settings to read process environment variables and .env in the backend working directory. This reference covers the supported Settings fields; the copyable template is backend/.env.example.

IMPORTANT

.env contains model keys, access passwords and identities. Never commit it. Fully restart after changes; uvicorn --reload does not rebuild cached Settings for .env edits.

For initial setup and everyday changes, use the backend configuration UI and setup wizard. Advanced users who manage files directly can use the configuration editor to generate a file locally in the browser. Templates are available with English comments or Chinese comments; their values are identical.

Loading rules ​

  • Process environment variables override .env; field names are case-insensitive and documented in uppercase.
  • .env and relative paths use the process working directory. Source instructions start with cd backend.
  • Unknown fields are ignored, so typos may not fail startup. Check this reference and .env.example.
  • “Default/example” below primarily reflects the template, not every code fallback. CHAT_MODEL is gpt-4o in the template and gpt-4o-mini without .env; LABEL_MAX_CONCURRENCY is 19 versus 1.
  • The configuration UI's field whitelist also comes from .env.example; update both when adding Settings fields.

These are backend/template defaults, not English wizard suggestions. The English wizard fills only unconfigured services with Google chat and OpenAI embeddings/auxiliary models, preserving saved values. See Configuration and privacy.

Important dependencies ​

  • RELATIONSHIP_TYPE=custom requires RELATIONSHIP_DESCRIPTION.
  • SELF_UID/FRIEND_UID accept comma-separated accounts belonging to the same person; do not merge different people.
  • Empty LIFE_* falls back to the main model; RESPONSE_POLICY_* falls back through Life.
  • Empty QUERY_REWRITE_*/SCHEDULE_* prefers Label, then Policy/Life/main.
  • Empty RERANK_* uses Policy/Life/main; adaptive chunking prefers Label, then Life/main.
  • VISION_ENABLED=true with CHAT_MODEL_SUPPORTS_VISION=false requires independent vision URL/key/model. Historical-image import always needs its independent VLM chain.
  • WEB_FETCH_ENABLED is subordinate to WEB_ACCESS_ENABLED.
  • WINDOW_OVERLAP must be less than WINDOW_SIZE; adaptive maximum characters must be at least the target.
  • Changing embedding model/dimension requires rebuilding existing vector tables/indexes.
  • WRITEBACK_VECTORIZE=false stores zero vectors; those Live messages do not take part in semantic recall.

Application, identity and relationship ​

VariableDefault/examplePurpose
XUWEN_LANGUAGEenBackend default and proactive-message language: en or zh-CN. CLI --language overrides command output; ordinary HTTP uses Accept-Language when supported. Proactive output always follows this setting. Restart after changes.
APP_NAMEAfterglowApplication name shown by the API and frontend.
APP_SLOGAN把曾经对你好的话,续成往后的陪伴Application subtitle; the existing configured/default text is preserved, not auto-translated.
APP_TIMEZONEAsia/ShanghaiIANA time zone supplied to models; affects real time, circadian patterns and schedules.
SELF_NAMEEmptyYour display name; required identity setting.
SELF_UIDEmptyYour platform UID; comma-separated accounts are supported.
FRIEND_NAMEEmptyTarget person's display name; required identity setting.
FRIEND_UIDEmptyTarget person's platform UID; comma-separated accounts are supported.
SELF_UIDSEmptyLegacy multiple-UID list; prefer comma-separated SELF_UID.
FRIEND_UIDSEmptyLegacy friend UID list; prefer FRIEND_UID.
SELF_ALIASESEmptyYour real name, usernames, nicknames and aliases, comma-separated.
FRIEND_ALIASESEmptyTarget person's aliases for cleaning, retrieval and prompt identity matching.
RELATIONSHIP_TYPEfriendOne of friend, lover, family, colleague, custom.
RELATIONSHIP_DESCRIPTIONEmptyFree-form relationship description; required for custom, optionally overrides defaults otherwise.
PERSONA_TEMPLATExuwenBuilt-in xuwen/friend/lover/family/colleague or an absolute custom .md.j2 path.
PROMPT_TEMPLATE_DIREmptyOverride the built-in template directory; empty means unset.

Main chat model ​

VariableDefault/examplePurpose
OPENAI_API_KEYEmptyMain chat model API key.
OPENAI_BASE_URLhttps://api.openai.com/v1OpenAI-compatible base URL; include the required provider path (such as /v1), without /chat/completions or /responses.
CHAT_MODELgpt-4oFinal reply model; code fallback without .env is gpt-4o-mini.
CHAT_API_PROTOCOLchat_completionsMain upstream protocol: chat_completions or responses; auxiliary models are unaffected.
CHAT_TIMEOUT_SECONDS60Main chat request timeout in seconds; greater than zero.
LLM_REASONING_EFFORTnullReasoning effort for compatible LLMs: none, low, medium, high, xhigh; null omits the field. Applies to chat, Life, policy, schedules, rewrite, adaptive chunking, labels and VLM; not embeddings/search/rerank.

Responses upstream sends store=false. Prompt caching is automatic only where supported and depends on provider, input length and exact prefix matching; protocol switching does not guarantee savings. Inspect model_chain[].response.usage.cached_tokens for reported hits. Life, policy, rewrite and LLM rerank still use Chat Completions.

Life-state model ​

VariableDefault/examplePurpose
LIFE_API_URLEmptyLife-state model base URL; empty reuses the main model.
LIFE_API_KEYEmptyLife-state API key; empty reuses the main model key.
LIFE_MODELEmptyModel maintaining life_state.json; empty uses CHAT_MODEL.
LIFE_TEMPERATURE0.35State JSON generation temperature, 0..2.
LIFE_MAX_TOKENS1500Maximum state JSON output tokens; allow room for reasoning on thinking models.
LIFE_TIMEOUT_SECONDS30Life-state request timeout in seconds; greater than zero.
LIFE_UPDATE_INTERVAL_MINUTES60Maximum interval before state reevaluation; 0 uses events and next_update_at only.
LIFE_MAX_REPLY_DELAY_SECONDS45Maximum suggested reply presentation delay.
LIFE_SLEEPING_MIN_REPLY_DELAY_SECONDS8Minimum fallback delay while sleeping; 0 disables it.
LIFE_MARKER_UPDATE_ENABLEDtrueNormalize and strip main-model <life-event> asynchronously; legacy <life-update> input is accepted. false still strips markers.

Response policy model ​

VariableDefault/examplePurpose
RESPONSE_POLICY_MODEL_ENABLEDfalseEnable bounded small-model refinement after rule-based policy.
RESPONSE_POLICY_API_URLEmptyPolicy model URL; empty reuses Life/main chain.
RESPONSE_POLICY_API_KEYEmptyPolicy API key; empty reuses Life/main chain.
RESPONSE_POLICY_MODELEmptyPolicy model name; empty reuses Life/main chain.
RESPONSE_POLICY_TEMPERATURE0.2Policy output temperature.
RESPONSE_POLICY_MAX_TOKENS260Maximum policy JSON output tokens.
RESPONSE_POLICY_TIMEOUT_SECONDS8Policy timeout in seconds; greater than zero.

Output, silence and Responses API ​

VariableDefault/examplePurpose
SILENCE_RESPONSE_SENTINEL[silent]Response content marker when the policy chooses silence.
SILENCE_FINISH_REASONsilencedsilenced or stop; use stop for strict OpenAI SDK enums.
AI_SILENCE_ENABLEDtrueAllow model-chosen silence in low-risk situations; does not disable rule-based safety silence.
RESPONSE_STREAMING_ENABLEDfalsefalse sends complete text over simulated SSE; true enables real streaming.
RESPONSES_STORE_CAPACITY512In-process LRU capacity mapping previous_response_id to conversation_id; lost on restart.

Long-conversation summaries ​

/v1/chat/completions and /v1/responses incrementally summarize older history when either threshold below is exceeded, retaining recent messages and the current input verbatim. Summaries use the LIFE_* model configuration and run alongside RAG, relationship memory and Life-state preparation. Initial or subsequent compression can add one or more model calls; later turns reuse the cache to reduce main-model input. Character counts are estimates, not model token counts.

VariableDefault/examplePurpose
CONVERSATION_SUMMARY_ENABLEDtrueEnable long-conversation summaries; disabling sends the full history.
CONVERSATION_SUMMARY_TRIGGER_CHARS16000Update when the combined character count of unsummarized history and existing summary exceeds this value.
CONVERSATION_SUMMARY_TRIGGER_MESSAGES40Update when unsummarized historical messages exceed this count.
CONVERSATION_SUMMARY_KEEP_MESSAGES16Maximum recent original messages retained after compression.
CONVERSATION_SUMMARY_RECENT_CHARS8000Recent-message character budget; keeps whole messages and tries to preserve question/answer pairs.
CONVERSATION_SUMMARY_MAX_CHARS3000Maximum summary characters.
CONVERSATION_SUMMARY_BATCH_CHARS12000New source characters per summary call; very long messages are processed in batches.
CONVERSATION_SUMMARY_TIMEOUT_SECONDS30Total timeout budget for a summary update; must be finite and positive.

Summaries are cached in PERSONA_DATA_DIR/conversation_summaries/ under hashed conversation IDs. A stable conversation_id (or caller_id fallback for Chat Completions) allows reuse across requests and restarts; without one, compression applies only to the supplied request. The cache verifies the original history prefix and rebuilds after edits or branching. Summaries provide conversation continuity: they do not rewrite original chats or become historical or long-term relationship facts. Failure stops the current request and preserves the previous cache. Existing Live writeback and relationship_memory.md continue independently.

The main prompt uses the final fused/reranked candidates; FINAL_CONTEXT_K controls their total. Built-in templates no longer repeat recent original messages in the system prompt; custom templates can still use recent_conversation.

Simulated Chat Completions SSE sends the complete reply before parsing schedules, then includes schedule_tasks in the closing chunk. This avoids delaying visible text without requiring token streaming. A single stream=false JSON response still waits for schedule extraction.

After all uploaded files have been stored, the configuration wizard attempts vector-index creation using LANCE_INDEX_MIN_ROWS. Failure produces a warning and preserves imported data; the task report lists index results for each table. Use uv run xuwen index --language en to create indexes for existing data or uv run xuwen optimize --language en to organize newly added data.

Proactive messages (experimental) ​

VariableDefault/examplePurpose
PROACTIVE_ENABLEDfalseRuntime proactive-message switch; currently not recommended for production.
PROACTIVE_LEARNING_MIN_GAP_MINUTES120Minimum silence gap used to recognize a new conversation opening.
PROACTIVE_SCORE_THRESHOLD0.55Minimum proactive trigger score.
PROACTIVE_CHECK_INTERVAL_SECONDS900Suggested polling interval for clients/schedulers.
PROACTIVE_MIN_IDLE_MINUTES180Minimum current-conversation idle time.
PROACTIVE_MAX_PER_DAY1Maximum proactive messages per conversation/day; 0 prohibits sending.
PROACTIVE_QUIET_HOURS00:00-08:30Quiet interval, including overnight ranges; empty disables it.
PROACTIVE_SKIP_WHEN_LIFE_BUSYtrueSkip initiation when Life state is busy, sleeping or away.
PROACTIVE_PROFILE_WINDOW_LIMIT10000Recent dialogue-window limit for profile fallback reconstruction.
PROACTIVE_AUDIT_MAX_RECORDS200In-memory proactive audit record window.
PROACTIVE_CONTEXT_CACHE_ENABLEDtrueKeep short recent context per caller/conversation.
PROACTIVE_CONTEXT_CACHE_MAX_ITEMS40Maximum cached messages per conversation.
PROACTIVE_CONTEXT_CACHE_PROMPT_ITEMS12Maximum cached messages injected into proactive generation.
PROACTIVE_CONTEXT_CACHE_MAX_TEXT_CHARS240Maximum characters per cached message.

Embeddings ​

VariableDefault/examplePurpose
EMBEDDING_API_URLhttps://maas-api.cn-huabei-1.xf-yun.com/v2OpenAI-compatible embedding base URL; include provider path, without /embeddings.
EMBEDDING_API_KEYEmptyEmbedding service key.
EMBEDDING_MODELxop3qwen8bembeddingEmbedding model name.
EMBEDDING_DIM4096Model output and LanceDB schema dimension; positive and identical. Rebuild existing vectors after changes; see Troubleshooting.
EMBEDDING_TIMEOUT_SECONDS60Embedding timeout in seconds; greater than zero.
EMBEDDING_INPUT_MODEarrayarray for standard batches, single for one input at a time.
EMBEDDING_BATCH_SIZE25Maximum texts per request; forced to 1 in single mode.
EMBEDDING_MAX_CONCURRENCY20Maximum in-flight HTTP requests; greater than zero.
EMBEDDING_MAX_REQUESTS_PER_MINUTE0Request cap per minute; 0 means no client-side cap.
EMBEDDING_INCLUDE_ENCODING_FORMATtrueSend encoding_format=float; disable for incompatible gateways.
EMBEDDING_SEND_DIMENSIONStrueSend dimensions; usually needed with MRL models.
EMBEDDING_RETRY_ATTEMPTS8Total attempts including the first request.
EMBEDDING_RETRY_MAX_WAIT_SECONDS10Maximum single exponential-backoff delay.
EMBEDDING_MAX_CONSECUTIVE_FAILURES3Consecutive exhausted requests before import treats failure as systemic and stops. Isolated failures skip their batch; rerunning fills gaps.

Vision and historical images ​

VariableDefault/examplePurpose
VISION_ENABLEDfalseEnable vision, including offline historical-image description.
CHAT_MODEL_SUPPORTS_VISIONfalseWhether the main model accepts OpenAI multimodal image content directly.
VISION_API_URLEmptyIndependent VLM base URL when the main model lacks vision; always needed for historical-image import.
VISION_API_KEYEmptyIndependent VLM key.
VISION_MODELqwen-vl-plusIndependent VLM model.
VISION_DESCRIBE_PROMPTDescribe the image objectively in one or two sentences. Do not invent details.Image-to-text instruction; a custom prompt is preserved as supplied.
VISION_TIMEOUT_SECONDS15Online chat/responses VLM description budget in seconds; positive. Does not change VisionClient's default 60-second HTTP timeout.
VISION_MAX_IMAGE_BYTES8388608Maximum bytes per image; default 8 MiB.
IMAGE_DATA_DIR.data/imagesDirectory for original images stored by SHA-256.

Web search and page fetching ​

VariableDefault/examplePurpose
WEB_ACCESS_ENABLEDfalseMaster web switch; false disables search and URL fetching.
WEB_SEARCH_PROVIDERtavilytavily or searxng.
WEB_SEARCH_BASE_URLhttps://api.tavily.comSearch service base URL.
WEB_SEARCH_API_KEYEmptySearch key; often unnecessary for SearXNG.
WEB_SEARCH_MAX_RESULTS5Requested result count; capped at 10 by code.
WEB_SEARCH_TIMEOUT_SECONDS8Search timeout in seconds; nonnegative.
WEB_SEARCH_LANGUAGEzh-CNSearch language hint; independent of backend output language.
WEB_FETCH_ENABLEDtrueFetch user-supplied public URLs; still requires web master switch.
WEB_FETCH_TIMEOUT_SECONDS8Per-page fetch timeout in seconds.
WEB_FETCH_MAX_URLS2Maximum fetched URLs per turn; capped at 5.
WEB_FETCH_MAX_REDIRECTS3Maximum redirects; capped at 10.
WEB_FETCH_MAX_BYTES524288Maximum page download size; capped at 2 MiB.
WEB_FETCH_MAX_CHARS6000Maximum page characters injected into the prompt; capped at 20000.

Storage, authentication, configuration UI and privacy ​

VariableDefault/examplePurpose
LANCE_DB_PATH.data/lancedbLanceDB directory.
LANCE_UPSERT_BATCH_SIZE128Rows per merge_insert batch; smaller reduces memory at a throughput cost. Does not fix vector dimension mismatches.
LANCE_INDEX_MIN_ROWS1000Rows required before automatic physical indexing; 0 disables it.
PERSONA_DATA_DIR.data/personaPersona, circadian, Life state and proactive profile directory.
ANALYSIS_DATA_DIR.data/analysisTimeline, personality, block cache and isolated experimental output directory.
API_AUTH_REQUIREDtrueRequire API authentication; /healthz remains public.
XUWEN_API_KEYEmptyBearer/x-api-key access password; any nonempty value always enables validation.
CONFIG_UI_ENABLEDfalseExplicitly mount the wizard; missing critical settings may also enable it automatically.
CONFIG_UI_PATH_PREFIX/configWizard path; must begin with / and avoid overlapping business API prefixes.
CONFIG_UI_LOCALHOST_ONLYtrueRestrict the configuration UI to local clients.
CONFIG_UI_SETUP_TOKENEmptySeparate setup token; empty generates a random session token at startup.
CONFIG_UI_UPLOADS_DIR.data/uploadsTemporary directory for wizard uploads.
ENABLE_PII_REDACTIONtrueRedact phone numbers, emails, identity documents, bank cards and IPs before storage.
PII_RULES_PATHEmptyCustom YAML/JSON redaction rules; empty means unset.

API authentication matrix ​

API_AUTH_REQUIREDXUWEN_API_KEYResult
falseEmptyOpen API access
falseNonemptyToken still required
trueEmptyBusiness routes return 503
trueNonemptyToken required normally

Chat splitting ​

VariableDefault/examplePurpose
CHUNKING_STRATEGYfixedfixed windows or adaptive topic-based splitting.
SESSION_GAP_MINUTES30Start a new session when adjacent messages exceed this gap.
WINDOW_SIZE12Messages per fixed multi-turn window.
WINDOW_OVERLAP3Overlap between windows; must be strictly less than WINDOW_SIZE.
SINGLE_CONTEXT_BEFORE6Context messages before a standalone friend message.
SINGLE_CONTEXT_AFTER2Context messages after a standalone friend message.
SINGLE_CONTEXT_MAX_CHARS600Adaptive-mode character budget for a message's embedding context.
ADAPTIVE_CHUNK_MODEL_ENABLEDfalseUse a small model for adaptive topic boundaries.
ADAPTIVE_CHUNK_API_URLEmptyChunking model URL; empty follows the fallback chain.
ADAPTIVE_CHUNK_API_KEYEmptyChunking model key.
ADAPTIVE_CHUNK_MODELEmptyChunking model name.
ADAPTIVE_CHUNK_TEMPERATURE0Boundary output temperature, 0..2.
ADAPTIVE_CHUNK_MAX_TOKENS900Maximum boundary JSON output tokens.
ADAPTIVE_CHUNK_TIMEOUT_SECONDS60Adaptive chunking timeout in seconds; positive.
ADAPTIVE_CHUNK_MAX_MESSAGES_PER_CALL80Maximum messages per boundary-model call.
ADAPTIVE_CHUNK_TARGET_CHARS700Target chunk characters.
ADAPTIVE_CHUNK_MAX_CHARS1400Hard character limit; at least ADAPTIVE_CHUNK_TARGET_CHARS.
ADAPTIVE_CHUNK_MIN_TURNS3Minimum turns per adaptive chunk.
ADAPTIVE_CHUNK_OVERLAP_TURNS2Overlap turns between adaptive chunks.
ADAPTIVE_CHUNK_SOFT_GAP_MINUTES8Soft time gap used to assist boundaries.
ADAPTIVE_CHUNK_MAX_CONCURRENCY0Positive explicitly sets concurrency; 0 uses Label concurrency or falls back to 4.
ADAPTIVE_CHUNK_CACHE_PATH.data/ingestion/adaptive_chunk_cache.jsonlModel boundary cache; resumed/repeated imports avoid calls on hits. Remove this file to reset it.

Relationship analysis ​

Analysis runs only when explicitly requested with xuwen analyze or the task API. Empty model fields fall back to chat. It can send all selected cleaned chats to the configured provider; review privacy.

VariableDefault/examplePurpose
ANALYSIS_API_URLEmptyOpenAI-compatible block-analysis URL; empty uses the main chat model.
ANALYSIS_API_KEYEmptyAnalysis key; empty uses the main chat key.
ANALYSIS_MODELEmptyAnalysis model; empty uses CHAT_MODEL.
ANALYSIS_FINAL_API_URLEmptyFinal relationship-stage, personality, Life and experimental merge URL; empty uses OPENAI_BASE_URL.
ANALYSIS_FINAL_API_KEYEmptyFinal model key; empty uses OPENAI_API_KEY.
ANALYSIS_FINAL_MODELEmptyFinal report/merge model, not a block-failure fallback; empty uses CHAT_MODEL.
ANALYSIS_TEMPERATURE0.3Block Map and monthly candidate-merge temperature, 0..2.
ANALYSIS_MAX_TOKENS6000Block/monthly structured-output token cap; too low can truncate JSON.
ANALYSIS_FINAL_MAX_TOKENS6000Final model merge/personality output token cap.
ANALYSIS_TIMEOUT_SECONDS120Per-request analysis timeout in seconds; positive.
ANALYSIS_BLOCK_CHAR_BUDGET10000Character budget per analysis block.
ANALYSIS_MAX_CONCURRENCY3Maximum in-flight block-analysis calls.
ANALYSIS_REQUEST_INTERVAL_SECONDS0Spacing between request starts; 0 adds no delay.
ANALYSIS_PROACTIVE_ENABLEDtrueDuring explicit analyze-proactive only, use the final model to explain opening motives/timing. Up to 12 openings per batch, with prior tail, opening and first response; stable IDs permit attribution reuse.
ANALYSIS_PROACTIVE_BATCH_SIZE4Openings per attribution batch, 1..12; smaller reduces JSON truncation risk.
ANALYSIS_PROACTIVE_MAX_CONCURRENCY4Concurrent proactive-attribution batches; at least 1.
ANALYSIS_LIFE_CONTEXT_ENABLEDfalseInject inferred sleep/meal/activity/availability patterns into Life decisions; real current time and today's state take precedence.
ANALYSIS_PERSONALITY_PROMPT_ENABLEDfalseProvide evidence-free regular personality context to the main chat model; independent of experimental switches.
ANALYSIS_EXPERIMENTAL_ENABLEDfalseAdd a separate experimental Map per block and a global merge; disabled by default.
ANALYSIS_EXPERIMENTAL_PROMPT_ENABLEDfalseGenerate an evidence-free, non-diagnostic summary for the main chat model; requires the experimental-generation switch too.

Hybrid retrieval ​

VariableDefault/examplePurpose
RESPONSE_PAIR_TOP_K24Response-pair vector recall count.
FRIEND_TOP_K32Standalone friend-message recall count.
WINDOW_TOP_K16Historical multi-turn window recall count.
HISTORY_IMAGE_TOP_K8Historical VLM image-description recall count.
LIVE_TOP_K12Live semantic recall count.
FINAL_CONTEXT_K12Maximum fused/reranked candidates injected into the main prompt.
RRF_K60Reciprocal Rank Fusion smoothing constant.
RETRIEVAL_TIMEOUT_SECONDS15Total retrieval budget, including rewrite, embeddings, recall and rerank; positive seconds.
RETRIEVAL_OVERFETCH3Per-path overfetch multiplier to compensate for filtering and deduplication.
RECENCY_HALF_LIFE_DAYS30Time-decay half-life in days.
RECENCY_MAX_BOOST0.15Maximum recency bonus.
WARMTH_BOOST0.12Warmth-score weighting coefficient.
LIVE_SOURCE_WEIGHT1.08Live source weight.
HISTORY_SOURCE_WEIGHT1.0Human text-history weight.
HISTORY_IMAGE_SOURCE_WEIGHT0.75Historical image-description fusion weight.
AI_GENERATED_SOURCE_WEIGHT0.25Trust weight for AI-generated live memory.
AI_GENERATED_LONG_TERM_ENABLEDfalseAllow AI replies in cross-conversation long-term retrieval.

Query Rewrite ​

VariableDefault/examplePurpose
QUERY_REWRITE_ENABLEDfalseRewrite short colloquial messages into retrieval-friendly queries.
QUERY_REWRITE_API_URLEmptyRewrite URL; empty prefers the Label chain.
QUERY_REWRITE_API_KEYEmptyRewrite model key.
QUERY_REWRITE_MODELEmptyRewrite model name.
QUERY_REWRITE_TEMPERATURE0Rewrite temperature, 0..2.
QUERY_REWRITE_MAX_TOKENS240Maximum rewrite output tokens.
QUERY_REWRITE_MAX_VARIANTS3Maximum variants including the original query.
QUERY_REWRITE_TIMEOUT_SECONDS30Rewrite timeout in seconds; positive.

LLM Rerank (experimental) ​

VariableDefault/examplePurpose
RERANK_ENABLEDfalseLLM semantic/style ranking of RRF candidates; usually unsuitable for weak small models.
RERANK_MODEautoOne of auto, always, never.
RERANK_API_URLEmptyLLM reranker URL; empty reuses Policy/Life/main model.
RERANK_API_KEYEmptyLLM reranker key.
RERANK_MODELEmptyLLM reranker model.
RERANK_TEMPERATURE0Ranking temperature, 0..2.
RERANK_MAX_TOKENS1200Maximum ranking JSON output tokens.
RERANK_TOP_K28Candidates supplied to LLM ranking.
RERANK_MIN_CANDIDATES16Minimum candidates before ranking runs.
RERANK_TIMEOUT_SECONDS30Ranking timeout; failures retain RRF order (fail open).
RERANK_WEIGHT0.55Mixing weight between LLM rank and original score, 0..1.
RERANK_MAX_SAME_SESSION3Maximum retained candidates from one session.

Cross-encoder Rerank ​

VariableDefault/examplePurpose
CROSS_RERANK_ENABLEDfalseUse a dedicated cross-encoder before optional LLM ranking.
CROSS_RERANK_PROTOCOLjinajina or dashscope request format.
CROSS_RERANK_API_URLEmptyRerank service base URL.
CROSS_RERANK_API_KEYEmptyRerank key.
CROSS_RERANK_MODELEmptyDedicated reranker name.
CROSS_RERANK_INPUT_K48Candidates passed from RRF to the cross-encoder.
CROSS_RERANK_TOP_N16Retained candidates; normally at least FINAL_CONTEXT_K.
CROSS_RERANK_TIMEOUT_SECONDS5Cross-encoder timeout in seconds; positive.

Schedule extraction ​

VariableDefault/examplePurpose
SCHEDULE_EXTRACT_ENABLEDfalseParse hidden <schedule-hint> output into structured tasks.
SCHEDULE_API_URLEmptyExtractor URL; empty follows Label-to-main fallback chain.
SCHEDULE_API_KEYEmptyExtractor key.
SCHEDULE_MODELEmptyExtractor model.
SCHEDULE_TEMPERATURE0.1Schedule JSON temperature.
SCHEDULE_MAX_TOKENS400Maximum extraction JSON tokens.
SCHEDULE_TIMEOUT_SECONDS60Extractor model timeout in seconds; positive.
SCHEDULE_MAX_HINTS_PER_TURN5Maximum parsed hints per turn.
SCHEDULE_EXTRACT_TIMEOUT_SECONDS10Whole-batch budget; failure returns no tasks without blocking the main reply.

Live writeback ​

VariableDefault/examplePurpose
WRITEBACK_ENABLEDtrueWrite new conversations to Live Memory.
WRITEBACK_QUEUE_SIZE1000Asynchronous writeback queue capacity.
WRITEBACK_BATCH_TURNS8Per-conversation turns accumulated before batch embedding/storage.
WRITEBACK_FLUSH_INTERVAL_SECONDS300Force flush after this idle interval.
WRITEBACK_VECTORIZEtrueGenerate vectors for Live messages; false stores zero vectors excluded from semantic recall.

Debugging and metrics ​

VariableDefault/examplePurpose
DEBUG_ENDPOINTS_ENABLEDfalseExpose /debug/*; disable after investigation.
DEBUG_MODEL_FULL_PAYLOADS_ENABLEDfalseRetain complete prompt/response text in debug records.
METRICS_CAPACITY100Ring-buffer capacity for each metric/model-chain record class.

Stickers ​

VariableDefault/examplePurpose
STICKER_DATA_DIR.data/stickersDirectory for sticker originals and index.json.
STICKER_MAX_FOR_AI30Maximum available stickers shown to the main model.
STICKER_MAX_IMAGE_BYTES2097152Maximum bytes per sticker; default 2 MiB.
STICKER_REJECT_RETRYtrueRetry once when a non-streaming reply selects a nonexistent sticker.

Semantic labels ​

VariableDefault/examplePurpose
LABELING_ENABLEDfalseEnable mood/topic/importance soft labels.
LABEL_API_URLhttps://open.bigmodel.cn/api/paas/v4OpenAI-compatible labeling URL.
LABEL_API_KEYEmptyLabeling key.
LABEL_MODELglm-4-flashLabeling model name.
LABEL_TIMEOUT_SECONDS30Labeling timeout in seconds; positive.
LABEL_BATCH_SIZE8Messages per labeling call.
LABEL_MAX_CONCURRENCY19Concurrent labeling batches; code fallback without .env is 1.
LABEL_REQUEST_INTERVAL_SECONDS0Spacing between request starts; 0 adds no delay.
LABEL_FLUSH_AFTER_N20Reserved field; not consumed by the current pipeline.
LABEL_FLUSH_INTERVAL_SECONDS300Reserved field; not consumed by the current pipeline.
LABEL_INCREMENTALtrueReserved field; offline labeling currently always processes unlabeled chunks only.
LABEL_MAX_CHARS_PER_MESSAGE200Maximum characters of each chunk in a labeling prompt.
LABEL_MOOD_VOCABEmptyComma-separated custom mood vocabulary; empty uses built-in values.

Update checks ​

VariableDefault/examplePurpose
UPDATE_CHECK_ENABLEDtrueQuery the latest release at startup.
UPDATE_CHECK_URLhttps://api.github.com/repos/kldhsh123/Afterglow/releases/latestPublic release lookup URL.
UPDATE_CHECK_TIMEOUT_SECONDS8Update-check timeout in seconds.

AGPL-3.0-or-later