背景:入库前审查链路一直整条超时(日志每 ~20s 一条 WARN),异步那层 (含刚装好的 T1)从未成功跑过。 - 新增 endpoint.go:把「连接语义上不可靠」的回环别名规范化成 127.0.0.1 (localhost 大小写不敏感 / 0.0.0.0 / 空主机),只替换 Host,不碰 path / query / fragment / userinfo;显式 [::1] 与真实主机名逐字不动 - Embed 加独立短超时 DefaultRequestTimeout = 5s(远小于审查 20s 预算): 卡住的调用快速失败并走既有「降级到词项余弦」的路径,把预算留给 T1 - .env.example 示例地址 localhost -> 127.0.0.1(未注释行键数 69 -> 69,无增删) - 跨包测试钉住 5s 严格小于审查总预算 诚实边界(子代理实测,推翻了主代理原先的 IPv6 根因推断): - Go 客户端走 localhost 实测约 57ms、curl 约 0.2s ⇒「localhost -> ::1 等满 20s 预算」这条链不成立;更可能是单槽 llama.cpp 的吞吐/争用 (一批 64 条约 2.1~2.9s,审查 201 条约 8~10s,再叠 T1 8s 顶满预算) - 规范化在任何环境下都无害,5s 快速失败对这个真因对症;但真因 (容量/争用)需要另排切片,已记入工作小结
552 lines
39 KiB
Bash
552 lines
39 KiB
Bash
# ============================================
|
||
# Cyrene v2 配置文件 (.env)
|
||
# 复制为 .env 后修改。所有配置均从环境变量注入,代码内禁硬编码。
|
||
# 注意:.env 仅用于本地开发;生产用 systemd / env_file。
|
||
# 敏感信息(API Key / JWT_SECRET)一律不要写进日志。
|
||
# ============================================
|
||
|
||
# ---- 运行环境 ----
|
||
ENV=development
|
||
LOG_LEVEL=debug
|
||
TZ=Asia/Shanghai
|
||
|
||
# ---- 数据目录(裁决 12.4.2/15.4.1,design/13 §2) ----
|
||
# 两种取法都实现:默认 ./data;显式写 platform(保留字哨兵)则走平台标准数据目录
|
||
# (Windows %APPDATA%\Cyrene、macOS ~/Library/Application Support/Cyrene、Linux ~/.local/share/cyrene)。
|
||
DATA_DIR=./data
|
||
|
||
# ---- 服务器(网关,唯一对外端口) ----
|
||
# HOST 默认 0.0.0.0,暴露面由 .env 决定(本机自托管要收紧就改 127.0.0.1)。
|
||
HOST=0.0.0.0
|
||
PORT=8080
|
||
# 管理面板的安全入口路径(裁决 1.6/16.4.7,design/07 §0.2):
|
||
# 管理面板前端挂在这个路径下,默认 admin(即 /admin);想藏起来就自定义,例如
|
||
# ADMIN_PATH=my-secret/admin → 面板在 /my-secret/admin,猜 /admin 直接 404。
|
||
# 它只影响面板前端路由;REST 仍是 /api/v1/admin/*(API 不藏,安全靠 JWT + 角色门),
|
||
# 且该路径串不会出现在用户端页面里。
|
||
ADMIN_PATH=admin
|
||
# chat.image 的【解码后图像字节】上限(协同文档 G3),默认 5242880(5 MiB,与 POST /api/v1/upload 同口径)。
|
||
# 图片有「上传」与「base64 内联」两条入口,两边必须给出同一个「一张图能有多大」的答案,否则内联可绕开上传限制。
|
||
# 调大请谨慎:整段 base64 会被落库,并随每页历史(GET /sessions/{id}/messages)与每次 WS history 回放重传一遍。
|
||
# ≤0(写 0 或负数)= 用默认值 5 MiB,不是「禁用上限」——一张图能有多大只能有一个答案。
|
||
CHAT_IMAGE_MAX_BYTES=5242880
|
||
|
||
# POST /api/v1/documents 的单文件字节上限,默认 20971520(20 MiB)。
|
||
# 它与上面的图片上限【刻意解耦】:图片上限被 vision 解码层钳住,文档上限由本项目的解析与上下文预算决定;
|
||
# 合用一个数会让「调文档上限」静默改掉图片行为。
|
||
# 文档读侧(GET /api/v1/documents/{name})要 Bearer owner/admin,且一律 attachment + nosniff(永不可内联渲染)。
|
||
# ≤0(写 0 或负数)= 用默认值 20 MiB,不是「禁用上限」。
|
||
CHAT_DOCUMENT_MAX_BYTES=20971520
|
||
|
||
# ---- 文档回收(GC:引用计数 + 保留期,design/24 §3.2(配额与清理);切片 S7) ----
|
||
# 判据:**未被任何消息引用**(ref_count = 0)且最后一次被引用(从未被引用则看上传时间)
|
||
# 早于「现在 − 保留期」。动作:原件(<DATA_DIR>/uploads/documents/<存储名>)+ 抽取正文
|
||
# sidecar(<DATA_DIR>/extracted/<存储名>.txt)+ documents 表里的元数据行**三样一起删**。
|
||
# 引用计数由消息落库/编辑/删除时维护(都在同一个事务里),因此**仍被引用的文件绝不删**。
|
||
# 启动时清扫一次 + 此后按间隔定时清扫;每轮只记一条汇总(删了几件/释放多少字节,不含正文)。
|
||
# DOCUMENT_GC_INTERVAL:定时清扫间隔(Go duration,如 30m / 1h / 6h),默认 1h。
|
||
# DOCUMENT_RETENTION:保留期(Go duration),默认 168h(7 天)。
|
||
# ⚠️ 任一键写 0 或负数 = **关闭 GC**(同时关闭启动期那一次清扫,日志会写明原因)。
|
||
# `DOCUMENT_RETENTION=0` 不是「立即回收」——那种解释会让一次笔误清空未引用的附件。
|
||
DOCUMENT_GC_INTERVAL=1h
|
||
DOCUMENT_RETENTION=168h
|
||
|
||
# ---- 渠道事件留存(非消息事件 / 请求 / 未知帧;design/26 §4.4;切片 E3+E4) ----
|
||
# 目的:让**到达过适配器的每一帧**至少留下可查(逐条落行)、可计数(按平台+类型聚合)的
|
||
# 脱敏结构痕迹 —— 事故排查时「上游推过没有 / 是不是被我们过滤了」必须答得上来。
|
||
# 落库口径:T2/T3 事件与「未知类型 / 解析失败」逐条落 channel_events(30 天保留期),
|
||
# 纯遥测(心跳 / 生命周期 / 自身回声)只进 channel_event_counters(不参与 GC)。
|
||
# 摘要一律走 adapter.SanitizeNoticeText;**消息正文 / 媒体 URL / OneBot request.flag
|
||
# 等凭据绝不入库、绝不进日志**。
|
||
# CHANNEL_EVENT_RETENTION:channel_events 行的保留期(Go duration),默认 720h(30 天)。
|
||
# 它比文档保留期(168h)长:事件表的核心用途是**事后定案**,一周太短。
|
||
# CHANNEL_EVENT_GC_INTERVAL:保留期清扫间隔(Go duration),默认 1h。
|
||
# ⚠️ 上面任一键写 0 或负数 = **关闭清扫**(同时关闭启动期那一次,日志会写明原因);
|
||
# `CHANNEL_EVENT_RETENTION=0` 不是「立即清空」——那会让一次笔误抹掉唯一的取证面。
|
||
# CHANNEL_EVENT_COUNTER_FLUSH:内存计数落盘间隔(Go duration),默认 30s。
|
||
# 计数是**近似值**(crash 会丢 ≤ 一个间隔的计数,面板须如实标注 approx)。
|
||
# 该键不做「显式关闭」:写 0 或负数一律回落 30s(计数落盘不是破坏性动作)。
|
||
CHANNEL_EVENT_RETENTION=720h
|
||
CHANNEL_EVENT_GC_INTERVAL=1h
|
||
CHANNEL_EVENT_COUNTER_FLUSH=30s
|
||
|
||
# ---- 链路图本地落盘(flow_graphs 表;切片 F2,design/19 §4 P3) ----
|
||
# 每个会话**每轮收尾落一条**链路图(web / web:<uuid> / sess-backthink 三个白名单会话;
|
||
# 隔离的群聊 / 陌生人会话绝不入库)。让「刷新 / 重启后翻历史轮」有本地数据,
|
||
# 而不是图只活在进程内存里。
|
||
# FLOW_GRAPH_RETENTION:flow_graphs 行的保留期(Go duration),默认 168h(7 天)。
|
||
# 图的用途是「回看最近若干轮」,不是事后定案证据(后者是 channel_events 的 720h)。
|
||
# FLOW_GRAPH_GC_INTERVAL:保留期清扫间隔(Go duration),默认 1h。
|
||
# ⚠️ 任一键写 0 或负数 = **关闭清扫**(同时关闭启动期那一次,日志会写明原因)⇒
|
||
# 落盘的轮次图将**无限增长**;`FLOW_GRAPH_RETENTION=0` 不是「立即清空」。
|
||
FLOW_GRAPH_RETENTION=168h
|
||
FLOW_GRAPH_GC_INTERVAL=1h
|
||
|
||
# ---- LLM 用量样本保留期(llm_usage 表;切片 U1,主人裁决「2.4 落」) ----
|
||
# 每次成功模型调用都会把一条**非敏感**用量样本(token 计数 / 缓存两档 / 模型名 /
|
||
# 用途 / 耗时)异步落进 llm_usage 表,供 GET /api/v1/admin/llm/usage 与面板的
|
||
# 用量小卡聚合。**凭据与消息正文绝不入库、绝不进日志**。
|
||
# 写入是有界队列 + 单写者 + 批量事务:队列满就丢弃并限流 WARN,**绝不阻塞模型调用**。
|
||
# LLM_USAGE_RETENTION:保留期(Go duration),默认 720h(30 天)。
|
||
# 启动时清理一次 + 此后每小时清理一次(清扫间隔无 env 键:保留期才是旋钮)。
|
||
# ⚠️ 写 0 或负数 = **关闭清理**(样本全留,日志会写明「llm usage retention disabled」)。
|
||
# `LLM_USAGE_RETENTION=0` 不是「立即清空」——那种解释会让一次笔误把成本视图清空。
|
||
LLM_USAGE_RETENTION=720h
|
||
|
||
# ---- 认证 / 管理员 ----
|
||
# JWT_SECRET 必填,长度 >= 32;缺失或过短会在启动时 panic。
|
||
JWT_SECRET=change-me-to-a-random-string-at-least-32-characters
|
||
ADMIN_USERNAME=admin
|
||
ADMIN_PASSWORD=admin12345
|
||
REGISTRATION_ENABLED=true
|
||
# 不透明 refresh token 有效期(Go duration,如 720h = 30 天);access token 固定 24h。
|
||
AUTH_REFRESH_TTL=720h
|
||
# refresh token 单次使用轮换默认开启(用旧换新、防重放);仅当客户端无法保存轮换后的
|
||
# 新 token 时才设为 true 关闭轮换。
|
||
AUTH_REFRESH_ROTATE_DISABLED=false
|
||
|
||
# ---- 数据库 ----
|
||
# SQLite 为默认(单二进制、无需外部服务)。
|
||
DB_SQLITE_PATH=./data/cyrene.db
|
||
# PostgreSQL + pgvector 为可选增强;未配置时走 SQLite。相关向量能力在 M4 接入。
|
||
# DB_PG_URL=postgres://cyrene:cyrene_pass@localhost:5432/cyrene_ai?sslmode=disable
|
||
|
||
# ---- LLM 多供应商(LLM_PROVIDER 显式声明协议:openai / anthropic,默认 openai) ----
|
||
# ⚠️ 本节是【兜底】:管理面板「LLM 模型」页保存会写入本地 models.json(默认 <DATA_DIR>/models.json,已 gitignore),
|
||
# 只要 models.json 存在且有效,运行中的 LLM 就优先用它的多厂商多模型组,并支持面板实时保存→热更新(无需重启)。
|
||
# 仅当 models.json 不存在/无效时才回退到下面的 .env。
|
||
# Provider = openai:OpenAI 兼容 /chat/completions(含 OpenAI 兼容网关,也可经它承载 Anthropic 模型,但失去原生 tool input 对象优势)
|
||
LLM_PROVIDER=openai
|
||
|
||
LLM_BASE_URL=https://api.openai.com/v1
|
||
LLM_API_KEY=sk-xxxxx
|
||
LLM_MODEL=gpt-4o
|
||
LLM_FALLBACK_MODEL=gpt-4o-mini
|
||
# 最后一道回退模型(fallback 链末端)的 token 预算上限。仅当链确有回退模型、
|
||
# 且该模型组未在 models.json 设 maxTokens、请求也未显式给 MaxTokens 时生效;
|
||
# 0 = 关闭该兜底(改用适配器默认,如 anthropic 8192)。每模型组预算见 models.json 的 maxTokens。
|
||
LLM_FALLBACK_MAX_TOKENS=8192
|
||
# 推理开关的【提供商形状】声明(裁决 03.4.2 / 08.4.1):auto(默认,= 留空)/ deepseek /
|
||
# openai / vllm / dashscope。形状决定把思考开关下发改成哪个字段(如 vllm =
|
||
# chat_template_kwargs.enable_thinking、dashscope = 顶层 enable_thinking),必须按端点真实形状
|
||
# 声明——发错形状会被上游拒。留空/auto = 按模型名与 base URL 推断厂商,形状有歧义时一个字段都不发。
|
||
# ⚠️ 本键只作用于 .env 合成的模型组:存在有效 models.json 时,以该组的 reasoning.kind 为准
|
||
# (面板可编辑,见「LLM 模型」页)。
|
||
LLM_REASONING_KIND=
|
||
|
||
# ---- LLM 视觉模型(视觉/OCR 工具用的模型;与「主模型能否收图」无关) ----
|
||
# 语义(v0.53 修正):主模型自己能不能收图,看 models.json 生效组的 multimodal 字段(面板可勾选),
|
||
# 不是看这里;本节的模型【只供 vision / ocr 工具】调用。都不配置时工具回落用主模型(LLM_MODEL)。
|
||
# .env 侧的等价键是下面的 LLM_MULTIMODAL——它同样只作用于 .env 合成的模型组。
|
||
# LLM_VISION_MODEL=gpt-4o-mini
|
||
# OCR 工具单独用另一个模型(可选):留空 = 复用 LLM_VISION_MODEL。
|
||
# LLM_OCR_MODEL=qwen-vl-ocr
|
||
|
||
# 声明【主模型自身】能否直接接收图片(= models.json 组 multimodal 的 .env 等价物):
|
||
# true = 图片直接进主模型上下文(省掉工具那一轮模型调用、不做有损文本摘要);
|
||
# 留空 / false(默认)= 图片交给 vision / ocr 工具,由工具返回文本描述。
|
||
# 默认 false 与引入本键之前【逐字节一致】——扁平 env 块只有这一个键能声明收图能力,
|
||
# 而声称端点可能不具备的能力,比把图交给视觉/OCR 工具更糟(design/06 §0 首条);
|
||
# 绝不凭 base URL / 模型名猜测端点是否收图。
|
||
# ⚠️ 只作用于 .env 合成的模型组:存在有效 models.json 时以该组的 multimodal 为准(面板可勾选)。
|
||
# ⚠️ 非法值(非 bool,如 maybe)= 启动即报错,不静默回退。
|
||
# LLM_MULTIMODAL=false
|
||
|
||
# 声明该端点的【模型上下文窗口】(token)。窗口是上下文压缩预算的推导依据:
|
||
# 未设置 CONTEXT_MAX_TOKENS 时 budget = min(窗口 × CONTEXT_BUDGET_RATIO, 窗口 − 输出保留)。
|
||
# ⚠️ 本仓没有任何 provider 侧的窗口发现代码(GET /models 的自动发现另立设计),窗口只能声明:
|
||
# 不声明就回落 131072(128 Ki)并记一条 WARN,默认模型的 1M 窗口因此吃不到。
|
||
# 它必须与 models.json 组的 contextWindow 一致(那一处是面板一等来源,本键只给 .env 合成的组播种)。
|
||
# 负数 = 启动即报错。
|
||
# LLM_CONTEXT_WINDOW=1048576
|
||
|
||
# Provider = anthropic:Anthropic Messages /v1/messages(tool_use.input 为结构化对象,工具循环更稳)
|
||
# ANTHROPIC_BASE_URL=https://api.anthropic.com
|
||
# ANTHROPIC_API_KEY=sk-ant-xxxxx
|
||
# ANTHROPIC_MODEL=claude-sonnet-4-20250514
|
||
# ANTHROPIC_FALLBACK_MODEL=claude-haiku-3-5
|
||
# ⚠️ 若 ANTHROPIC_BASE_URL 指向 DeepSeek(https://api.deepseek.com/anthropic),模型名须用 DeepSeek 当前名称
|
||
# (deepseek-flash / deepseek-v4-pro):不认识的名称(如 claude-*)会被服务端【静默映射成 deepseek-flash】,
|
||
# 配置错了不会报错。旧的 deepseek-chat / deepseek-reasoner 已于 2026-07-24 停用。
|
||
|
||
# ---- LLM 本地第三级(降级链末端;默认关,裁决 03.4.3) ----
|
||
# 降级链为「主 → 备 → 本地」;本地这一级默认关闭(当前设备跑本地模型困难),链保持两级。
|
||
# 开启需要三个条件同时满足:LLM_LOCAL_ENABLED=true + LLM_LOCAL_BASE_URL + LLM_LOCAL_MODEL;
|
||
# 只开开关不配端点/模型会被记 WARN 并跳过(不会半配成一个只会失败的链尾步)。
|
||
LLM_LOCAL_ENABLED=false
|
||
# 本地端点协议:openai(llama.cpp / ollama / vLLM 兼容)或 anthropic;留空 = openai。
|
||
# LLM_LOCAL_PROVIDER=openai
|
||
# LLM_LOCAL_BASE_URL=http://127.0.0.1:8080/v1
|
||
# 本地服务通常不需要 key;留空即可。
|
||
# LLM_LOCAL_API_KEY=
|
||
# LLM_LOCAL_MODEL=qwen3-4b-instruct
|
||
|
||
# ---- 记忆嵌入(可选,真语义) ----
|
||
# 不配置时使用内置 n-gram / FTS 向量(dim=256)。配置后必须真实走语义路径。
|
||
# EMBEDDING_API_URL 是【完整 /embeddings 端点】(不是 base)——例:Ollama / llama.cpp = http://127.0.0.1:11434/v1/embeddings
|
||
# ⚠️ 回环地址请写具体的 IPv4 字面量 127.0.0.1,**不要写 localhost**:本机 embedding 服务
|
||
# (llama.cpp / ollama)默认只绑 IPv4 回环,而 localhost 会先解析到 IPv6 ::1 —— 那里没有
|
||
# 监听,轻则多一次无效拨号(实测 localhost 约 0.2s,127.0.0.1 约 0.001s),重则在「::1 被
|
||
# 静默丢弃」的环境里等到系统连接超时,白白吃掉整条入库审查的预算。
|
||
# (客户端已对 localhost / 0.0.0.0 / 空主机做兜底规范化,但直接写对更省事、更好排查。)
|
||
# EMBEDDING_API_URL=http://127.0.0.1:11434/v1/embeddings
|
||
# EMBEDDING_API_KEY=
|
||
# EMBEDDING_MODEL=Qwen3-Embedding-0.6B # 推荐(Q8_0 ~639MB、dim=1024、ModelScope 国内可下)
|
||
|
||
# ---- IoT 设备提供者 ----
|
||
# mock = 模拟智能家居设备(开发测试用);none = 禁用 IoT。
|
||
IOT_PROVIDER=mock
|
||
|
||
# ---- 语音服务 ----
|
||
TTS_PROVIDER=edge-tts
|
||
STT_PROVIDER=dashscope
|
||
# DASHSCOPE_API_KEY=sk-xxxxx # ⚠️ 必填才能接通阿里百炼语音;未填时走降级链 (silent)。绝不打日志。
|
||
# --- 阿里百炼 DashScope 语音(STT + TTS 主链路)---
|
||
# DASHSCOPE_BASE_URL=https://dashscope.aliyuncs.com/api/v1
|
||
# VOICE_STT_MODEL=qwen-audio-3.0-asr-flash
|
||
# VOICE_STT_LANGUAGE=zh
|
||
# IM 入站语音转写的超时(秒,默认 20):桥接器会为这次调用举着一个入站并发槽,
|
||
# 因此上游卡住不能拖死整条流水线。≤0 或未配置时用桥接器默认值 20s。
|
||
# 只影响 IM 渠道的入站语音;Web 客户端的语音输入不受它约束。
|
||
# VOICE_STT_TIMEOUT_SEC=20
|
||
# 已实测:cosyvoice-v3.5-plus / cosyvoice-v2 走 HTTP SpeechSynthesizer 会回 418(引擎拒绝);
|
||
# 可用组合为 cosyvoice-v3-flash + 对应 v3 音色(longxiaochun_v3 龙小淳·女助手等)。
|
||
# 各模型音色不可混用(v2 名如 longxiaochun 用于 v3 模型会 418)。
|
||
# VOICE_TTS_MODEL=cosyvoice-v3-flash
|
||
# VOICE_TTS_VOICE_ID=longxiaochun_v3
|
||
# VOICE_TTS_FORMAT=wav
|
||
# VOICE_TTS_SAMPLE_RATE=24000
|
||
# 情绪/语气指令(TTS instruction):只对「复刻/设计音色」生效(可任意指令,如
|
||
# "语气开朗俏皮,像女朋友撒娇"),系统音色 longxiaochun_v3 必须用固定格式故不传。
|
||
# 长度≤100 字符(汉字记 2)。也可在 POST /api/v1/audio/speech 用 instruction 按请求覆盖。
|
||
# VOICE_TTS_INSTRUCTION=语气开朗俏皮,像女朋友撒娇
|
||
# 声音复刻前缀(create_voice 的 prefix,≤10 字母/数字,空则用 cyrene)。target_model
|
||
# 固定为 VOICE_TTS_MODEL(须与合成模型一致)。
|
||
# VOICE_CLONE_PREFIX=cyrene
|
||
# 声音复刻(响昔涟音色):先用参考音频(公网 URL)调 POST /api/v1/audio/voice-clone
|
||
# 建自定义音色,再把返回的 voice_id 填到 VOICE_TTS_VOICE_ID。
|
||
# ⚠️ 建音色必须公网可访问的参考音频 URL(create_voice 只收 input.url,不收 base64);
|
||
# 待主人提供参考音频公网 URL 方能真建音色。
|
||
|
||
# ---- 网络搜索(web-search 工具) ----
|
||
# WEB_SEARCH_PROVIDER = 选谁当搜索后端。可选:searxng(默认,本机兜底)/ zhipu(智谱
|
||
# BigModel)/ aliyun_iqs(阿里云 IQS)/ bocha(博查)/ volcengine(火山·豆包搜索)/
|
||
# baidu_qianfan(百度千帆)。**未配置的家不会出现在可用清单里**(fail-closed)。
|
||
# ⚠️ 指向未登记(如本期未做的 tavily)或未配置(缺 key)的名字 ⇒ **启动期报错**,
|
||
# 绝不静默回落到兜底;写空串 / off / none ⇒ **web-search 不注册**,模型看不见它。
|
||
WEB_SEARCH_PROVIDER=searxng
|
||
# WEB_SEARCH_FALLBACK = 降级链(逗号分隔,从左到右试;空 = 只用手选的那一个)。
|
||
# 只在该家「不可用」(无 key / 鉴权失败 / 限流 / 额度 / 网络)时前进一格;结果里会
|
||
# 如实标注**实际应答**的 provider,绝不拿兜底冒充主力。空结果**不**触发前进。
|
||
# WEB_SEARCH_FALLBACK=zhipu,bocha,searxng
|
||
# WEB_SEARCH_MAX_RESULTS = 单次检索返回条数上限(**播种层**的键:面板文件一旦落盘,
|
||
# 就以 $DATA_DIR/config/plugins/web-search.json 的 maxResults 为准,改面板即生效、不用重启)。
|
||
# 默认 10;provider 自身的条数上限(如博查 50、IQS 固定 10)优先于本键的下限。
|
||
WEB_SEARCH_MAX_RESULTS=10
|
||
# WEB_SEARCH_ENDPOINT = **searxng provider** 的端点(SearXNG 兼容,GET + format=json)。
|
||
# 默认值 http://127.0.0.1:38471 是**本机兜底**:scripts/searxng/settings.yml 就是它的
|
||
# 配套配置(docker 起法见该文件头注释),无需任何第三方 API key、开箱即用 —— 默认指向
|
||
# 本机而不是某个云搜索服务,原因就在这。它只在 WEB_SEARCH_PROVIDER=searxng 时起作用。
|
||
WEB_SEARCH_ENDPOINT=http://127.0.0.1:38471
|
||
# 显式关闭:把上面这行写成空串 / off / none(大小写不敏感)⇒ **web-search 不注册**,
|
||
# 模型根本看不见它(不给一把一调就报错的锤子)。值不是 http(s) 绝对地址时同样不注册,
|
||
# 启动日志会有一条带键名的 WARN 说明原因(绝不静默半开)。
|
||
# WEB_SEARCH_ENDPOINT=off
|
||
# WEB_SEARCH_TIMEOUT = 单次搜索请求的超时(Go duration,如 20s)。
|
||
# 不配置时**沿用 io 包既有超时(15s)** —— 这里刻意不写第二个默认值。
|
||
# 它只影响 web-search 一次调用,不改 http / web-fetch 用的那个共享客户端。
|
||
# ⚠️ 降级链下它是**每一次上游尝试**的预算(主家超时后备家仍有自己的份额)。
|
||
# WEB_SEARCH_TIMEOUT=20s
|
||
#
|
||
# ---- 各搜索后端独立一组键(未配置的家不出现;密钥绝不进日志/响应/提示词)----
|
||
# 智谱 BigModel(Bearer;官方定价已确证:Search-Std 0.01 元/次起)。
|
||
# 申请 key:https://open.bigmodel.cn
|
||
# WEB_SEARCH_ZHIPU_API_KEY=<your-zhipu-api-key>
|
||
WEB_SEARCH_ZHIPU_BASE_URL=https://open.bigmodel.cn
|
||
# 阿里云信息查询服务 IQS(GET + X-API-Key,免签名免 SDK;默认返回 10 条且不可调)。
|
||
# 申请 key:https://www.aliyun.com/product/iqs
|
||
# WEB_SEARCH_ALIYUN_IQS_API_KEY=<your-aliyun-iqs-api-key>
|
||
WEB_SEARCH_ALIYUN_IQS_BASE_URL=https://cloud-iqs.aliyuncs.com
|
||
# 博查 Bocha(POST + Bearer;中文优先)。默认域名取官方文档口径 api.bocha.cn
|
||
# (官网首页样例仍用 api.bochaai.com,两域关系官方未说明,可在此键切换)。
|
||
# 申请 key:https://open.bocha.cn
|
||
# WEB_SEARCH_BOCHA_API_KEY=<your-bocha-api-key>
|
||
WEB_SEARCH_BOCHA_BASE_URL=https://api.bocha.cn
|
||
# 火山引擎·豆包搜索 SearchInfinity(Bearer;含每月 500 次免费额度,官方原文确证)。
|
||
# 申请 key:https://console.volcengine.com/search-infinity/api-key
|
||
# WEB_SEARCH_VOLCENGINE_API_KEY=<your-volcengine-api-key>
|
||
WEB_SEARCH_VOLCENGINE_BASE_URL=https://open.feedcoopapi.com
|
||
# 百度·千帆 AI 搜索(Bearer;标准版 0.036 元/次,每月免费 1500 次,官方原文确证)。
|
||
# 申请 key:https://console.bce.baidu.com/qianfan/
|
||
# WEB_SEARCH_BAIDU_QIANFAN_API_KEY=<your-baidu-qianfan-api-key>
|
||
WEB_SEARCH_BAIDU_QIANFAN_BASE_URL=https://qianfan.baidubce.com
|
||
|
||
|
||
# ---- 后台思考 ----
|
||
# ⚠️ 未接线(全仓无消费者),配了不生效;是否接线待主人拍板
|
||
# (DevDocs/audit/07-backthink-automation-iot.md §1-17)。
|
||
ENABLE_BACKGROUND_THINKING=true
|
||
# 自主思考心跳周期(秒)。默认 900(15 分钟一次);数值越小越频繁打扰。
|
||
THINK_INTERVAL_SEC=900
|
||
# 静默时段内的心跳周期(秒)。默认 3600(1 小时):当前时刻落在安静时段
|
||
# (QUIET_START_HOUR–QUIET_END_HOUR)内时,周期性心跳改用该间隔降频,窗外仍用
|
||
# THINK_INTERVAL_SEC;≤0 = 关闭降频(回落普通间隔,不是「半夜不思考」)。
|
||
# ⚠️ 只作用于周期性心跳:事件驱动(安全域/急性事件)照旧立刻触发、穿透安静时段。
|
||
THINK_QUIET_INTERVAL_SEC=3600
|
||
THINK_SILENCE_TIMEOUT_SEC=120
|
||
# 主动推送频率(design/12 §6):窗口内最多 PushLimit 次;推后冷却 Cooldown 秒;
|
||
# 同一风味(问候/提醒/分享/关心)在 KindWindow 秒内最多一次;主人最近消息在
|
||
# RecentChatCooldown 秒内则冷避不推。收敛默认值:1 次 / 60 分钟 + 推后 30 分钟冷却。
|
||
THINK_PUSH_LIMIT=1
|
||
THINK_PUSH_WINDOW_SEC=3600
|
||
THINK_PUSH_COOLDOWN_SEC=1800
|
||
THINK_RECENT_CHAT_COOLDOWN_SEC=600
|
||
THINK_KIND_WINDOW_SEC=7200
|
||
# 安静时段(本地时钟小时,默认 23:00-07:00;两端相等且非 0 则关闭)。
|
||
# 同时用于 backthink 后台思考与 channelbridge 公共平台安静时段轻思考(design/12 §6 策略五)。
|
||
QUIET_START_HOUR=23
|
||
QUIET_END_HOUR=7
|
||
|
||
# ---- 记忆整理与去重(design/23;主题 N · 长期记忆维护) ----
|
||
# **低峰定期后台任务**(不是会话内派 subagent):逐分区扫描 → 相似度**召回**候选对 →
|
||
# 「事实集合包含关系」判定 → 规则否决 → 落 `memory_tidy_candidates` 建议队列。
|
||
# 第一版**只产建议**:绝不自动合并/删除/改写任何一条记忆,也**不推送**、不进 chat、
|
||
# 不碰主会话上下文(跑在专属隔离会话 sess-memorytidy,与 backthink 同一范式)。
|
||
# 每轮汇总量(扫描/候选/否决原因分布)进日志与 `memory_tidy_runs` 表,绝不静默。
|
||
# 关闭开关:写 false 即完全不跑(日志会写明)。
|
||
MEMORY_TIDY_ENABLED=true
|
||
# 整理周期(秒),默认 86400 = 每天 1 次。它是**下限**:实际在低峰窗口起点跑,
|
||
# 因此真实间隔取「低峰窗口每天一次」与本值中较长者。
|
||
MEMORY_TIDY_INTERVAL_SEC=86400
|
||
# 低峰窗口(本地钟点),默认与 backthink 一致的 23:00-07:00(窗口可跨午夜;
|
||
# 两端相等且非 0 = 关闭窗口,改为按上面周期跑)。整理只在窗口内开跑。
|
||
MEMORY_TIDY_QUIET_START_HOUR=23
|
||
MEMORY_TIDY_QUIET_END_HOUR=7
|
||
# 候选召回的余弦**召回门**,默认 0.80。⚠️ 它只决定「哪些对值得看一眼」,
|
||
# **不是**合并判据 —— 能否合并由「事实集合包含关系(A ⊆ B)+ 规则否决」决定
|
||
# (实据:必合对 0.8330 与必不合对 0.7100 只差 0.12,单阈值双向失效)。
|
||
MEMORY_TIDY_RECALL_THRESHOLD=0.80
|
||
# 每分区每轮的扫描上限(默认 5000)。
|
||
MEMORY_TIDY_SCAN_LIMIT=5000
|
||
# 每分区每轮的**候选**上限,默认 200。⚠️ 它是**每分区**的量,不是全库总量。
|
||
# 2026-10-06 由 20 抬到 200:首轮真跑时四个分区同时打满旧值,候选数(77)由上限
|
||
# 而不是规则决定;命中上限时响应里的 `truncated` 会带 `<分区>(candidates)`。
|
||
MEMORY_TIDY_CANDIDATE_LIMIT=200
|
||
# ⚠️ 2026-10-06 起(主人红线):**`.env` 冻结为「只保证最小化功能可跑」的引导面** ——
|
||
# **新旋钮一律不再进 `.env`**(本块此前收过的「两两比对上限」与「入库前审查」四键**已撤出**:
|
||
# 它们有代码默认值 2000 / true / 256 / 200 / 20,真正入口是 `$DATA_DIR/config/**` + 面板,
|
||
# 迁移切片已排队)。规矩全文见 `design/13 §2.1`;`AGENTS §10` 的 E6 已按此改写。
|
||
|
||
# ---- 唤醒式能力渐进(capacity 意图判定,design/14 §2.2) ----
|
||
# 总开关(默认 false):关闭时 loop 向模型暴露【全部】已注册工具,行为与接线前逐字节一致;
|
||
# 置 true 才按判定出的状态裁剪可用工具集(判定只在 loop 外围,不阻塞 Invoke)。
|
||
CAPACITY_ENABLED=false
|
||
# 唤醒阈值(默认 0.6):判定置信度低于它的状态强制回落到角色默认态(保守、不打扰);
|
||
# 角色 YAML 的 awakening.minConfidence 为正数时覆盖本全局值。
|
||
# 写 0 = 用代码内默认 0.6,不是「阈值归零」。
|
||
CAPACITY_MIN_CONFIDENCE=0.6
|
||
# 状态 → 允许工具名的 JSON 映射,例如
|
||
# {"quiet":["terminal","file"],"awake":["terminal","file","web-search"],"full":null}
|
||
# 缺失的状态用内置默认集(quiet = terminal/file/knowledge/text/transcode/capability_list;
|
||
# awake = quiet + web-search/web-fetch/http;full 不限制);null(如 "full")= 不限制。
|
||
# 解析失败记 WARN 并回落到内置默认。
|
||
# ⚠️ 自己写映射时,请把你要用的新能力一并列进去:不在允许集里的工具在
|
||
# CAPACITY_ENABLED=true 时会从模型可见工具面里消失(Invoke 仍放行,见 design/14 §4)。
|
||
# CAPACITY_TOOL_SETS=
|
||
# L3 = 模型辅助的意图分类:仅当 L1 启发式与 L2 上下文仍拿不准时介入一次轻量模型调用。
|
||
# 默认关闭(纯启发式够日常,且该层要多花一次模型调用);关闭时该层从不运行,
|
||
# L1/L2/L4 的行为与接线前逐字节一致。
|
||
CAPACITY_L3_ENABLED=false
|
||
# L3 判定结果的缓存 TTL(Go duration,如 5m):同一段回合文本在此窗口内复用判定,避免每轮都问模型;
|
||
# 留空 = 5m;0 或解析不出 = 不缓存。
|
||
CAPACITY_L3_CACHE_TTL=5m
|
||
|
||
# ---- 子代理(orchestration,design/05 §7) ----
|
||
# 单个子代理整次运行的时限(秒)。默认 600 = 10 分钟(裁决 02.4.4:agent_timeout
|
||
# 可配置);模型派发时可用 subagent_spawn 的 timeout_seconds 参数按调用覆盖。
|
||
SUBAGENT_TIMEOUT_SEC=600
|
||
|
||
# ---- 护栏与上下文预算(design/04 §1.3 / §5、附录 A.3) ----
|
||
# 上下文溢出压缩预算(token,离线估算值)。会话估算上下文超过它时,更早的轮次被摘要成
|
||
# 一条前导摘要消息,近期尾部(含尾部工具结果)原样保留。三种取值:
|
||
# · 未设置(默认,即把本行注释掉)= 按模型窗口推导:
|
||
# budget = min(窗口 × CONTEXT_BUDGET_RATIO, 窗口 − 输出保留)
|
||
# 输出保留 = max(32768, 本组 maxTokens);窗口未声明 ⇒ 回落 131072 并记一条 WARN。
|
||
# · > 0 = 显式覆盖(原样使用)
|
||
# · 0 / 负数 = 关闭压缩(行为与本条接线前逐字节一致)
|
||
# ⚠️ 旧模板里的 CONTEXT_MAX_TOKENS=32768 取自「gpt-4o 128K 窗口的四分之一」,那个前提已失效
|
||
# (默认模型窗口 1M)。若你的 .env 里还留着它,它就是【显式覆盖 32768】,会盖掉按窗口推导
|
||
# (1M 窗口 ⇒ 699050 token)——要吃到推导,把那一行注释掉。固定低阈值会既丢上下文、又因反复
|
||
# 压缩作废 KV 缓存前缀而反复烧钱(附录 A.2)。
|
||
# CONTEXT_MAX_TOKENS=
|
||
# 推导比例:预算占窗口的比例,主人 2026-10-04 裁决取 1/2–3/4 之间,默认 2/3。
|
||
# 写法:小数(0.5)或分数(1/2)都接受;非法值 = 记一条 WARN 并回落 2/3。
|
||
# CONTEXT_BUDGET_RATIO=2/3
|
||
# 单份附件注入模型可见上下文的字符上限(sidecar 仍存全文,只受 8 MiB 安全上限约束)。
|
||
# 留空 = 按推导出的预算算:推导预算的 1/8(按一个回合最多 5 个附件留余量),下限 64K 字符。
|
||
# 它决定「每回合往上下文里放多少」,也因此决定清单行给的续读游标从哪里开始。
|
||
# ⚠️ 它必须**不超过**下面 GUARDRAIL_MAX_INPUT_CHARS 生效的输入上限 —— 严格说是
|
||
# 「单份注入 × 单回合附件数(最多 5)」不超过上限,否则满载附件的回合会在装配完之后
|
||
# 被输入护栏整回合拦死(input_length_exceeded)。改了本键就顺手核对那一项。
|
||
# DOCUMENT_MAX_INJECT_CHARS=
|
||
# 请求侧字符上限(输入护栏跑在**组装完成的请求**上:系统提示词 + 记忆块 + 整段对话 + 工具结果)。
|
||
# 三种取值:
|
||
# · 未设置 / 0(默认)= 由推导出的上下文预算派生:
|
||
# 上限 = max(262144, 推导预算 token 数 × 4)
|
||
# 那个 4 与附件注入预算用的是**同一个换算常量**(loop.CharsPerToken = 4 字符 ≈ 1 token)。
|
||
# 上限量的是整段装配请求,而注入预算是单份的,两边必须是同一套换算,否则**多附件**回合
|
||
# 会被拦死(G2b 修的正是这个:旧口径按 1 字符 ≈ 1 token 兑,2 份满额注入就顶到上限):
|
||
# 1M 窗口 ⇒ 预算 699050 token ⇒ 上限 2796200 字符;
|
||
# 单份附件注入预算 349525 字符 ⇒ 5 份(单回合附件上限)满额注入合计 1747625 字符,
|
||
# 关系不变量「单回合全部附件的注入预算合计 ≤ 输入上限」成立,「分享大文件」才走得通。
|
||
# 预算关闭(CONTEXT_MAX_TOKENS=0)或预算很小时,上限落回 262144。
|
||
# · > 0 = 显式覆盖(原样使用;压到「单份注入 × 单回合附件数」之下会让多附件回合被拦,
|
||
# 届时启动日志里有 WARN)
|
||
# · < 0 = 非法:记一条 WARN 并回落派生值(绝不静默生效)
|
||
# 它只动**输入**侧;输出上限(65536 字符)防的是模型输出失控,与上下文预算无关,不开放配置。
|
||
# 敏感信息(API key / bearer token / 密码 / 私钥)为阻断档,同样是代码内定的安全默认值。
|
||
# (取值与关系不变量的落点在 cmd/cyrene/wire_guardrail.go)
|
||
# GUARDRAIL_MAX_INPUT_CHARS=
|
||
# 内容策略关键词表(逗号分隔,大小写不敏感的子串匹配)。留空 = 不挂关键词护栏
|
||
# (项目不内置任何词表,只有你显式声明过的词才会被拦)。
|
||
# GUARDRAIL_KEYWORDS=
|
||
|
||
# ---- 主人身份说明书注入范围(design/11 §0 红线) ----
|
||
# 主人身份说明书(owner.yaml identityFile)注入范围:owner_only(默认,仅主人会话) | always(所有会话,含群聊/陌生人,仅自测) | off。
|
||
# owner_only 按渠道层强类型 actor 元数据判定;非法值回退 owner_only 并记 WARN(绝不静默放行)。
|
||
# 它只决定那段知识进不进该会话的上下文,不参与任何身份/权限判定(身份始终看 actor 元数据 + 白名单)。
|
||
OWNER_IDENTITY_INJECTION=owner_only
|
||
|
||
# ---- 推送出口(D1,主动推送的两级投递)----
|
||
# 主动消息在 WS/IM 投递之外,异步镜像到「主人自建统一推送服务」(主通道)。
|
||
# 该服务不可达/未配时,日志注明「个推(Getui)回退待接入」——当前无 Getui SDK,不伪造投递。
|
||
# 填写自建服务的 webhook 地址并置 ENABLE=true 即启用;token 只走 Authorization 头,不落日志。
|
||
PUSH_EXPORTER_ENABLED=false
|
||
# PUSH_EXPORTER_URL=https://push.example.com/webhook
|
||
# PUSH_EXPORTER_TOKEN=change-me
|
||
# PUSH_EXPORTER_TIMEOUT_SEC=5
|
||
# 个推(Getui)回退字段:预留占位,SDK 未接入,当前不生效。
|
||
# GETUI_APP_ID=
|
||
# GETUI_APP_KEY=
|
||
# GETUI_MASTER_SECRET=
|
||
# GETUI_BASE_URL=
|
||
|
||
# ---- WebSocket ----
|
||
WS_MAX_CONNECTIONS=1000
|
||
SESSION_IDLE_TIMEOUT_MIN=30
|
||
|
||
# ---- MCP 服务器(可选,JSON 数组字符串;每台 server 含 name/command/args/url/enabled) ----
|
||
# stdio 子进程示例:
|
||
# MCP_SERVERS_JSON=[{"name":"calc","command":"mcp-calc","args":["--stdio"],"enabled":true}]
|
||
# SSE 端点示例:
|
||
# MCP_SERVERS_JSON=[{"name":"weather","url":"http://localhost:3001/sse","enabled":true}]
|
||
# ⚠️ 旧键(未接线,配了不生效,勿用):`MCP_NAME` / `MCP_COMMAND` / `MCP_ARGS` / `MCP_URL` /
|
||
# `MCP_TRANSPORT` / `MCP_ENABLED` 这类「单 server 扁平 env 模式」(含带编号的
|
||
# `MCP_0_*`、`MCP_1_*` …)只在 internal/capability/mcp 的单测里被解析;生产装配
|
||
# (cmd/cyrene/mcp.go)只读 `MCP_SERVERS_JSON`。`MCP_API_KEY` / `MCP_ENV` 更连那套
|
||
# 解析都不读(结构体上的残留 tag)。要接 MCP server 请只用上面的 MCP_SERVERS_JSON。
|
||
|
||
# ---- 本地执行沙箱(exec/terminal 工具;默认关闭,授权放权) ----
|
||
# 只有 Enabled=true 时 agent 才可执行命令;仍需命令白名单与根目录边界。
|
||
# EXEC_SANDBOX_ENABLED=false
|
||
# EXEC_SANDBOX_COMMANDS=git,ls,cat,pwd
|
||
# EXEC_SANDBOX_ROOTS=./data
|
||
# EXEC_SANDBOX_ENV=PATH
|
||
|
||
# ---- 跨域白名单 ----
|
||
ALLOWED_ORIGINS=http://localhost:5173,http://localhost:3000
|
||
|
||
# ---- KOOK(KaiHeiLa)渠道 ----
|
||
# 单账号走环境变量;多账号走下方 CHANNELS_JSON。
|
||
# .env 仅提供【必要连接兜底】;接收模式 / webhook 回调路由 / verify_token / encrypt_key 等
|
||
# 业务·高级项一律在管理面板「渠道管理」配置(写入 channels.json,热更新),不落 .env。
|
||
# CHANNEL_KOOK_TOKEN 为 KOOK 开发者中心机器人 token(敏感,勿写日志/提交)。
|
||
# CHANNEL_KOOK_BASE_URL 可选,默认 https://www.kookapp.cn/api/v3。
|
||
# CHANNEL_KOOK_TOKEN=
|
||
# CHANNEL_KOOK_BASE_URL=
|
||
|
||
# ---- Telegram 渠道 ----
|
||
# 同 KOOK 口径:单账号走环境变量、多账号走下方 CHANNELS_JSON,业务·高级项一律在面板配置。
|
||
# bot_token 为空时该账号【完全不存在】(空占位符绝不占用裸平台名),所以不用的平台留空即可。
|
||
# CHANNEL_TELEGRAM_BOT_TOKEN 为 BotFather 签发的 token(敏感,勿写日志/提交)。
|
||
# CHANNEL_TELEGRAM_WEBHOOK_URL 可选:填公网 HTTPS 回调地址走 webhook 投递;
|
||
# 留空则适配器改用 getUpdates 长轮询(本地开发无需公网地址)。
|
||
# CHANNEL_TELEGRAM_BOT_TOKEN=
|
||
# CHANNEL_TELEGRAM_WEBHOOK_URL=
|
||
|
||
# ---- OneBot v11(QQ)渠道 ----
|
||
# 四端由 transport(ws|http) × mode(client|server) 组合决定(裁决 1.4 / design/08 §4):
|
||
# ws+client Cyrene 拨号 OneBot,收发同一 WS
|
||
# ws+server OneBot 反连 Cyrene(需 LISTEN_ADDR),收发同一 WS
|
||
# http+client Cyrene → OneBot(纯出站,POST {API_BASE_URL}/{action})
|
||
# http+server OneBot → Cyrene(纯入站,POST 到 LISTEN_ADDR + REPORT_PATH)
|
||
# 该平台【无 token 门槛】:一个键都不配也会合成账号,是否真拨号由渠道桥的 configured 闸门
|
||
# 决定(server 模式要 LISTEN_ADDR 非空,client 模式要 REMOTE_URL 非空)。
|
||
# transport 留空或未知值一律回落 ws;mode 默认 server(即不给任何新配置时行为与改造前一致)。
|
||
# CHANNEL_QQ_OBV11_TRANSPORT=ws
|
||
# CHANNEL_QQ_OBV11_MODE=server
|
||
# ⚠️ LISTEN_ADDR 落在 AGENTS §9 登记的唯一「可开监听端口」豁免(OneBot 反连):
|
||
# 必须由配置显式给出,为空则 server 模式 Connect 直接失败、绝不开端口。
|
||
# CHANNEL_QQ_OBV11_LISTEN_ADDR=127.0.0.1:5700
|
||
# ws+client 的拨号端点(ws:// 或 wss://)。
|
||
# CHANNEL_QQ_OBV11_REMOTE_URL=
|
||
# OneBot HTTP API 基址(如 http://127.0.0.1:3000):http+client 必填;http+server 可选,
|
||
# 给了才有出站(回消息)能力。必须显式给出,不从 REMOTE_URL 推导。
|
||
# CHANNEL_QQ_OBV11_API_BASE_URL=
|
||
# http+server 接收上报的路径,默认 /(缺前导 / 会自动补齐)。
|
||
# CHANNEL_QQ_OBV11_REPORT_PATH=/
|
||
# 可选 OneBot access_token,四端通用:出站走 Authorization: Bearer;http+server 入站侧
|
||
# fail-closed——配了则 Bearer 或 ?access_token= 不匹配回 403,为空则放行(勿写日志/提交)。
|
||
# CHANNEL_QQ_OBV11_ACCESS_TOKEN=
|
||
# 机器人自己的 QQ 号(已知时填写,用于识别自消息)。
|
||
# CHANNEL_QQ_OBV11_SELF_ID=
|
||
|
||
# ---- 通用 Webhook 渠道(入站专用) ----
|
||
# 回调由网关挂在上面的唯一端口上,不新开监听。全部字段可选且都有可用默认值,
|
||
# 空配置也是一个能接请求的端点;该平台无 token 门槛,configured 闸门对 webhook 恒放行。
|
||
# ENDPOINT_PATH 是该适配器在网关上的路由,默认 /webhook。
|
||
# CHANNEL_WEBHOOK_ENDPOINT_PATH=/webhook
|
||
# CHANNEL_ID / CHANNEL_NAME 只用于向 ListChannels 报告该渠道(留空 = 不预注册渠道)。
|
||
# CHANNEL_WEBHOOK_CHANNEL_ID=
|
||
# CHANNEL_WEBHOOK_CHANNEL_NAME=
|
||
# ⚠️ SECRET 非空才对请求体做 HMAC-SHA256 验签;留空 = 【关闭验签】,任何能访问该路径的请求
|
||
# 都会被当消息收下。对公网暴露时务必填写(敏感,勿写日志/提交)。
|
||
# CHANNEL_WEBHOOK_SECRET=
|
||
# 承载签名的请求头名,默认 X-Webhook-Signature。
|
||
# CHANNEL_WEBHOOK_SIGNATURE_HEADER=X-Webhook-Signature
|
||
|
||
# ---- 微信 iLink 渠道 ----
|
||
# bot_token 为空时该账号【不存在】(同 Telegram),configured 闸门要求它非空才连接。
|
||
# CHANNEL_WEIXIN_ILINK_BOT_TOKEN 是扫码登录得到的长期 bearer token:非空即跳过二维码流程
|
||
# (敏感,勿写日志/提交)。
|
||
# CHANNEL_WEIXIN_ILINK_BOT_TOKEN=
|
||
# BOT_ID = 登录确认返回的 ilink_bot_id;OWNER_ID = 已绑定主人的 ilink_user_id
|
||
# (用于把该渠道的主人身份对上:身份判定仍只看渠道层 actor 元数据,不看提示词)。
|
||
# CHANNEL_WEIXIN_ILINK_BOT_ID=
|
||
# CHANNEL_WEIXIN_ILINK_OWNER_ID=
|
||
# API 根地址与媒体 CDN 根地址;留空用协议默认值:
|
||
# https://ilinkai.weixin.qq.com 与 https://novac2c.cdn.weixin.qq.com/c2c。
|
||
# CHANNEL_WEIXIN_ILINK_BASE_URL=
|
||
# CHANNEL_WEIXIN_ILINK_CDN_BASE_URL=
|
||
|
||
# ---- IM 多账号 / 黑白名单(可选,design/16 §4.6 §5-6) ----
|
||
# ⚠️ 本节是【兜底】:管理面板「渠道管理」页保存会写入本地 channels.json(默认 <DATA_DIR>/channels.json,已 gitignore),
|
||
# 只要 channels.json 存在且有效,运行中的渠道 adapter 就优先用它的多平台账号配置,并支持面板实时保存→热更新(无需重启)。
|
||
# 仅当 channels.json 不存在/无效时才回退到下面的 CHANNELS_JSON 与 CHANNEL_<NAME>_*。
|
||
# 业务·高级项(接收模式 receive_mode / webhook 回调路由与 verify_token、encrypt_key / 黑白名单 / 限流)
|
||
# 一律在管理面板「渠道管理」配置:写 channels.json、热更新;.env 仅作无文件时的必要连接回退(token/base_url 等)。
|
||
# 单账号仍走上面 CHANNEL_<NAME>_* 环境变量;这里提供独立的 JSON 注册表,
|
||
# 支持同一平台配多个接入配置(多账号),并配群聊/私聊黑白名单(代码层拦截,
|
||
# 被拉黑/不在白名单的群或用户消息不进 LLM,且有审计)。形如:
|
||
# CHANNELS_JSON={"telegram":[{"id":"conf0","config":{"bot_token":"..."},"denyUsers":["12345"],"denyGroups":["-100"]}]}
|
||
# 每个 account 字段:id(平台内唯一)、config(平台特有凭据 map)、
|
||
# allowGroups/denyGroups(群黑白名单,allowGroups 非空则成为白名单)、
|
||
# allowUsers/denyUsers(私聊用户黑白名单)。未配置时按单账号 env 路径处理。
|
||
# 群/总限流与总上限(可选,design/12 §6 策略三/四,公共平台防刷屏/最小化打扰):
|
||
# groupMsgPerMin 群聊每分钟上限(0=用默认6,-1=不限,正整数=该值)
|
||
# directMsgPerMin 非主人(陌生人)私聊每分钟每发送者上限(0=用默认6,-1=关闭,正整数=该值)
|
||
# msgPerMin 非主人消息每分钟总上限(>0 生效,0/-1=不限)
|
||
# maxMessages 待处理上限,接近上限时由审查模型剔除低价值消息(0=用默认50,-1=不限,正整数=该值)
|
||
# 旧账号不配这些字段默认走「保护性默认/不限」,保持向后兼容。
|
||
# CHANNELS_JSON=
|