-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy path.env.example
More file actions
280 lines (256 loc) · 17.2 KB
/
Copy path.env.example
File metadata and controls
280 lines (256 loc) · 17.2 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
# Hunter Community Edition · P1 skeleton env
#
# ⚠️ 自 v1.1.0 起 **.env 不是必需的**:`git clone` 后直接 `docker compose up -d`
# 就能起来(JWT_SECRET 会自动生成,大模型可以之后再配)。想改端口、接自己的
# 大模型、填平台 key 时才 `cp .env.example .env`。
#
# All values below have working defaults for local dev.
# For production: set a strong POSTGRES_PASSWORD, and add your LLM_API_KEY.
# ─── 镜像版本与仓库 ─────────────────────────────────────────
# 默认编排(docker-compose.yml)只用预构建镜像,这两个变量决定拉哪一个。
#
# HUNTER_VERSION · **钉具体版本,别用 latest**。浮动标签意味着某次
# `docker compose pull` 会无声换掉运行的代码,出了问题连「什么时候变的」
# 都查不出来。升级就是改这一行然后 `docker compose pull && up -d`。
# HUNTER_REGISTRY · 镜像仓库前缀(不含镜像名)。默认 GHCR,匿名可拉。
# 换自建 registry / 国内镜像站时改这里,例如
# HUNTER_REGISTRY=registry.example.com/mynamespace
# Docker Hub / 阿里云 ACR 的官方分发**规划中**,暂未提供,填了也拉不到。
#
# 想用本地构建的镜像,别改这两个 —— 叠加开发覆盖文件:
# docker compose -f docker-compose.yml -f docker-compose.dev.yml up -d
HUNTER_VERSION=1.2.0
HUNTER_REGISTRY=ghcr.io/agentpit-io
# ─── Boot mode ─────────────────────────────────────────────
# When 1, skip background schedulers (collector, signal_monitor, gm_alerts,
# backtest, stocks_catalog seed) that need external creds like LLM_API_KEY.
# DDL is always run · table-backed features (auth · watchlist · settings) work
# regardless. Set to 0 once you've filled in LLM_API_KEY + HUNTER_SAAS_DATA_KEY
# (or configured local akshare/yfinance providers) to enable the full features.
HUNTER_MINIMAL_BOOT=1
# ─── 监听地址(几乎所有人都不用动)──────────────────────────
# api / opencode / llm-shim / web 监听哪个地址。默认 0.0.0.0(IPv4 全部网卡)。
# 需要改的只有一种情况:**Railway 的老环境**(2025-10-16 之前创建)私有网络是
# IPv6-only,绑 0.0.0.0 的服务在那里互相连不上,要设成 `::`(双栈,v4/v6 都收)。
# 见 docs/deploy/railway.md 与 https://docs.railway.com/networking/private-networking/how-it-works
# HUNTER_BIND_HOST=::
# 魔法筛选器:两次扫描的间隔 / 扫完倒数几秒再出结果。默认 5 秒(多人共用时替所有人省上游数据源)。
# 只有自己一个人用的本地部署可以设 0 = 扫完立刻显示。上游取数缓存与并发限制不受影响。
# SCREEN_SCAN_GAP_S=5
# ─── Host port mapping ──────────────────────────────────────
# We use non-standard host ports to avoid conflict with hermes / VLLM / opencode
# on shared machines like fin-r1.
WEB_HOST_PORT=3100
API_HOST_PORT=8100
POSTGRES_HOST_PORT=5442
REDIS_HOST_PORT=6479
# OPENCODE_HOST_PORT=3921
# ─── Postgres ──────────────────────────────────────────────
POSTGRES_USER=hunter
POSTGRES_PASSWORD=hunter
POSTGRES_DB=hunter
# ─── Local Auth (P3) ───────────────────────────────────────
# JWT_SECRET · 签发 / 验签登录 token,同时也是数据库里各种 key 的加密密钥。
#
# **留空即可** —— 首次启动时 api 会自己生成一把,写进 hunter_secrets 卷,
# opencode 以只读方式挂同一个卷读到同一把(两边必须同值:api 签发的 token
# 要由 opencode 的 hunter-auth 插件验签才能认出用户,取值不同的话服务照常
# 启动、只是对话莫名 401)。
#
# ⚠️ **更换或丢失 JWT_SECRET = 已保存的 key 全部解不开、需要重新填写。**
# 自动生成的那把活在 Docker 卷里,`docker compose down -v` 会一起删掉。
# 要自己指定就填在下面(生成:openssl rand -base64 48),填了就**别再改**;
# 也别把示例值当成密钥用 —— 它是公开的。
JWT_SECRET=
JWT_ACCESS_TTL=3600
JWT_REFRESH_TTL=2592000
# ─── 首启向导的初始化口令(M2 · 设计方案 4.2)────────────────
# 第一次打开浏览器时的「初始化向导」要不要先输口令。
#
# 留空 = 本机 / 内网直接进向导(git clone && docker compose up -d 的主路径)
# 非空 = **一律要口令**,不管来源看起来是本机还是公网
#
# ⚠️ **这台实例只要能从公网打开,就必须设**。不设的话,谁先打开这个页面谁就能
# 配置大模型、看到实例的运行状态。向导第 1 步会对"没设口令"打黄色警告。
#
# 为什么不能只靠"来源是不是公网"这个判断:来源取自 HTTP 转发头。
# 前面有 nginx 这类反代时它是可信的(X-Real-IP 是覆盖写、XFF 取最右边那一项);
# 但**裸 docker compose、没有任何反代**时,访问者自己带一个
# `X-Forwarded-For: 127.0.0.1` 就能把自己伪装成本机,协议层分不出来。
# 「有没有口令」伪造不了,所以口令一旦设了就一律校验。
# 连错 5 次锁 15 分钟;通过后签发 30 分钟的初始化会话。
#
# 生成一个:openssl rand -base64 24
# HUNTER_SETUP_TOKEN=
# ─── Single-user mode (ON by default) ──────────────────────
# It's your own machine, so there is no login screen: the frontend silently
# gets a session for one built-in local account and you land straight in the app.
#
# ⚠️ Set to 0 the moment this instance is reachable by anyone but you.
# With it on, ANY request to /api/auth/local-session gets an admin token —
# no reverse proxy in front can tell the difference.
# Turning it off brings back /login + /register (first account = admin).
HUNTER_SINGLE_USER=1
# HUNTER_LOCAL_USER_EMAIL=local@hunter.local
# Registration policy (only matters when HUNTER_SINGLE_USER=0): open · invite · closed
# open = anyone can register (first user auto-admin)
# invite = requires code from admin (first user still auto-admin)
# closed = registration disabled entirely
REGISTRATION_MODE=open
# Comma-separated admin email allowlist (used by /api/backtest/run guard until P4)
# HUNTER_ADMIN_EMAILS=admin@example.com,ops@example.com
# 合规灰度 · strict=改写+打标+免责 · permissive=只免责 · off=关(灾备)
HUNTER_COMPLIANCE_MODE=strict
# ═══════════════════════════════════════════════════════════════════════
# ⭐ 唯一必填项 · HUNTER_API_KEY · 一把 key 走遍全部功能
# ═══════════════════════════════════════════════════════════════════════
#
# hunter-community 只需要 **一把** hunter-side key,不管是:
# · Kronos 走势预测 · 关键新闻
# · K 线数据 / 财报 / 行情 · UZI 深度分析
# · 任何走 hunter.agentpit.io/api/saas/* 的功能
# 全部用同一个 HUNTER_API_KEY,由服务端按 key 归属计量、限流、鉴权。
# 你会在 .env 下方看到 HUNTER_SAAS_DATA_KEY / HUNTER_SAAS_KRONOS_KEY —— 那些
# 是"分设独立 key 想分账"时才用的高级覆盖,**留空即自动 fallback 到本 key**。
#
# 申请: https://hunter.agentpit.io/dev/api-keys 免费 · 约 30 秒
#
# 两种填法:
# 1. 直接在下方 uncomment 填入 · docker compose up -d 生效(推荐)
# 2. 留空 · UI 左下角「解锁全部工具」粘贴 · 立即生效不用重启
#
# ⚠️ 不填 = 工具/SKILL/预测**全部 403** · 聊天仍可用(走你自己的 LLM_API_KEY)
# HUNTER_API_KEY=hunt_tools_xxxxxxxxxxxxxxxx
# ─── Pluggable providers (P4) ──────────────────────────────
# Data source: hunter · saas · akshare (A-shares · no key) · yfinance (US/HK)
# 留空 = auto:配了 HUNTER_API_KEY 走 hunter,否则 akshare。想显式设也行。
DATA_SOURCE_PROVIDER=
# ─── Hunter 数据源(一 key 通用 · §3 的 HUNTER_API_KEY 就够)──────────────
# 客户端默认走 https://hunter.agentpit.io/api/saas/data/* 网关中转 ·
# 服务端替你注入 finance-data 的内部 X-Finance-Token · 无需额外配置。
# 深度分析 Sentinel 抓 60+ 条新闻自动生效。
#
# 私有部署 finance-data 才需要覆盖以下变量(客户端检测到 URL 不含
# /api/saas/data 会切到 X-Finance-Token 直连模式):
# FINANCE_DATA_URL=https://your.finance-data.example.com
# FINANCE_DATA_TOKEN=<your shared token>
# ═══════════════════════════════════════════════════════════════════════
# 大模型 · 这一整段都可以不填(推荐)
# ═══════════════════════════════════════════════════════════════════════
#
# **推荐路径:浏览器里的首启向导 → 第 2 步第一张卡「使用 HunterCode 内置额度」。**
# 那条路只需要一把免费的 `hunt_tools_` 平台 key(和工具、数据源共用同一把),
# 地址与模型名向导自动填好,深度分析也会自动指向 hunter-deep;每天有免费 token 额度,
# 用完在对话里会用中文说清什么时候重置、怎么改用自带 key。
# 隐私:网关只记 token 数与模型名,**不记任何 prompt 与回复内容**。
# 说明见 docs/builtin-llm/使用说明.md。
#
# 下面这三项是**高级路径**(自带大模型 key)。两个用法:
# · 留空 → 向导里选「自带 key」的卡片,填完当场检测三项,加密存进本机数据库;
# · 填了 → 这台实例就是**锁定**状态,向导只读展示、改不了它(演示站就这么跑的)。
# 换模型要改这里再 `docker compose up -d`(**不是 restart** —— restart 不重读 .env)。
#
# 三项**留空也能把服务起起来**:六个容器都会健康,只是没配大模型之前不能对话。
# 填一半比不填更糟:上游 401 会被吞成一条空消息,前端只显示「深度思考完成」
# 没有正文,极难排查。要填就三项一起填。
#
# 想在 .env 里写死内置额度(例如一键部署模板预填)也可以,三项这么写:
# LLM_BASE_URL=https://hunter.agentpit.io/api/saas/llm/v1
# LLM_API_KEY=hunt_tools_xxxxxxxxxxxxxxxx ← 就是平台 key,不用第二把
# LLM_DEFAULT_MODEL=hunter-chat
# LLM_SCHEMA_SANITIZE=0 ← 清洗在网关做,本地不用再过一遍
# 这么写时深度分析那批模型变量要自己填(见本文件「深度分析 / 子智能体的模型名」一节),
# 走向导的话它们由向导自动写好,不用管。
LLM_PROVIDER=openai_compat
LLM_BASE_URL=
LLM_API_KEY=
LLM_DEFAULT_MODEL=
# Tool-schema shim(scripts/llm-shim/shim.py)开关
# auto(默认) = 模型名含 gemini 才走 shim,其余直连
# 1 = 全部走 shim,任何模型都清洗一遍
# 0 = 从不走 shim
# DeepSeek(deepseek-v4-flash / deepseek-v4-pro)必须设 1,否则某些 MCP 工具
# 会送 `parameters: null` 让 DeepSeek 400「Invalid schema ... type: "null"」,
# 表现是气泡里只有"深度思考完成"没有正文。见 docs/02-providers.md。
# 内置额度(hunter-chat / hunter-deep)用 **0**:清洗在网关做,本地再走一遍只是多一跳。
# LLM_SCHEMA_SANITIZE=auto
# ─── 深度分析 / 子智能体的模型名 · 正常不用填 ────────────────────────
# 取值优先级:**这里非空 → 数据库(首启向导写入)→ 代码默认值**。
# · 走内置额度 → 向导自动写好(对话类 hunter-chat、深度分析 hunter-deep),这里留空;
# · 自带 key → 留空即用代码默认值(gemini-3.5-flash 一档);上游不认 gemini 模型名时
# (DeepSeek / Anthropic 直连)在这里按你的上游填一遍,否则深度分析会 400。
# ASSISTANT_MODEL_ROUTE=
# ASSISTANT_MODEL_CHAT=
# ASSISTANT_MODEL_COMPRESS=
# AGENT_MODEL_ROUTER=
# AGENT_MODEL_ROUTE_LITE=
# AGENT_MODEL_GENERAL_FINANCE=
# AGENT_SUB_WL_MODEL=
# AGENT_SUB_PORT_MODEL=
# AGENT_SUB_EVENT_MODEL=
# AGENT_SUB_RESEARCH_MODEL=
# AGENT_SUB_UZI_MODEL=
# SIGNAL_ANALYSIS_MODEL=
# Forecast: kronos_saas (default · 走 hunter 网关 · 只需上面那把 HUNTER_API_KEY)
# kronos_local (自建 GPU) · noop (关掉,左侧不显示走势预测)
# 留空即 kronos_saas。以前默认 noop 是因为当时 Kronos 接不上 ——
# 它曾要求 HUNTER_SAAS_KRONOS_KEY=hunt_kron_...,而平台**从没签发过这个前缀**,
# 用户点了会被提示去申请一把根本不存在的 key。网关打通后这条死路已经拆掉。
FORECAST_PROVIDER=
# KRONOS_LOCAL_URL=http://kronos:8188 # 自建 GPU 时才填
# ─── 应急回退 · 正常不用填 ──────────────────────────────────
# Kronos / TrueSource 默认经 hunter.agentpit.io 网关中转(校验 key + 记流量 +
# 隐藏上游)。万一网关出问题,填下面两行可立即回退到直连上游:
# KRONOS_URL=https://kronos.agentpit.io
# TRUESOURCE_API_URL=https://truesource.agentpit.io
# ─── 宿主机代理(可选)────────────────────────────────────────
# 容器连外网超时(macOS 开了 Clash / Verge 等 TUN 代理),或网关拦截容器直连
# (aihubmix 会报 SSL UNEXPECTED_EOF)时填写,指向宿主机上的代理端口。
# api 取数据与 llm-shim 调大模型共用这组变量;留空不走代理。
# HTTP_PROXY_UPSTREAM=http://host.docker.internal:7890
# HTTPS_PROXY_UPSTREAM=http://host.docker.internal:7890
# NO_PROXY_UPSTREAM 一般不用填 —— 默认已排除内部服务名,自己填时务必保留它们
# NO_PROXY_UPSTREAM=localhost,127.0.0.1,api,web,postgres,redis,opencode,llm-shim
# ─── Frontend ──────────────────────────────────────────────
# 浏览器访问 API 的地址。前端代码读的是 NEXT_PUBLIC_API_URL(app/login/page.tsx 等
# 6 处),不是 _BASE —— 名字写错的话取值一律回落成空串(见下)。
#
# 留空 = 走同源相对路径 /api/*。**留空就是对的**,两种部署形态都能通:
# · 前面有 nginx 反代(演示站)→ nginx 把 /api/ 转给后端;
# · 直接 docker compose up(没有反代)→ web 自己有一条 catch-all BFF
# (apps/web/app/api/[...path]/route.ts)把 /api/* 原样转发到 api 容器。
#
# ⚠️ NEXT_PUBLIC_* 是**构建期**烘进前端产物的。官方预构建镜像烘的就是空值,
# 所以在默认部署里**改这一行不会有任何效果** —— 要改必须自己重新构建 web:
# docker compose -f docker-compose.yml -f docker-compose.dev.yml up -d --build web
NEXT_PUBLIC_API_URL=
# ─── OpenCode chat engine (对话引擎镜像) ──────────────────────
# ⚠️ OPENCODE_REGISTRY / OPENCODE_TAG 自 v1.1.0 起**不再被 docker-compose.yml 读取**。
# opencode 服务改用自家包装镜像 hunter-community-opencode(deploy/opencode.Dockerfile,
# 它 FROM huntercode 的 hunter-opencode:1.18.12-slim.1 并把入口脚本 / MCP /
# 插件 / SKILL 都 COPY 了进去),版本与仓库由上面的 HUNTER_VERSION /
# HUNTER_REGISTRY 统一控制。
# 这两行留在这里只是为了让老 .env 里写着它们的人知道「改了为什么没反应」;
# 要换基础镜像版本,改 deploy/opencode.Dockerfile 的 FROM 并重新构建。
# OPENCODE_REGISTRY=ghcr.io/agentpit-io
# OPENCODE_TAG=1.18.12-slim.1
OPENCODE_USER=opencode
OPENCODE_PASS=changeme
# Shared secret between the opencode and api containers for internal MCP
# callbacks (/api/internal/*). Both containers must see the SAME value.
# Fine as-is for a local instance; regenerate before exposing anything:
# openssl rand -hex 20
HUNTER_INTERNAL_KEY=hunter-internal-local
# Budget plugin (LLM token cap). You pay your own LLM bill, so it's off here.
# 钉在 1.18.12-slim.1 之前的老镜像不认这个开关,靠 docker-compose.yml 里
# HUNTER_BUDGET_DAILY / _PER_REQUEST 两个大得离谱的值把它架空。
HUNTER_BUDGET_ENABLED=false
# MCP 工具超时(毫秒)· 留空按默认走(hunter_cap 180000 · screener 60000)。
# 换了更慢的后端(自建 Kronos 推理、上游网关排队)导致工具被掐断时才需要调大 ——
# 症状是模型回「服务不可用」而日志里看不到任何超时字样。
# HUNTER_MCP_TIMEOUT_MS=180000
#
# 深度分析(uzi MCP)调后端的读超时(秒)· 默认 170。
# 必须**小于** HUNTER_MCP_TIMEOUT_MS / 1000,否则 opencode 先掐断,
# 模型拿到的是 "(pending / no output)",看不出是超时。
# UZI_HTTP_TIMEOUT=170