-
Notifications
You must be signed in to change notification settings - Fork 7.1k
Expand file tree
/
Copy pathenv.ts
More file actions
152 lines (131 loc) · 6.9 KB
/
env.ts
File metadata and controls
152 lines (131 loc) · 6.9 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
import { createEnv } from '@t3-oss/env-core';
import z from 'zod';
const truthyBoolStrs = ['true', '1', 'yes', 'y'];
const BoolSchema = z
.string()
.transform((val) => truthyBoolStrs.includes(val.toLowerCase()))
.pipe(z.boolean());
const NumSchema = z.coerce.number<number>();
const IntSchema = NumSchema.int().nonnegative();
// 枚举
const LogLevelSchema = z.enum(['trace', 'debug', 'info', 'warning', 'error', 'fatal']);
const StorageVendorSchema = z.enum(['minio', 'aws-s3', 'cos', 'oss']);
const StorageCosProtocolSchema = z.enum(['https:', 'http:']);
export const env = createEnv({
server: {
FILE_TOKEN_KEY: z.string().min(6, 'FILE_TOKEN_KEY must be at least 6 characters'),
// ===== Agent sandbox =====
AGENT_SANDBOX_PROVIDER: z.enum(['sealosdevbox', 'opensandbox', 'e2b']).optional(),
AGENT_SANDBOX_E2B_API_KEY: z.string().optional(),
AGENT_SANDBOX_SEALOS_BASEURL: z.string().url().optional(),
AGENT_SANDBOX_SEALOS_TOKEN: z.string().optional(),
AGENT_SANDBOX_OPENSANDBOX_BASEURL: z.string().url().optional(),
AGENT_SANDBOX_OPENSANDBOX_API_KEY: z.string().optional(),
AGENT_SANDBOX_OPENSANDBOX_RUNTIME: z.enum(['docker', 'kubernetes']).default('docker'),
AGENT_SANDBOX_OPENSANDBOX_IMAGE_REPO: z.string().optional(),
AGENT_SANDBOX_OPENSANDBOX_IMAGE_TAG: z.string().default('latest'),
AGENT_SANDBOX_OPENSANDBOX_USE_SERVER_PROXY: BoolSchema.default(true),
AGENT_SANDBOX_ENABLE_VOLUME: BoolSchema.default(false),
AGENT_SANDBOX_VOLUME_MANAGER_URL: z.string().url().optional(),
AGENT_SANDBOX_VOLUME_MANAGER_TOKEN: z.string().optional(),
AGENT_SANDBOX_VOLUME_MANAGER_MOUNT_PATH: z.string().default('/workspace'),
AGENT_SKILL_MAX_UPLOAD_SIZE: NumSchema.optional(),
AGENT_SKILL_MAX_UNCOMPRESSED_SIZE: NumSchema.optional(),
AGENT_SKILL_MAX_DOWNLOAD_SIZE: NumSchema.optional(),
AGENT_SKILL_MAX_SANDBOX_SIZE: NumSchema.optional(),
AGENT_SANDBOX_MAX_EDIT_DEBUG: NumSchema.optional(),
AGENT_SANDBOX_MAX_SESSION_RUNTIME: NumSchema.optional(),
// 对象存储
STORAGE_VENDOR: StorageVendorSchema.default('minio'),
STORAGE_PUBLIC_BUCKET: z.string().default('fastgpt-public'),
STORAGE_PRIVATE_BUCKET: z.string().default('fastgpt-private'),
STORAGE_REGION: z.string().default('us-east-1'),
STORAGE_EXTERNAL_ENDPOINT: z.string().optional(),
STORAGE_S3_ENDPOINT: z.string().default('http://localhost:9000'),
STORAGE_PUBLIC_ACCESS_EXTRA_SUB_PATH: z.string().optional(),
STORAGE_ACCESS_KEY_ID: z.string().default('minioadmin'),
STORAGE_SECRET_ACCESS_KEY: z.string().default('minioadmin'),
STORAGE_S3_FORCE_PATH_STYLE: BoolSchema.default(false),
STORAGE_S3_MAX_RETRIES: IntSchema.default(3),
STORAGE_COS_PROTOCOL: StorageCosProtocolSchema.default('https:'),
STORAGE_COS_USE_ACCELERATE: BoolSchema.default(false),
STORAGE_COS_CNAME_DOMAIN: z.string().optional(),
STORAGE_COS_PROXY: z.string().optional(),
STORAGE_OSS_ENDPOINT: z.string().optional(),
STORAGE_OSS_CNAME: BoolSchema.default(false),
STORAGE_OSS_INTERNAL: BoolSchema.default(false),
STORAGE_OSS_SECURE: BoolSchema.default(false),
STORAGE_OSS_ENABLE_PROXY: BoolSchema.default(true),
// ===== Logging =====
LOG_ENABLE_CONSOLE: BoolSchema.default(true),
LOG_CONSOLE_LEVEL: LogLevelSchema.default('debug'),
LOG_ENABLE_OTEL: BoolSchema.default(false),
LOG_OTEL_LEVEL: LogLevelSchema.default('info'),
LOG_OTEL_SERVICE_NAME: z.string().default('fastgpt-client'),
LOG_OTEL_URL: z.url().optional(),
METRICS_ENABLE_OTEL: BoolSchema.default(false),
METRICS_EXPORT_INTERVAL: NumSchema.int().positive().default(30000),
METRICS_OTEL_SERVICE_NAME: z.string().default('fastgpt-client'),
METRICS_OTEL_URL: z.url().optional(),
TRACING_ENABLE_OTEL: BoolSchema.default(false),
TRACING_OTEL_SERVICE_NAME: z.string().default('fastgpt-client'),
TRACING_OTEL_URL: z.url().optional(),
TRACING_OTEL_SAMPLE_RATIO: NumSchema.min(0).max(1).optional(),
APP_FOLDER_MAX_AMOUNT: NumSchema.int().positive().default(1000),
DATASET_FOLDER_MAX_AMOUNT: NumSchema.int().positive().default(1000),
// ===== Workflow =====
/** Max length of loop / parallelRun input array. */
WORKFLOW_MAX_LOOP_TIMES: NumSchema.int()
.min(1)
.max(10000)
.optional()
.default(100)
.meta({ description: '循环节点最大循环次数' }),
/** Env upper bound for parallelRun concurrency. Must not exceed WORKFLOW_MAX_LOOP_TIMES. */
WORKFLOW_PARALLEL_MAX_CONCURRENCY: NumSchema.int()
.min(5)
.max(1000)
.optional()
.default(10)
.meta({ description: '并行节点最大并发数' }),
// ===== Security =====
CHECK_INTERNAL_IP: BoolSchema.default(false).meta({
description: '是否启用内网 IP 检查'
}),
USE_IP_LIMIT: BoolSchema.default(true).meta({ description: '是否启用 IP 限制' }),
TRUSTED_PROXY_IPS: z.string().optional().meta({
description:
'可信反向代理 IP/CIDR 列表,逗号或空白分隔。生产环境默认不信任任何代理;仅显式可信代理传入的 X-Forwarded-For/X-Real-IP 会用于客户端 IP 解析'
}),
/** Redis 流式镜像续期:生成中(秒) */
STREAM_RESUME_TTL_SECONDS: IntSchema.positive().default(5 * 60),
/** 流结束后缩短 TTL,便于回收(秒) */
STREAM_RESUME_POST_COMPLETE_TTL_SECONDS: IntSchema.positive().default(30),
/** 当 Redis 已用内存 / maxmemory 达到该阈值时,停止为新请求创建流恢复镜像 */
STREAM_RESUME_REDIS_MAXMEMORY_RATIO: NumSchema.positive().max(1).default(0.5),
/** Redis 内存水位检测缓存时长(毫秒),避免每个流请求都调用 INFO MEMORY */
STREAM_RESUME_REDIS_MEMORY_CHECK_INTERVAL_MS: IntSchema.positive().default(5000),
// ===== Wechat outLink =====
/** 微信渠道 poll worker 并发数,需 ≥ online shareId 峰值,否则消息延迟会线性恶化 */
WECHAT_CHANNEL_CONCURRENCY: NumSchema.int().positive().default(1000).meta({
description: '微信渠道 poll worker 并发数'
}),
// Beta features
// Whether the Skill feature is enabled (frontend entries + backend runtime)
SHOW_SKILL: BoolSchema.default(false),
// Agent engine selection: 'default' uses the built-in Plan+Step engine, 'pi' uses pi-agent-core
AGENT_ENGINE: z.enum(['default', 'pi']).default('default'),
SKIP_FILE_TYPE_CHECK: BoolSchema.default(false)
},
emptyStringAsUndefined: true,
runtimeEnv: process.env,
onValidationError(issues) {
const paths = issues.map((issue) => issue.path).join(', ');
throw new Error(`Invalid environment variables. Please check: ${paths}\n`);
}
});
if (env.WORKFLOW_PARALLEL_MAX_CONCURRENCY > env.WORKFLOW_MAX_LOOP_TIMES) {
throw new Error(
`Invalid environment configuration: WORKFLOW_PARALLEL_MAX_CONCURRENCY (${env.WORKFLOW_PARALLEL_MAX_CONCURRENCY}) must not exceed WORKFLOW_MAX_LOOP_TIMES (${env.WORKFLOW_MAX_LOOP_TIMES})`
);
}