import { __esmMin } from "../../_virtual/_rolldown/runtime.js";
import { checkCacheDir, init_cache_dir_policy } from "../browser/cache-dir-policy.js";
import { init_public_url, validatePublicUrl } from "./public-url.js";
import { TelegramAccountConfigSchema, TelegramConfigSchema, TelegramGroupConfigSchema, TelegramTopicConfigSchema, init_config_schema } from "../../extensions/telegram/src/config-schema.js";
import { WeixinAccountConfigSchema, WeixinConfigSchema, init_config_schema as init_config_schema$1 } from "../../extensions/weixin/src/config-schema.js";
import { z } from "zod";
//#region src/config/schema.ts
/**
* Primary model ref from `agents.defaults.model`. Returns undefined when unset.
*/
function getAgentDefaultModelRef(config) {
	return config.agents?.defaults?.model?.primary?.trim() || void 0;
}
/** `provider/model` or null when invalid. */
function parseModelRef(ref) {
	const trimmed = ref.trim();
	const idx = trimmed.indexOf("/");
	if (idx <= 0 || idx === trimmed.length - 1) return null;
	return {
		provider: trimmed.slice(0, idx).trim(),
		model: trimmed.slice(idx + 1).trim()
	};
}
var AgentModelRefSchema, AgentImageGenerationModelSchema, AgentTypedModelSchema, AgentTypedModelsArraySchema, AgentDefaultsSchema, AgentConfigSchema, AgentsConfigSchema, BindingMatchSchema, BindingRuleSchema, BindingsConfigSchema, SessionDmScopeSchema, SessionStorageConfigSchema, SessionResetModeSchema, SessionResetConfigSchema, SessionResetByTypeSchema, SessionScopeSchema, SessionConfigSchema, ChannelsConfigSchema, SearchProviderEntrySchema, WebSearchConfigSchema, WebsiteBlocklistSchema, WebToolsConfigSchema, ToolsConfigSchema, GatewayAuthRateLimitSchema, GatewaySecuritySchema, GatewayTrustedProxySchema, GatewayAuthSchema, GatewayTailscaleConsentSchema, GatewayTailscaleSchema, GatewayRemoteSchema, GatewayTlsSchema, GatewayModeSchema, HeartbeatConfigSchema, GatewayChannelConnectDeferModeSchema, TunnelConsentSchema, TunnelConfigSchema, WorkspaceImportConfigSchema, WorkspaceConfigSchema, GatewayBindModeSchema, GatewayConfigSchema, CronConfigSchema, ModelsDevConfigSchema, SttProviderConfigCatchallSchema, STTProviderConfigSchema, STTFallbackConfigSchema, MediaUnderstandingCapabilitiesSchema, MediaUnderstandingModelSchema, STTConfigSchema, TtsProviderConfigCatchallSchema, TTSProviderConfigSchema, TTSFallbackConfigSchema, TTSModelOverridesConfigSchema, TTSEdgeConfigSchema, TTSSummarizationConfigSchema, TTSConfigSchema, MessagesConfigSchema, ToolsMediaAudioConfigSchema, ToolsMediaConfigSchema, ProviderAzureConfigSchema, ProviderRequestOverridesSchema, ProviderAuthConfigSchema, ProvidersConfigSchema, ExtensionSecurityConfigSchema, ExtensionSlotsConfigSchema, ExtensionsConfigSchema, UpdateAutoConfigSchema, GoalsConfigSchema, UpdateConfigSchema, CommandsConfigSchema, McpHttpUrlSchema, McpServerSchema, McpConfigSchema, ConfigSchema;
var init_schema = __esmMin((() => {
	init_cache_dir_policy();
	init_public_url();
	init_config_schema();
	init_config_schema$1();
	AgentModelRefSchema = z.object({
		primary: z.string().min(1),
		fallbacks: z.array(z.string()).optional()
	}).strict();
	AgentImageGenerationModelSchema = z.object({
		primary: z.string().min(1),
		fallbacks: z.array(z.string()).optional(),
		/** Hard cap for the whole generation attempt (ms). */
		timeoutMs: z.number().int().positive().optional(),
		/**
		* When all `primary + fallbacks` candidates fail, sweep every other
		* configured provider before giving up.
		*/
		autoProviderFallback: z.boolean().optional()
	}).strict();
	AgentTypedModelSchema = z.object({
		id: z.string().min(1).regex(/^[a-z][a-z0-9_-]{0,63}$/),
		description: z.string().max(500).optional(),
		model: z.string().min(1)
	}).strict().superRefine((entry, ctx) => {
		const trimmed = entry.model.trim();
		const idx = trimmed.indexOf("/");
		if (idx <= 0 || idx === trimmed.length - 1) ctx.addIssue({
			code: "custom",
			message: `model must be provider/model format (got '${entry.model}')`,
			path: ["model"]
		});
	});
	AgentTypedModelsArraySchema = z.array(AgentTypedModelSchema).optional().superRefine((arr, ctx) => {
		if (!arr) return;
		const seen = /* @__PURE__ */ new Set();
		for (let i = 0; i < arr.length; i++) {
			const id = arr[i].id;
			if (seen.has(id)) ctx.addIssue({
				code: "custom",
				message: `duplicate typed model id '${id}'`,
				path: [i, "id"]
			});
			seen.add(id);
		}
	});
	AgentDefaultsSchema = z.object({
		/** Parent directory: each agent’s Markdown root is `<expanded>/<agentId>/` (e.g. `.../workspace/main`). */
		workspace: z.string().default("~/.xopc/workspace"),
		/** Default model for new sessions. Optional — runtime resolves a fallback when unset. */
		model: AgentModelRefSchema.optional(),
		/** Named model roles (e.g. `small`, `large`) for workflows and other callers. */
		models: AgentTypedModelsArraySchema,
		/** Vision / image understanding model (provider/model). Falls back to heuristics when unset. */
		imageModel: AgentModelRefSchema.optional(),
		/** Image generation model (provider/model), e.g. openai/gpt-image-1. Supports plugin-based providers (OpenAI / DashScope / MiniMax / Google / Fal). */
		imageGenerationModel: AgentImageGenerationModelSchema.optional(),
		/** Max image size for image tool loads (MB). */
		mediaMaxMb: z.number().positive().optional(),
		maxTokens: z.number().default(8192),
		temperature: z.number().default(.7),
		maxToolIterations: z.number().default(20),
		maxTaskDurationMs: z.number().min(6e4).max(144e5).optional(),
		maxRequestsPerTurn: z.number().min(10).max(200).default(50),
		maxToolFailuresPerTurn: z.number().min(1).max(20).default(3),
		thinkingDefault: z.enum([
			"off",
			"minimal",
			"low",
			"medium",
			"high",
			"xhigh",
			"adaptive"
		]).optional(),
		reasoningDefault: z.enum([
			"off",
			"on",
			"stream"
		]).optional(),
		verboseDefault: z.enum([
			"off",
			"on",
			"full"
		]).optional(),
		bootstrapMaxChars: z.number().int().positive().optional(),
		bootstrapTotalMaxChars: z.number().int().positive().optional(),
		bootstrapPromptTruncationWarning: z.enum([
			"off",
			"once",
			"always"
		]).optional(),
		startupContext: z.object({
			enabled: z.boolean().optional(),
			applyOn: z.array(z.enum(["new", "reset"])).optional(),
			dailyMemoryDays: z.number().int().min(1).optional(),
			maxFileBytes: z.number().int().positive().optional(),
			maxFileChars: z.number().int().positive().optional(),
			maxTotalChars: z.number().int().positive().optional()
		}).optional(),
		contextLimits: z.object({ postCompactionMaxChars: z.number().int().positive().optional() }).optional(),
		compaction: z.object({
			enabled: z.boolean().default(true),
			mode: z.enum(["default", "safeguard"]).default("default"),
			reserveTokens: z.number().default(8e3),
			triggerThreshold: z.number().min(.5).max(.95).default(.8),
			minMessagesBeforeCompact: z.number().default(10),
			keepRecentMessages: z.number().default(5),
			evictionWindow: z.number().min(.1).max(.5).default(.2),
			retentionWindow: z.number().min(3).max(20).default(6),
			postCompactionSections: z.array(z.string()).optional()
		}).optional(),
		pruning: z.object({
			enabled: z.boolean().default(true),
			maxToolResultChars: z.number().default(1e4),
			headKeepRatio: z.number().default(.3),
			tailKeepRatio: z.number().default(.3)
		}).optional(),
		/**
		* Curated memory (`agents/<id>/memories/`) + pluggable external provider.
		* Only one external provider at a time.
		*/
		memory: z.object({
			/** Master switch: `curated_memory` tool, prefetch, and external provider. Default true. */
			enabled: z.boolean().optional(),
			/** When false, disable curated_memory tool and memory subsystem helpers. Default true. */
			useEnhancedSystem: z.boolean().optional(),
			/** Include USER.md in snapshot. Default true. */
			userProfileEnabled: z.boolean().optional(),
			memoryCharLimit: z.number().positive().optional(),
			userCharLimit: z.number().positive().optional(),
			provider: z.enum(["none", "stub"]).optional(),
			/** How often prefetched external memory is injected into the user message. */
			injectionFrequency: z.enum(["every-turn", "first-turn"]).optional(),
			/** Inject prefetch on turns 1, 1+N, 1+2N, … (only when injectionFrequency is every-turn). Min 1. */
			contextCadence: z.number().int().min(1).optional(),
			/** Reserved for future external “dialectic” sync cadence (not wired yet). */
			dialecticCadence: z.number().int().min(1).optional(),
			/**
			* Background memory consolidation ("dreaming"): three-phase sleep model that
			* promotes short-term recall signals into long-term memory (`MEMORY.md`).
			*
			* Phases:
			* - **light** — fast, frequent sweep (default every 6 h): dedup + signal collection.
			* - **deep**  — daily deep promotion (default 3 AM): score-gated write to MEMORY.md.
			* - **rem**   — weekly pattern discovery (default Sun 5 AM): cross-session insight mining.
			*/
			dreaming: z.object({
				enabled: z.boolean().optional(),
				/** Default deep-phase cron when `phases.deep.cron` is omitted. */
				frequency: z.string().optional(),
				timezone: z.string().optional(),
				phases: z.object({
					light: z.object({
						enabled: z.boolean().optional(),
						cron: z.string().optional(),
						lookbackDays: z.number().int().min(1).optional(),
						limit: z.number().int().min(0).optional(),
						dedupeSimilarity: z.number().min(0).max(1).optional()
					}).optional(),
					deep: z.object({
						enabled: z.boolean().optional(),
						cron: z.string().optional(),
						minScore: z.number().min(0).max(1).optional(),
						minRecallCount: z.number().int().min(1).optional(),
						minUniqueQueries: z.number().int().min(1).optional(),
						limit: z.number().int().min(0).optional(),
						recencyHalfLifeDays: z.number().min(1).optional(),
						maxAgeDays: z.number().int().min(1).optional()
					}).optional(),
					rem: z.object({
						enabled: z.boolean().optional(),
						cron: z.string().optional(),
						lookbackDays: z.number().int().min(1).optional(),
						limit: z.number().int().min(0).optional(),
						minPatternStrength: z.number().min(0).max(1).optional()
					}).optional()
				}).optional()
			}).optional()
		}).optional(),
		/** Cross-session transcript search (`session_search` tool). */
		sessionSearch: z.object({ 
		/** Model ref for per-session summaries (e.g. openai/gpt-4o-mini). */
summaryModel: z.string().optional() }).optional(),
		/**
		* Post-turn background review (Hermes-style): optional quiet follow-up that may call
		* `curated_memory` / `skill_manage` so durable facts and reusable workflows persist
		* without bloating the main user-visible turn.
		*/
		backgroundReview: z.object({
			/** When true, nudges may run after successful turns. Default false (opt-in). */
			enabled: z.boolean().optional(),
			/** User-turn cadence for memory review. 0 disables the memory channel. Default 10. */
			memoryNudgeInterval: z.number().int().min(0).optional(),
			/** LLM rounds without `skill_manage` before a skill review. 0 disables the skill channel. Default 10. */
			skillNudgeInterval: z.number().int().min(0).optional(),
			/** Max tool executions for the review agent. Default 8. */
			maxToolRounds: z.number().int().min(1).max(32).optional(),
			/** Max prior messages passed into the review context (tail). Default 80. */
			maxHistoryMessages: z.number().int().min(10).max(200).optional(),
			/** Wall-clock cap for the review run (ms). Default 120000. */
			maxDurationMs: z.number().int().min(3e4).max(6e5).optional()
		}).optional(),
		/** LLM pass for `web_extract` (markdown-focused extraction). */
		webExtract: z.object({
			model: z.string().optional(),
			maxLength: z.number().positive().optional()
		}).optional(),
		/**
		* Browser capability via unified `browser_use` tool. Enabled by default (set `enabled: false` to disable).
		* The local Playwright backend requires Chromium on the gateway host: `npx playwright install chromium`.
		*/
		browser: z.object({
			enabled: z.boolean().optional(),
			/** Run browser in headless mode (default: false — visible window). */
			headless: z.boolean().optional(),
			/** When true, skip private-IP blocking for browser navigation (cloud metadata endpoints are always blocked). */
			allowPrivateUrls: z.boolean().optional(),
			/** Browser command timeout in seconds (default: 30). */
			commandTimeout: z.number().min(5).optional(),
			/** Browser backend mode (default: 'extension'). Also: 'local' (Playwright), 'cdp', 'cloud', or 'cloakbrowser'. */
			backend: z.enum([
				"local",
				"cdp",
				"cloud",
				"extension",
				"cloakbrowser"
			]).optional(),
			/** Cloud browser backend: 'local' (default Playwright), 'browserbase', or 'browser-use'. */
			cloudProvider: z.enum([
				"local",
				"browserbase",
				"browser-use"
			]).optional(),
			/** Cloud browser credentials and optional session hints. */
			cloud: z.object({
				/** API key for the selected cloud provider. Environment variables are still supported as fallback. */
				apiKey: z.string().optional(),
				/** Browserbase project id. Falls back to BROWSERBASE_PROJECT_ID. */
				projectId: z.string().optional(),
				/** Optional cloud provider region. */
				region: z.string().optional()
			}).optional(),
			/** Direct CDP WebSocket endpoint URL (bypasses cloud provider). */
			cdpUrl: z.string().optional(),
			/** Chrome Extension bridge settings (only used when backend = 'extension'). */
			extension: z.object({
				/** WebSocket server port. Default: 19820. */
				port: z.number().min(1024).max(65535).optional(),
				/** Host to bind. Default: 127.0.0.1. */
				host: z.string().optional(),
				/** Timeout waiting for extension connection (ms). Default: 30000. */
				connectionTimeout: z.number().min(1e3).optional()
			}).optional(),
			/** JS dialog handling policy: 'must_respond' (agent must act), 'auto_dismiss', or 'auto_accept'. */
			dialogPolicy: z.enum([
				"must_respond",
				"auto_dismiss",
				"auto_accept"
			]).optional(),
			/** Dialog auto-dismiss/accept timeout in seconds (default: 300). */
			dialogTimeoutSeconds: z.number().min(1).optional(),
			/** Enable humanized input simulation (Bezier mouse, per-char typing, wheel scroll). Default: false. */
			humanize: z.boolean().optional(),
			/** Humanize behavior preset: 'default' (fast) or 'careful' (slower, more realistic). Default: 'careful'. */
			humanPreset: z.enum(["default", "careful"]).optional(),
			/** CloakBrowser settings (only used when backend = 'cloakbrowser'). */
			cloakbrowser: z.object({
				/** Keep browser process alive between tasks. Default: true. */
				keepOpen: z.boolean().optional(),
				/** Create a temporary profile directory, cleaned up on close. Default: false. */
				temporaryProfile: z.boolean().optional(),
				/** Directory for cached CloakBrowser binaries. Must live under the user's home directory. Default: ~/.xopc/bin/cloakbrowser. */
				cacheDir: z.string().optional().superRefine((v, ctx) => {
					const r = checkCacheDir(v);
					if (r.ok === false) ctx.addIssue({
						code: "custom",
						message: r.message
					});
				}),
				/** Override the CloakBrowser binary path (skip auto-download). */
				binaryPath: z.string().optional(),
				/** Timezone to emulate (e.g. "America/New_York"). */
				timezone: z.string().optional(),
				/** Locale to emulate (e.g. "en-US"). */
				locale: z.string().optional(),
				/** Public IP for WebRTC leak prevention. */
				webrtcIp: z.string().optional(),
				/** Platform to emulate in fingerprint (e.g. "windows", "macos"). */
				fingerprintPlatform: z.string().optional(),
				/** Extra Chromium launch args (override defaults with same --key= prefix). */
				extraArgs: z.array(z.string()).optional()
			}).optional()
		}).optional(),
		/** Sub-agent delegation (`delegate_task`). Opt-in. */
		delegate: z.object({ enabled: z.boolean().optional() }).optional(),
		/** Sandboxed `execute_code` (programmatic tool calls). Opt-in. */
		executeCode: z.object({ enabled: z.boolean().optional() }).optional(),
		/**
		* Dynamic workflows (`workflow` tool). On by default — disable to remove the
		* tool from the agent surface entirely. Subagents spawned by workflows still
		* obey the global `delegate` allowlist; `maxSubagents` caps a single workflow
		* run, `defaultTimeoutSec` caps wall-clock per run.
		*/
		workflow: z.object({
			enabled: z.boolean().default(true),
			maxConcurrency: z.number().int().min(1).max(64).default(16),
			maxSubagents: z.number().int().min(1).max(1e4).default(1e3),
			defaultTimeoutSec: z.number().int().min(60).max(14400).default(1800),
			/** Subagent live progress in workflow snapshots: tool steps only, or full text stream. */
			subagentStream: z.enum([
				"off",
				"steps",
				"full"
			]).default("steps")
		}).optional(),
		/** Optional full system prompt replacement (merged with per-agent entry; entry wins). */
		systemPromptOverride: z.string().optional(),
		/** Optional allowlist of skill names for `<available_skills>`; when set, replaces unfiltered list. */
		skills: z.array(z.string()).optional(),
		/** Disable built-in tools by name (e.g. `shell`, `web_search`). */
		tools: z.object({ disable: z.array(z.string()).optional() }).optional(),
		/** Opaque per-process params (reserved for extensions / future use). */
		params: z.record(z.string(), z.unknown()).optional()
	});
	AgentConfigSchema = z.object({
		id: z.string(),
		/** When true, this entry is the default routing agent. */
		default: z.boolean().optional(),
		name: z.string().optional(),
		/** Short human-readable summary for UIs (gateway console, pickers). */
		description: z.string().max(4e3).optional(),
		enabled: z.boolean().default(true),
		/** Per-agent workspace root (`~` expanded at runtime). */
		workspace: z.string().optional(),
		/**
		* Internal agent state directory (`…/credentials`, `agent.json`, pid, inbox).
		* Default: `<stateDir>/agents/<id>/agent`.
		*/
		agentDir: z.string().optional(),
		model: AgentModelRefSchema.optional(),
		/** Per-agent typed model overrides; same `id` replaces the defaults entry. */
		models: AgentTypedModelsArraySchema,
		thinkingDefault: z.enum([
			"off",
			"minimal",
			"low",
			"medium",
			"high",
			"xhigh",
			"adaptive"
		]).optional(),
		reasoningDefault: z.enum([
			"off",
			"on",
			"stream"
		]).optional(),
		verboseDefault: z.enum([
			"off",
			"on",
			"full"
		]).optional(),
		systemPromptOverride: z.string().optional(),
		skills: z.array(z.string()).optional(),
		tools: z.object({ disable: z.array(z.string()).optional() }).optional(),
		params: z.record(z.string(), z.unknown()).optional()
	});
	AgentsConfigSchema = z.object({
		/** Default agent id when not specified (routing / session creation). */
		default: z.string().optional(),
		defaults: AgentDefaultsSchema.optional(),
		list: z.array(AgentConfigSchema).optional()
	}).default({ defaults: {
		workspace: "~/.xopc/workspace",
		maxTokens: 8192,
		temperature: .7,
		maxToolIterations: 20,
		maxRequestsPerTurn: 50,
		maxToolFailuresPerTurn: 3,
		thinkingDefault: "medium",
		reasoningDefault: "stream",
		verboseDefault: "full",
		compaction: {
			enabled: true,
			mode: "default",
			reserveTokens: 8e3,
			triggerThreshold: .8,
			minMessagesBeforeCompact: 10,
			keepRecentMessages: 5,
			evictionWindow: .2,
			retentionWindow: 6
		},
		pruning: {
			enabled: true,
			maxToolResultChars: 1e4,
			headKeepRatio: .3,
			tailKeepRatio: .3
		},
		browser: {
			enabled: true,
			headless: false,
			backend: "extension"
		}
	} });
	BindingMatchSchema = z.object({
		channel: z.string(),
		accountId: z.string().optional(),
		peerKind: z.string().optional(),
		peerId: z.string().optional(),
		guildId: z.string().optional(),
		teamId: z.string().optional(),
		memberRoleIds: z.array(z.string()).optional()
	});
	BindingRuleSchema = z.object({
		id: z.string().optional(),
		agentId: z.string(),
		priority: z.number().default(100),
		match: BindingMatchSchema,
		enabled: z.boolean().default(true)
	});
	BindingsConfigSchema = z.array(BindingRuleSchema).default([]);
	SessionDmScopeSchema = z.enum([
		"main",
		"per-peer",
		"per-channel-peer",
		"per-account-channel-peer"
	]);
	SessionStorageConfigSchema = z.object({
		pruneAfterMs: z.number().optional(),
		maxEntries: z.number().optional()
	});
	SessionResetModeSchema = z.enum(["daily", "idle"]);
	SessionResetConfigSchema = z.object({
		mode: SessionResetModeSchema.optional(),
		/** Local hour (0–23) for the daily reset boundary. */
		atHour: z.number().int().min(0).max(23).optional(),
		/** Sliding idle window (minutes). When set with daily mode, whichever expires first wins. */
		idleMinutes: z.number().int().min(0).optional()
	}).strict();
	SessionResetByTypeSchema = z.object({
		direct: SessionResetConfigSchema.optional(),
		group: SessionResetConfigSchema.optional(),
		thread: SessionResetConfigSchema.optional()
	}).strict();
	SessionScopeSchema = z.enum(["per-sender", "global"]);
	SessionConfigSchema = z.object({
		scope: SessionScopeSchema.default("per-sender"),
		mainKey: z.string().default("main"),
		dmScope: SessionDmScopeSchema.default("main"),
		identityLinks: z.record(z.string(), z.array(z.string())).optional(),
		resetTriggers: z.array(z.string()).optional(),
		idleMinutes: z.number().int().positive().optional(),
		reset: SessionResetConfigSchema.optional(),
		resetByType: SessionResetByTypeSchema.optional(),
		resetByChannel: z.record(z.string(), SessionResetConfigSchema).optional(),
		storage: SessionStorageConfigSchema.optional()
	}).default({
		scope: "per-sender",
		mainKey: "main",
		dmScope: "main"
	});
	ChannelsConfigSchema = z.record(z.string(), z.unknown()).default({ telegram: {
		enabled: false,
		allowFrom: [],
		groupAllowFrom: [],
		debug: false,
		accounts: { default: {
			accountId: "default",
			enabled: true,
			botToken: "",
			allowFrom: [],
			dmPolicy: "pairing",
			groupPolicy: "open",
			replyToMode: "off",
			historyLimit: 50,
			textChunkLimit: 4e3,
			streamMode: "partial"
		} },
		dmPolicy: "pairing",
		groupPolicy: "open",
		replyToMode: "off",
		historyLimit: 50,
		textChunkLimit: 4e3
	} });
	SearchProviderEntrySchema = z.object({
		type: z.enum([
			"brave",
			"tavily",
			"bing",
			"searxng"
		]),
		apiKey: z.string().optional(),
		/** SearXNG instance base URL (e.g. http://localhost:8080) */
		url: z.string().optional(),
		disabled: z.boolean().optional()
	});
	WebSearchConfigSchema = z.object({
		maxResults: z.number().default(5),
		/** Ordered API providers; empty → HTML fallback only */
		providers: z.array(SearchProviderEntrySchema).default([])
	});
	WebsiteBlocklistSchema = z.object({
		/** Master switch. Default false (no blocking). */
		enabled: z.boolean().default(false),
		/** Domain patterns to block (e.g. "example.com", "*.evil.org"). */
		domains: z.array(z.string()).default([])
	});
	WebToolsConfigSchema = z.object({
		/** Search result HTML fallback: cn → Bing, otherwise DuckDuckGo */
		region: z.enum(["cn", "global"]).optional(),
		search: WebSearchConfigSchema.optional(),
		/** Domain blocklist for web_fetch / web_extract / browser tools. */
		blocklist: WebsiteBlocklistSchema.optional()
	});
	ToolsConfigSchema = z.object({
		web: WebToolsConfigSchema.optional(),
		/**
		* Per-capability media providers. Currently only `audio` (STT) is wired;
		* `image` / `video` slots are reserved for future capabilities.
		*/
		media: z.lazy(() => ToolsMediaConfigSchema)
	}).default({ web: { search: {
		maxResults: 5,
		providers: []
	} } });
	GatewayAuthRateLimitSchema = z.object({
		enabled: z.boolean().default(true),
		maxAttempts: z.number().int().min(1).default(5),
		windowMs: z.number().default(9e5),
		blockDurationMs: z.number().default(3e5),
		/** OpenClaw alias for blockDurationMs. */
		lockoutMs: z.number().optional(),
		/** Skip rate limiting for loopback client IPs (default true). Remote browser Origin requests never exempt. */
		exemptLoopback: z.boolean().default(true),
		/**
		* Coalesce same-client failures arriving within this window into a single
		* attempt. Absorbs SPA fan-out / SDK auto-retry storms without weakening
		* brute-force protection (deliberate attackers are still rate-limited to
		* one effective attempt per window). Set to 0 to disable.
		*/
		burstCoalesceMs: z.number().int().min(0).default(1e3)
	}).optional();
	GatewaySecuritySchema = z.object({ 
	/** When true, non-loopback binds require explicit gateway.auth.rateLimit configuration. */
strict: z.boolean().optional() }).optional();
	GatewayTrustedProxySchema = z.object({
		/** Header set by the reverse proxy with the authenticated user identity. */
		userHeader: z.string().min(1),
		/** Additional headers that must be present (e.g. proxy auth markers). */
		requiredHeaders: z.array(z.string()).optional(),
		/** When non-empty, only these user identities are allowed. */
		allowUsers: z.array(z.string()).optional(),
		/** Allow trusted-proxy auth when the TCP source is loopback (same-host reverse proxy). */
		allowLoopback: z.boolean().optional()
	}).strict();
	GatewayAuthSchema = z.object({
		mode: z.enum([
			"none",
			"token",
			"password",
			"trusted-proxy"
		]).default("token"),
		token: z.string().optional(),
		password: z.string().optional(),
		/** When true (default for Serve), browser UI may auth via Tailscale identity headers. API routes still require token. */
		allowTailscale: z.boolean().optional(),
		rateLimit: GatewayAuthRateLimitSchema,
		trustedProxy: GatewayTrustedProxySchema.optional()
	}).default({ mode: "token" });
	GatewayTailscaleConsentSchema = z.object({
		version: z.string().min(1),
		acceptedAt: z.string().min(1)
	});
	GatewayTailscaleSchema = z.object({
		mode: z.enum([
			"off",
			"serve",
			"funnel"
		]).default("off"),
		resetOnExit: z.boolean().default(true),
		consent: GatewayTailscaleConsentSchema.optional()
	}).default({
		mode: "off",
		resetOnExit: true
	});
	GatewayRemoteSchema = z.object({
		url: z.string().url(),
		token: z.string().optional(),
		password: z.string().optional(),
		transport: z.enum(["direct", "ssh"]).default("direct"),
		sshTarget: z.string().optional(),
		sshIdentity: z.string().optional(),
		tlsFingerprint: z.string().optional()
	});
	GatewayTlsSchema = z.object({
		enabled: z.boolean().default(false),
		autoGenerate: z.boolean().default(false),
		certPath: z.string().optional(),
		keyPath: z.string().optional()
	}).default({
		enabled: false,
		autoGenerate: false
	});
	GatewayModeSchema = z.enum(["local", "remote"]).default("local");
	HeartbeatConfigSchema = z.object({
		enabled: z.boolean(),
		intervalMs: z.number(),
		/** When false, heartbeat instructions are only sent during heartbeat polling turns (not in every chat system prompt). */
		includeSystemPromptSection: z.boolean().optional().default(false),
		target: z.string().optional(),
		targetChatId: z.string().optional(),
		prompt: z.string().optional(),
		ackMaxChars: z.number().optional(),
		isolatedSession: z.boolean().optional(),
		activeHours: z.object({
			start: z.string(),
			end: z.string(),
			timezone: z.string().optional()
		}).optional()
	}).default({
		enabled: true,
		intervalMs: 18e5,
		includeSystemPromptSection: false
	});
	GatewayChannelConnectDeferModeSchema = z.enum([
		"auto",
		"off",
		"explicit"
	]);
	TunnelConsentSchema = z.object({
		version: z.string().min(1),
		acceptedAt: z.string().min(1)
	});
	TunnelConfigSchema = z.object({
		enabled: z.boolean().default(false),
		brokerUrl: z.string().url().default("https://frp.xopc.ai/api"),
		/** Broker register API secret (env `XOPC_TUNNEL_REGISTRATION_SECRET` overrides when set). */
		registrationSecret: z.string().min(1).optional(),
		autoStart: z.boolean().default(false),
		subdomain: z.string().optional(),
		consent: TunnelConsentSchema.optional()
	}).default({
		enabled: false,
		brokerUrl: "https://frp.xopc.ai/api",
		autoStart: false
	});
	WorkspaceImportConfigSchema = z.object({
		/** Workspace-relative subdir for imported files. Default `imports`. */
		targetDir: z.string().default("imports"),
		/** Per-file byte cap. Default 100 MiB. */
		maxBytes: z.number().int().min(1024).max(10737418240).default(104857600),
		/** When false, the route rejects `onConflict: 'overwrite'`. Default true. */
		allowOverwrite: z.boolean().default(true)
	});
	WorkspaceConfigSchema = z.object({ import: WorkspaceImportConfigSchema.optional() }).optional();
	GatewayBindModeSchema = z.enum([
		"auto",
		"loopback",
		"lan",
		"tailnet",
		"custom"
	]);
	GatewayConfigSchema = z.object({
		/** Semantic bind mode. */
		bind: GatewayBindModeSchema.optional(),
		/** IPv4 listen address when `bind` is `custom`. */
		customBindHost: z.string().optional(),
		port: z.number().optional(),
		/** local: this process runs the gateway; remote: CLI clients target gateway.remote. */
		mode: GatewayModeSchema.optional(),
		/** Persistent remote gateway target for CLI/TUI/MCP when mode=remote. */
		remote: GatewayRemoteSchema.optional(),
		tailscale: GatewayTailscaleSchema.optional(),
		tls: GatewayTlsSchema.optional(),
		auth: GatewayAuthSchema.optional(),
		heartbeat: HeartbeatConfigSchema.optional(),
		maxSseConnections: z.number().optional(),
		corsOrigins: z.array(z.string()).optional(),
		/**
		* Reverse-proxy publicly reachable URL (e.g. `https://gateway.example.com`).
		* Optional. When set, mobile pairing surfaces this URL as the preferred
		* baseUrl and it is auto-added to the browser CORS/CSRF allowlist.
		* - Must be a URL with no path / query / userinfo.
		* - Must use `https:` for public hosts; `http:` is only allowed when the
		*   hostname is in an RFC1918 / `.local` private range.
		*/
		publicUrl: z.string().superRefine((value, ctx) => {
			const result = validatePublicUrl(value);
			if (result.ok === false) ctx.addIssue({
				code: "custom",
				message: `gateway.publicUrl: ${result.message}`
			});
		}).optional(),
		/** Dangerous: allow browser Origin to match the HTTP Host header when not in corsOrigins. */
		dangerouslyAllowHostHeaderOriginFallback: z.boolean().optional(),
		/** CIDRs or exact IPs of reverse proxies allowed to terminate auth (trusted-proxy mode). */
		trustedProxies: z.array(z.string()).optional(),
		/** When true, fall back to X-Real-IP if X-Forwarded-For chain parsing fails. Default false (fail closed). */
		allowRealIpFallback: z.boolean().optional(),
		security: GatewaySecuritySchema,
		/**
		* How channel `start()` is split around HTTP listen when using `GatewayServer`.
		* - `auto` (default): defer ids come from channel plugin `meta.deferConnectUntilAfterListen` + enabled config.
		* - `off`: always start all channels in phase1 (troubleshooting / strict ordering).
		* - `explicit`: defer only `channelConnectDeferIds` (empty = defer none).
		*/
		channelConnectDeferMode: GatewayChannelConnectDeferModeSchema.optional(),
		/** When `channelConnectDeferMode` is `explicit`, these channel plugin ids are deferred until after listen. */
		channelConnectDeferIds: z.array(z.string().min(1)).max(24).optional(),
		/** Removed from the defer set (applied after `auto` or `explicit` resolution). */
		channelConnectDeferSkipIds: z.array(z.string().min(1)).max(24).optional(),
		/** Default skills marketplace provider id. Built-in: 'store', 'skillhub', 'clawhub'. Extensions may register more. */
		skillsMarketplaceProvider: z.string().optional(),
		/** Base URL for the xopc skills marketplace (public REST API). */
		skillsStoreBaseUrl: z.string().url().optional(),
		/** File sharing configuration (temporary public download links for workspace files). */
		share: z.object({
			enabled: z.boolean().default(true),
			/** Default TTL in ms (default 24h). */
			defaultTtlMs: z.number().min(6e4).max(6048e5).default(864e5),
			/** Maximum TTL in ms (default 7 days). */
			maxTtlMs: z.number().min(6e4).max(2592e6).default(6048e5),
			/** Maximum concurrent active shares (default 100). */
			maxActiveShares: z.number().min(1).max(1e4).default(100),
			/** Maximum shareable file size in bytes (default 100MB). */
			maxFileSize: z.number().min(1048576).max(10737418240).default(104857600),
			/** MIME types allowed for inline preview (?inline=1). */
			inlinePreviewMimes: z.array(z.string()).default([
				"image/png",
				"image/jpeg",
				"image/gif",
				"image/webp",
				"image/svg+xml",
				"application/pdf",
				"text/html",
				"text/markdown",
				"text/plain",
				"application/json"
			]),
			/** Folder-sharing controls (browse + ZIP). */
			directory: z.object({
				enabled: z.boolean().default(true),
				/** Maximum folder size in bytes at scan time (default 1 GB). */
				maxFolderSize: z.number().int().min(1048576).max(10737418240).default(1073741824),
				/** Maximum number of entries scanned for a single folder share. */
				maxFileCount: z.number().int().min(1).max(1e5).default(1e3),
				/** Traversal depth cap (defense against recursive symlinks). */
				maxDepth: z.number().int().min(1).max(64).default(20),
				/** In-memory directory listing cache TTL. */
				listingCacheMs: z.number().int().min(0).max(6e5).default(6e4),
				/** Maximum simultaneous ZIP streams per share token. */
				zipConcurrency: z.number().int().min(1).max(8).default(1)
			}).default({
				enabled: true,
				maxFolderSize: 1073741824,
				maxFileCount: 1e3,
				maxDepth: 20,
				listingCacheMs: 6e4,
				zipConcurrency: 1
			})
		}).optional(),
		/** Site-share configuration (static directory or reverse-proxy a local dev server). */
		siteShare: z.object({
			enabled: z.boolean().default(true),
			/** Public host suffix that subdomain shares are served under. */
			publicHostSuffix: z.string().min(1).default("share.xopc.ai"),
			/** Default TTL in ms (default 6h, shorter than file shares — live app surface). */
			defaultTtlMs: z.number().int().min(6e4).max(6048e5).default(216e5),
			/** Maximum TTL in ms (default 7 days). */
			maxTtlMs: z.number().int().min(6e4).max(2592e6).default(6048e5),
			/** Maximum concurrent active site shares. */
			maxActiveSites: z.number().int().min(1).max(1e3).default(5),
			static: z.object({
				enabled: z.boolean().default(true),
				/** Maximum total bytes of files served per static site. */
				maxRootDirSize: z.number().int().min(1048576).max(10737418240).default(524288e3),
				/** Maximum file count under root dir. */
				maxFileCount: z.number().int().min(1).max(1e5).default(1e4),
				/** Whether HTML/CSS rewrite of absolute paths is on by default. */
				rewriteEnabledByDefault: z.boolean().default(false)
			}).default({
				enabled: true,
				maxRootDirSize: 524288e3,
				maxFileCount: 1e4,
				rewriteEnabledByDefault: false
			}),
			proxy: z.object({
				/** Reverse-proxy mode default-enabled per the product brief. */
				enabled: z.boolean().default(true),
				/** Upstream host whitelist. Loopback by default. */
				allowedUpstreamHosts: z.array(z.string().min(1)).default([
					"127.0.0.1",
					"localhost",
					"::1"
				]),
				/** Upstream port whitelist (common dev-server ports). */
				allowedUpstreamPorts: z.array(z.number().int().min(1).max(65535)).default([
					3e3,
					3001,
					4321,
					5173,
					8e3,
					8080,
					8888,
					9e3
				]),
				/** Whether to forward WebSocket upgrades. */
				forwardWebSocket: z.boolean().default(true),
				/** Maximum request body size in bytes (50 MB). */
				bodySizeLimit: z.number().int().min(0).max(1073741824).default(52428800),
				/** Per-request HTTP timeout in ms. */
				requestTimeoutMs: z.number().int().min(1e3).max(6e5).default(3e4),
				/** Per-WebSocket idle timeout in ms. */
				wsIdleTimeoutMs: z.number().int().min(1e4).max(36e5).default(3e5),
				/** Rewrite Set-Cookie Path attribute (subpath mode only). */
				rewriteSetCookiePath: z.boolean().default(true)
			}).default({
				enabled: true,
				allowedUpstreamHosts: [
					"127.0.0.1",
					"localhost",
					"::1"
				],
				allowedUpstreamPorts: [
					3e3,
					3001,
					4321,
					5173,
					8e3,
					8080,
					8888,
					9e3
				],
				forwardWebSocket: true,
				bodySizeLimit: 52428800,
				requestTimeoutMs: 3e4,
				wsIdleTimeoutMs: 3e5,
				rewriteSetCookiePath: true
			})
		}).optional()
	}).default({
		bind: "loopback",
		port: 18790,
		auth: { mode: "token" },
		heartbeat: {
			enabled: true,
			intervalMs: 18e5,
			includeSystemPromptSection: false
		},
		maxSseConnections: 100,
		corsOrigins: [],
		skillsMarketplaceProvider: "skillhub",
		skillsStoreBaseUrl: "https://store.xopc.ai"
	});
	CronConfigSchema = z.object({
		enabled: z.boolean().optional(),
		maxConcurrentJobs: z.number().optional(),
		defaultTimezone: z.string().optional(),
		historyRetentionDays: z.number().optional(),
		enableMetrics: z.boolean().optional()
	}).default({
		enabled: true,
		maxConcurrentJobs: 5,
		defaultTimezone: "UTC",
		historyRetentionDays: 7,
		enableMetrics: true
	});
	ModelsDevConfigSchema = z.object({ enabled: z.boolean().default(true) }).default({ enabled: true });
	SttProviderConfigCatchallSchema = z.union([
		z.string(),
		z.number(),
		z.boolean(),
		z.null(),
		z.array(z.unknown()),
		z.record(z.string(), z.unknown())
	]);
	STTProviderConfigSchema = z.object({
		apiKey: z.string().optional(),
		model: z.string().optional(),
		baseUrl: z.string().optional(),
		headers: z.record(z.string(), z.string()).optional(),
		language: z.string().optional(),
		prompt: z.string().optional()
	}).catchall(SttProviderConfigCatchallSchema);
	STTFallbackConfigSchema = z.object({
		enabled: z.boolean().default(true),
		order: z.array(z.string().min(1)).default(["alibaba", "openai"])
	});
	MediaUnderstandingCapabilitiesSchema = z.array(z.enum([
		"image",
		"audio",
		"video"
	])).optional();
	MediaUnderstandingModelSchema = z.object({
		provider: z.string().optional(),
		model: z.string().optional(),
		capabilities: MediaUnderstandingCapabilitiesSchema,
		type: z.union([z.literal("provider"), z.literal("cli")]).optional(),
		command: z.string().optional(),
		baseUrl: z.string().optional(),
		headers: z.record(z.string(), z.string()).optional(),
		apiKey: z.string().optional(),
		language: z.string().optional(),
		prompt: z.string().optional()
	}).catchall(SttProviderConfigCatchallSchema);
	STTConfigSchema = z.object({
		enabled: z.boolean().default(false),
		/** Primary provider id — any registered MediaUnderstandingProvider id. */
		provider: z.string().min(1).default("alibaba"),
		fallback: STTFallbackConfigSchema.optional(),
		timeoutMs: z.number().int().min(1e3).max(18e4).optional(),
		/** Ordered model entries for this capability (OpenClaw `tools.media.audio.models`). */
		models: z.array(MediaUnderstandingModelSchema).optional(),
		/** Provider settings map keyed by provider id. */
		providers: z.record(z.string(), STTProviderConfigSchema).optional()
	}).strict();
	TtsProviderConfigCatchallSchema = z.union([
		z.string(),
		z.number(),
		z.boolean(),
		z.null(),
		z.array(z.unknown()),
		z.record(z.string(), z.unknown())
	]);
	TTSProviderConfigSchema = z.object({
		apiKey: z.string().optional(),
		model: z.string().optional(),
		voice: z.string().optional()
	}).catchall(TtsProviderConfigCatchallSchema);
	TTSFallbackConfigSchema = z.object({
		enabled: z.boolean().default(true),
		order: z.array(z.string().min(1)).default([
			"openai",
			"alibaba",
			"minimax",
			"edge"
		])
	});
	TTSModelOverridesConfigSchema = z.object({
		enabled: z.boolean().default(true),
		allowText: z.boolean().default(true),
		allowProvider: z.boolean().default(false),
		allowVoice: z.boolean().default(true),
		allowModelId: z.boolean().default(true),
		allowVoiceSettings: z.boolean().default(false),
		allowNormalization: z.boolean().default(false),
		allowSeed: z.boolean().default(false)
	});
	TTSEdgeConfigSchema = z.object({
		enabled: z.boolean().default(true),
		voice: z.string().optional(),
		lang: z.string().optional(),
		outputFormat: z.string().optional(),
		pitch: z.string().optional(),
		rate: z.string().optional(),
		volume: z.string().optional(),
		proxy: z.string().optional(),
		timeoutMs: z.number().int().min(1e3).max(12e4).optional()
	});
	TTSSummarizationConfigSchema = z.object({
		enabled: z.boolean().optional(),
		targetLength: z.number().int().min(1).optional(),
		threshold: z.number().int().min(1).optional(),
		model: z.string().optional()
	});
	TTSConfigSchema = z.object({
		enabled: z.boolean().default(false),
		/** Primary provider id — any registered SpeechProviderPlugin id. */
		provider: z.string().min(1).default("openai"),
		trigger: z.enum([
			"off",
			"always",
			"inbound",
			"tagged"
		]).default("always"),
		fallback: TTSFallbackConfigSchema.optional(),
		maxTextLength: z.number().int().min(1).default(512),
		timeoutMs: z.number().int().min(1e3).max(18e4).default(6e4),
		summarization: TTSSummarizationConfigSchema.optional(),
		modelOverrides: TTSModelOverridesConfigSchema.optional(),
		/** Provider settings map keyed by provider id. */
		providers: z.record(z.string(), TTSProviderConfigSchema).optional()
	}).strict();
	MessagesConfigSchema = z.object({ 
	/** Voice (text-to-speech) output configuration. */
tts: TTSConfigSchema.optional() }).optional();
	ToolsMediaAudioConfigSchema = STTConfigSchema;
	ToolsMediaConfigSchema = z.object({
		/** Shared model entries applied across media capabilities when entry lacks capabilities. */
		models: z.array(MediaUnderstandingModelSchema).optional(),
		/** Audio (speech-to-text) capability provider config. */
		audio: ToolsMediaAudioConfigSchema.optional()
	}).optional();
	ProviderAzureConfigSchema = z.object({
		/** Azure resource name (subdomain before `.openai.azure.com`). */
		resource: z.string().min(1).optional(),
		/** Azure deployment id (configured per model). */
		deployment: z.string().min(1).optional(),
		/** Azure REST API version, e.g. `2024-08-01-preview`. */
		apiVersion: z.string().min(1).optional()
	}).strict();
	ProviderRequestOverridesSchema = z.object({
		/** Hard cap for a single HTTP call (ms). */
		timeoutMs: z.number().int().positive().optional(),
		/** Extra headers merged into every outbound request. */
		headers: z.record(z.string(), z.string()).optional()
	}).strict();
	ProviderAuthConfigSchema = z.object({
		/** Static API key (api-key / azure-key modes). */
		apiKey: z.string().optional(),
		/** Override the default REST base URL. */
		baseUrl: z.string().url().optional(),
		/** Vendor region (DashScope: `beijing` / `singapore`; AWS: region id). */
		region: z.string().optional(),
		/** Image-only base URL override (DashScope splits image vs LLM). */
		imageBaseUrl: z.string().url().optional(),
		/** Per-vendor request overrides. */
		request: ProviderRequestOverridesSchema.optional(),
		/** Azure OpenAI deployment overrides; only consumed by OpenAI image provider. */
		azure: ProviderAzureConfigSchema.optional()
	}).strict();
	ProvidersConfigSchema = z.record(z.string(), ProviderAuthConfigSchema);
	ExtensionSecurityConfigSchema = z.object({
		checkPermissions: z.boolean().default(true),
		allowUntrusted: z.boolean().default(false),
		allow: z.array(z.string()).default([]),
		trackProvenance: z.boolean().default(true),
		allowPromptInjection: z.boolean().default(false)
	});
	ExtensionSlotsConfigSchema = z.object({
		memory: z.string().optional(),
		tts: z.string().optional(),
		imageGeneration: z.string().optional(),
		webSearch: z.string().optional()
	});
	ExtensionsConfigSchema = z.record(z.string(), z.unknown());
	UpdateAutoConfigSchema = z.object({
		/** Enable automatic update installation. Default false. */
		enabled: z.boolean().default(false),
		/** Hours to wait before applying a stable update after first detection. */
		stableDelayHours: z.number().min(0).default(6),
		/** Additional random jitter hours for stable rollout (avoids thundering herd). */
		stableJitterHours: z.number().min(0).default(12),
		/** How often to re-check for beta updates (hours). Min 0.25. */
		betaCheckIntervalHours: z.number().min(.25).default(1)
	}).strict().optional();
	GoalsConfigSchema = z.object({
		/** Max continuation turns before auto-pause (Hermes default 20). */
		maxTurns: z.number().int().min(1).max(500).default(20),
		/** Optional judge model ref; defaults to `agents.defaults.model`. */
		judgeModelRef: z.string().optional(),
		/**
		* When true (default), first post-turn runs a decomposition judge to build a checklist;
		* subsequent turns evaluate progress per item (Hermes-style). When false, use legacy freeform judge only.
		*/
		checklistMode: z.boolean().default(true),
		/** Auto-pause after this many consecutive judge JSON/tool parse failures (Hermes default 3). */
		maxConsecutiveParseFailures: z.number().int().min(1).max(20).default(3),
		/** Judge LLM call timeout in ms (Hermes uses 60s). */
		judgeTimeoutMs: z.number().int().min(5e3).max(12e4).default(6e4),
		/** Max characters of recent transcript JSON passed to the checklist judge as extra context. */
		checklistHistoryChars: z.number().int().min(0).max(1e5).default(24e3)
	}).strict();
	UpdateConfigSchema = z.object({
		/** Check for updates on gateway startup. Default true. */
		checkOnStart: z.boolean().default(true),
		/** Update channel: stable (default), beta, or dev. */
		channel: z.enum([
			"stable",
			"beta",
			"dev"
		]).default("stable"),
		/** Automatic update policy. */
		auto: UpdateAutoConfigSchema
	}).strict().optional();
	CommandsConfigSchema = z.object({ restart: z.boolean().optional() }).strict().optional();
	McpHttpUrlSchema = z.string().url().refine((value) => {
		try {
			const protocol = new URL(value).protocol;
			return protocol === "http:" || protocol === "https:";
		} catch {
			return false;
		}
	}, "MCP server URL must use http or https");
	McpServerSchema = z.object({
		command: z.string().optional(),
		args: z.array(z.string()).optional(),
		env: z.record(z.string(), z.union([
			z.string(),
			z.number(),
			z.boolean()
		])).optional(),
		cwd: z.string().optional(),
		workingDirectory: z.string().optional(),
		url: McpHttpUrlSchema.optional(),
		transport: z.enum(["sse", "streamable-http"]).optional(),
		headers: z.record(z.string(), z.union([
			z.string(),
			z.number(),
			z.boolean()
		])).optional(),
		connectionTimeoutMs: z.number().finite().positive().optional()
	}).catchall(z.unknown()).superRefine((value, ctx) => {
		const hasCommand = typeof value.command === "string" && value.command.trim().length > 0;
		const hasUrl = typeof value.url === "string" && value.url.trim().length > 0;
		if (hasCommand && hasUrl) ctx.addIssue({
			code: "custom",
			message: "MCP server cannot define both command and url"
		});
	});
	McpConfigSchema = z.object({
		servers: z.record(z.string(), McpServerSchema).optional(),
		sessionIdleTtlMs: z.number().finite().min(0).optional()
	}).strict().optional();
	ConfigSchema = z.object({
		agents: AgentsConfigSchema,
		bindings: BindingsConfigSchema,
		session: SessionConfigSchema,
		channels: ChannelsConfigSchema,
		gateway: GatewayConfigSchema,
		tunnel: TunnelConfigSchema.optional(),
		workspace: WorkspaceConfigSchema,
		tools: ToolsConfigSchema,
		mcp: McpConfigSchema,
		cron: CronConfigSchema,
		goals: GoalsConfigSchema.optional(),
		extensions: ExtensionsConfigSchema.default({}),
		/** Per-vendor capability provider config (image / audio / video). */
		providers: ProvidersConfigSchema.optional(),
		modelsDev: ModelsDevConfigSchema,
		/** Delivery / presentation concerns (currently `tts`). */
		messages: MessagesConfigSchema,
		update: UpdateConfigSchema,
		commands: CommandsConfigSchema
	}).default({
		agents: { defaults: {
			workspace: "~/.xopc/workspace",
			maxTokens: 8192,
			temperature: .7,
			maxToolIterations: 20,
			maxRequestsPerTurn: 50,
			maxToolFailuresPerTurn: 3,
			thinkingDefault: "medium",
			reasoningDefault: "stream",
			verboseDefault: "full",
			compaction: {
				enabled: true,
				mode: "default",
				reserveTokens: 8e3,
				triggerThreshold: .8,
				minMessagesBeforeCompact: 10,
				keepRecentMessages: 5,
				evictionWindow: .2,
				retentionWindow: 6
			},
			pruning: {
				enabled: true,
				maxToolResultChars: 1e4,
				headKeepRatio: .3,
				tailKeepRatio: .3
			},
			browser: { backend: "extension" }
		} },
		bindings: [],
		session: {
			scope: "per-sender",
			mainKey: "main",
			dmScope: "main"
		},
		channels: { telegram: {
			enabled: false,
			allowFrom: [],
			groupAllowFrom: [],
			debug: false,
			accounts: { default: {
				accountId: "default",
				enabled: true,
				botToken: "",
				allowFrom: [],
				dmPolicy: "pairing",
				groupPolicy: "open",
				replyToMode: "off",
				historyLimit: 50,
				textChunkLimit: 4e3,
				streamMode: "partial"
			} },
			dmPolicy: "pairing",
			groupPolicy: "open",
			replyToMode: "off",
			historyLimit: 50,
			textChunkLimit: 4e3
		} },
		gateway: {
			bind: "loopback",
			port: 18790,
			auth: { mode: "token" },
			heartbeat: {
				enabled: true,
				intervalMs: 18e5,
				includeSystemPromptSection: false
			},
			maxSseConnections: 100,
			corsOrigins: [],
			skillsMarketplaceProvider: "skillhub",
			skillsStoreBaseUrl: "https://store.xopc.ai"
		},
		tools: { web: { search: {
			maxResults: 5,
			providers: []
		} } },
		cron: {
			enabled: true,
			maxConcurrentJobs: 5,
			defaultTimezone: "UTC",
			historyRetentionDays: 7,
			enableMetrics: true
		},
		goals: {
			maxTurns: 20,
			checklistMode: true,
			maxConsecutiveParseFailures: 3,
			judgeTimeoutMs: 6e4,
			checklistHistoryChars: 24e3
		},
		extensions: {
			allow: [],
			security: {
				checkPermissions: true,
				allowUntrusted: false,
				allow: [],
				trackProvenance: true,
				allowPromptInjection: false
			},
			slots: {}
		},
		modelsDev: { enabled: true }
	});
}));
//#endregion
init_schema();
export { AgentConfigSchema, AgentDefaultsSchema, AgentImageGenerationModelSchema, AgentModelRefSchema, AgentTypedModelSchema, AgentsConfigSchema, BindingMatchSchema, BindingRuleSchema, BindingsConfigSchema, ChannelsConfigSchema, CommandsConfigSchema, ConfigSchema, CronConfigSchema, ExtensionSecurityConfigSchema, ExtensionSlotsConfigSchema, ExtensionsConfigSchema, GatewayAuthRateLimitSchema, GatewayAuthSchema, GatewayBindModeSchema, GatewayChannelConnectDeferModeSchema, GatewayConfigSchema, GatewayModeSchema, GatewayRemoteSchema, GatewaySecuritySchema, GatewayTailscaleConsentSchema, GatewayTailscaleSchema, GatewayTlsSchema, GatewayTrustedProxySchema, GoalsConfigSchema, HeartbeatConfigSchema, McpConfigSchema, McpServerSchema, MediaUnderstandingCapabilitiesSchema, MediaUnderstandingModelSchema, MessagesConfigSchema, ModelsDevConfigSchema, ProviderAuthConfigSchema, ProviderAzureConfigSchema, ProviderRequestOverridesSchema, ProvidersConfigSchema, STTConfigSchema, STTFallbackConfigSchema, STTProviderConfigSchema, SearchProviderEntrySchema, SessionConfigSchema, SessionDmScopeSchema, SessionResetByTypeSchema, SessionResetConfigSchema, SessionResetModeSchema, SessionScopeSchema, SessionStorageConfigSchema, TTSConfigSchema, TTSEdgeConfigSchema, TTSFallbackConfigSchema, TTSModelOverridesConfigSchema, TTSProviderConfigSchema, TTSSummarizationConfigSchema, TelegramAccountConfigSchema, TelegramConfigSchema, TelegramGroupConfigSchema, TelegramTopicConfigSchema, ToolsConfigSchema, ToolsMediaAudioConfigSchema, ToolsMediaConfigSchema, TunnelConfigSchema, TunnelConsentSchema, UpdateAutoConfigSchema, UpdateConfigSchema, WebSearchConfigSchema, WebToolsConfigSchema, WebsiteBlocklistSchema, WeixinAccountConfigSchema, WeixinConfigSchema, WorkspaceConfigSchema, WorkspaceImportConfigSchema, getAgentDefaultModelRef, init_schema, parseModelRef };

//# sourceMappingURL=schema.js.map