102 lines
3.1 KiB
TypeScript
102 lines
3.1 KiB
TypeScript
import fs from "node:fs";
|
|
import path from "node:path";
|
|
import process from "node:process";
|
|
import { z } from "zod";
|
|
|
|
const cliAgentSchema = z.object({
|
|
name: z.string().min(1),
|
|
command: z.string().min(1),
|
|
args: z.array(z.string()).default([]),
|
|
inputMode: z.enum(["stdin", "arg"]).default("stdin"),
|
|
timeoutMs: z.number().int().positive().default(120_000),
|
|
outputMaxBytes: z.number().int().positive().default(64_000),
|
|
cwd: z.string().optional()
|
|
});
|
|
|
|
const policySchema = z.object({
|
|
allowedUsers: z.array(z.string()).default([]),
|
|
allowedChats: z.array(z.string()).default([]),
|
|
requireMentionInGroup: z.boolean().default(false)
|
|
});
|
|
|
|
const feishuSchema = z.object({
|
|
enabled: z.boolean().default(false),
|
|
appId: z.string().default(""),
|
|
appSecret: z.string().default(""),
|
|
verificationToken: z.string().default(""),
|
|
botNames: z.array(z.string()).default([])
|
|
});
|
|
|
|
const wecomSchema = z.object({
|
|
enabled: z.boolean().default(false),
|
|
corpId: z.string().default(""),
|
|
agentId: z.string().default(""),
|
|
secret: z.string().default("")
|
|
});
|
|
|
|
const qqSchema = z.object({
|
|
enabled: z.boolean().default(false),
|
|
appId: z.string().default(""),
|
|
clientSecret: z.string().default(""),
|
|
botSecret: z.string().default(""),
|
|
verifySignature: z.boolean().default(true),
|
|
botNames: z.array(z.string()).default([])
|
|
});
|
|
|
|
const webhookSchema = z.object({
|
|
enabled: z.boolean().default(true),
|
|
secret: z.string().default("")
|
|
});
|
|
|
|
const weixinSchema = z.object({
|
|
enabled: z.boolean().default(false),
|
|
mode: z.enum(["external-webhook", "not-implemented"]).default("external-webhook"),
|
|
secret: z.string().default("")
|
|
});
|
|
|
|
export const configSchema = z.object({
|
|
server: z.object({
|
|
host: z.string().default("0.0.0.0"),
|
|
port: z.number().int().positive().max(65_535).default(3000),
|
|
publicBaseUrl: z.string().default("")
|
|
}).default({}),
|
|
policy: policySchema.default({}),
|
|
defaultAgent: z.string().min(1).default("echo"),
|
|
agents: z.array(cliAgentSchema).min(1),
|
|
platforms: z.object({
|
|
feishu: feishuSchema.default({}),
|
|
wecom: wecomSchema.default({}),
|
|
qq: qqSchema.default({}),
|
|
webhook: webhookSchema.default({}),
|
|
weixin: weixinSchema.default({})
|
|
}).default({})
|
|
});
|
|
|
|
export type AppConfig = z.infer<typeof configSchema>;
|
|
export type CliAgentConfig = z.infer<typeof cliAgentSchema>;
|
|
export type GatewayPolicy = z.infer<typeof policySchema>;
|
|
|
|
export function resolveConfigPath(configPath = process.env.GORI_GATEWAY_CONFIG): string {
|
|
return path.resolve(configPath || "config.example.json");
|
|
}
|
|
|
|
export function parseConfig(rawConfig: unknown): AppConfig {
|
|
const config = configSchema.parse(rawConfig);
|
|
|
|
if (!config.agents.some((agent) => agent.name === config.defaultAgent)) {
|
|
throw new Error(`defaultAgent '${config.defaultAgent}' is not present in agents`);
|
|
}
|
|
|
|
return config;
|
|
}
|
|
|
|
export function loadConfig(configPath = process.env.GORI_GATEWAY_CONFIG): AppConfig {
|
|
return loadConfigFromPath(resolveConfigPath(configPath));
|
|
}
|
|
|
|
export function loadConfigFromPath(configPath: string): AppConfig {
|
|
const raw = fs.readFileSync(configPath, "utf8");
|
|
const parsed = JSON.parse(raw) as unknown;
|
|
return parseConfig(parsed);
|
|
}
|