Repository navigation
Expand file tree
/
Copy pathconfig.toml.example
More file actions
253 lines (217 loc) · 11.1 KB
/
Copy pathconfig.toml.example
File metadata and controls
253 lines (217 loc) · 11.1 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
# ==============================================
# AINS Shared Configuration File
# ==============================================
# Copy this file to config.toml and update values for your environment
# This configuration is shared between server and frontend (app)
# Database connection URL (PostgreSQL)
# Replace CHANGE_ME_POSTGRES_PASSWORD with a strong password
# Format: postgres://user:password@host:port/database
# Can be overridden by environment variable: AINS_DATABASE_URL
database_url = "postgres://ains:CHANGE_ME_POSTGRES_PASSWORD@127.0.0.1:5432/ains"
# Redis connection URL (for caching, distributed locking, and rate limiting)
# NOTE: When using Docker Compose, this is overridden by AINS_REDIS_URL
# which includes the Redis password. Make sure to include the password
# if your Redis instance has requirepass enabled.
# ⚠️ Use percent-encoding for special characters in the password
# (e.g., p%40ss for p@ss, p%2Fss for p/ss).
# To avoid this, generate passwords with: openssl rand -hex 32
# Format: redis://[:password]@host:port
# Can be overridden by environment variable: AINS_REDIS_URL
redis_url = "redis://:CHANGE_ME_REDIS_PASSWORD@127.0.0.1:6379"
# Redis cache connection pool size (default: 10)
# Maximum number of concurrent connections for the bb8 Redis cache pool.
# Increase this if the application handles many concurrent cache operations.
# Can be overridden by environment variable: AINS_CACHE_MAX_CONNECTIONS
cache_max_connections = 10
# Read replica database URLs (empty = disabled, backward compatible)
# When configured, SELECT queries are automatically routed to read replicas
# while INSERT/UPDATE/DELETE always go to the write database.
# Can be overridden by environment variable: AINS_DATABASE_READ_URLS
# Environment variable format: comma-separated list
# Example: export AINS_DATABASE_READ_URLS="postgres://user:pass@replica1:5432/ains,postgres://user:pass@replica2:5432/ains"
database_read_urls = []
# ⚠️ SECURITY WARNING: MUST change this in production!
# Generate a strong secret with: openssl rand -base64 64
# The server will refuse to start with this placeholder in non-development mode.
# Can be overridden by environment variable: AINS_JWT_SECRET
jwt_secret = "REPLACE_ME_WITH_A_STRONG_SECRET"
# Encryption key for AI Gateway channel API keys (AES-256-GCM).
# If not set, falls back to jwt_secret (not recommended for production).
# Generate with: openssl rand -base64 32
# Can be overridden by environment variable: AINS_GATEWAY_ENCRYPTION_KEY
gateway_encryption_key = ""
# Whether to disable system HTTP proxy for all outbound reqwest clients.
# When true, the server bypasses HTTP_PROXY / HTTPS_PROXY environment
# variables and connects directly. Useful in container/development
# environments where system proxy is not configured or interferes with
# local connections (e.g. wiremock mock servers in tests).
# Default: false (use system proxy if configured).
# Can be overridden by environment variable: AINS_SYS_NO_PROXY
# sys_no_proxy = false
# JWT token expiration time in seconds (default: 1 hour)
# Can be overridden by environment variable: AINS_JWT_EXPIRY_SECONDS
jwt_expiry_seconds = 3600
# JWT expiration when "remember me" is enabled (default: 30 days)
# Can be overridden by environment variable: AINS_JWT_REMEMBER_EXPIRY_SECONDS
jwt_remember_expiry_seconds = 2592000
# Refresh token expiration time in seconds (default: 90 days)
# Refresh tokens are used for silent JWT renewal when the JWT expires.
# Can be overridden by environment variable: AINS_REFRESH_TOKEN_EXPIRY_SECONDS
refresh_token_expiry_seconds = 7776000
# Whether to set the Secure flag on auth cookies (default: true)
# Set to false for local development over plain HTTP.
# MUST be true in production (requires HTTPS).
# Can be overridden by environment variable: AINS_COOKIE_SECURE
cookie_secure = true
# System admin account (auto-seeded on first boot, only one can exist)
# The system admin has super-admin privileges (bypasses all admin-only restrictions)
# ⚠️ SECURITY: MUST override these in staging/production environments!
# The server will refuse to start with default values in non-development mode.
# Can be overridden by environment variables: AINS_SYSTEM_ADMIN_EMAIL / AINS_SYSTEM_ADMIN_PASSWORD
system_admin_email = "admin@ains.local"
system_admin_password = "change-me-admin-password"
# Server configuration
[server]
# Server bind address
# Can be overridden by environment variable: AINS_SERVER__HOST
host = "0.0.0.0"
# Server port
# Can be overridden by environment variable: AINS_SERVER__PORT
port = 3000
# Allowed CORS origins (REQUIRED for staging/production environments)
# In non-development mode, the server will log an error and block all
# cross-origin requests if this list is empty.
# Can be overridden by environment variable: AINS_SERVER__ALLOWED_ORIGINS
# Environment variable format: comma-separated list
# Example: export AINS_SERVER__ALLOWED_ORIGINS="https://example.com,https://app.example.com"
# allowed_origins = ["https://example.com", "https://app.example.com"]
# Database connection pool configuration
[database]
# Maximum number of connections in the pool
# Can be overridden by environment variable: AINS_DATABASE__MAX_CONNECTIONS
max_connections = 10
# Minimum number of idle connections to maintain
# Can be overridden by environment variable: AINS_DATABASE__MIN_CONNECTIONS
min_connections = 1
# Connection timeout in seconds
# Can be overridden by environment variable: AINS_DATABASE__CONNECT_TIMEOUT_SECS
connect_timeout_secs = 8
# Idle timeout in seconds
# Can be overridden by environment variable: AINS_DATABASE__IDLE_TIMEOUT_SECS
idle_timeout_secs = 600
# Acquire timeout in seconds
# Can be overridden by environment variable: AINS_DATABASE__ACQUIRE_TIMEOUT_SECS
acquire_timeout_secs = 30
# Read-write routing configuration (optional, has defaults)
[database_routing]
# Read replica selection strategy: round_robin | random | weighted
# Can be overridden by environment variable: AINS_DATABASE_ROUTING__STRATEGY
strategy = "round_robin"
# Weights for each read replica (only applies to weighted strategy).
# MUST align with database_read_urls by index position.
# e.g., database_read_urls = [url_a, url_b] and read_weights = [3, 1]
# means url_a gets weight 3, url_b gets weight 1.
# Can be overridden by environment variable: AINS_DATABASE_ROUTING__READ_WEIGHTS
read_weights = []
# Extra retry attempts after all read replicas have been tried once.
# Each extra attempt tries any non-circuit-broken replica (including those
# that previously failed but whose circuit breaker has expired).
# Can be overridden by environment variable: AINS_DATABASE_ROUTING__RETRY_ATTEMPTS
retry_attempts = 2
# Circuit breaker duration in milliseconds for a failed read replica
# Can be overridden by environment variable: AINS_DATABASE_ROUTING__CIRCUIT_BREAK_MS
circuit_break_ms = 30000
# Fall back to the write database when no healthy read replicas are available
# Can be overridden by environment variable: AINS_DATABASE_ROUTING__FALLBACK_TO_WRITE
fallback_to_write = true
# Background health check interval in seconds (0 = disabled)
# Can be overridden by environment variable: AINS_DATABASE_ROUTING__HEALTH_CHECK_INTERVAL_SECS
health_check_interval_secs = 15
# Read replica connection pool configuration (optional, independent from write pool)
[database_read]
# Maximum number of connections in the pool (default: 20)
# Can be overridden by environment variable: AINS_DATABASE_READ__MAX_CONNECTIONS
max_connections = 20
# Minimum number of idle connections to maintain (default: 2)
# Can be overridden by environment variable: AINS_DATABASE_READ__MIN_CONNECTIONS
min_connections = 2
# Connection timeout in seconds (default: 5, independent from write pool)
# Can be overridden by environment variable: AINS_DATABASE_READ__CONNECT_TIMEOUT_SECS
connect_timeout_secs = 5
# Idle timeout in seconds (default: 600)
# Can be overridden by environment variable: AINS_DATABASE_READ__IDLE_TIMEOUT_SECS
idle_timeout_secs = 600
# Acquire timeout in seconds (default: 10, independent from write pool)
# Can be overridden by environment variable: AINS_DATABASE_READ__ACQUIRE_TIMEOUT_SECS
acquire_timeout_secs = 10
# Email (SMTP) configuration
# When left empty / default, the email service is disabled and registration
# auto-verifies users (useful for development). Configure all fields below to
# enable sending verification and welcome emails.
[email]
# SMTP server hostname
smtp_host = ""
# SMTP port (587 for STARTTLS, 465 for implicit TLS, 25 for plain)
smtp_port = 587
# SMTP authentication username
smtp_username = ""
# SMTP authentication password
smtp_password = ""
# From address for outgoing emails
from_address = ""
# Optional display name for the from address
from_name = "AINS"
# Whether to use TLS (STARTTLS or implicit TLS depending on port)
use_tls = true
# Connection timeout in seconds (0 = no timeout)
timeout_secs = 30
# WeChat Official Account configuration for captcha login
# When enabled, users can log in by sending a keyword (e.g. "验证码") to the
# WeChat Official Account, receiving a captcha code, and entering it on the
# login page.
# All fields below must be properly configured for the feature to work.
[wechat]
# Whether to enable WeChat captcha-login (default: false)
# enabled = true
# Your WeChat Official Account AppID
# app_id = "wx..."
# Your WeChat Official Account AppSecret
# app_secret = "..."
# The Token configured in the WeChat MP backend for signature verification
# token = "..."
# Optional: logical account identifier for multi-account setups
# account_id = "default"
# Optional: encoding AES key for safe mode (43 chars)
# encoding_aes_key = "..."
# Optional: message encryption mode: plain, compatible, safe (default: plain)
# message_mode = "plain"
# Captcha validity in seconds (default: 300)
# captcha_ttl_secs = 300
# Cooldown between captcha requests in seconds (default: 60)
# resend_cooldown_secs = 60
# Max failed attempts before captcha is invalidated (default: 5)
# max_failed_attempts = 5
# Captcha code length (default: 5)
# captcha_len = 5
# Keywords that trigger captcha generation (comma-separated)
# trigger_keywords = ["验证码", "登录码", "login"]
# Welcome text sent when a user subscribes (follows) the account. Because a
# callback URL + Token is configured, the backend "subscribe auto-reply" is
# bypassed, so the server sends this itself. Set to "" to disable the welcome
# and hand subscribe events to the official AI reply instead.
# subscribe_reply = "感谢关注 AINS!发送「验证码」即可获取用于网页端登录的验证码。"
# AI Gateway quota and circuit-breaker configuration
# All fields have sensible defaults — only uncomment if you need to override.
[quota]
# Channel-level max requests per minute (default: 60)
# channel_max_rpm = 60
# Channel-level max tokens per minute (default: 100000)
# channel_max_tpm = 100000
# Tenant-level max requests per minute per capability (default: 600)
# tenant_max_rpm = 600
# Consecutive upstream failures before circuit breaker trips (default: 5)
# cb_failure_threshold = 5
# Seconds to wait before retrying a tripped circuit (default: 60)
# cb_retry_after_secs = 60
# Whether to fail-open (allow requests) when Redis is unavailable (default: true)
# fail_open = true