fix: enforce strict config validation

This commit is contained in:
Peter Steinberger
2026-01-19 03:38:51 +00:00
parent a9fc2ca0ef
commit d1e9490f95
53 changed files with 1025 additions and 821 deletions

View File

@@ -30,6 +30,7 @@ export const HeartbeatSchema = z
prompt: z.string().optional(),
ackMaxChars: z.number().int().nonnegative().optional(),
})
.strict()
.superRefine((val, ctx) => {
if (!val.every) return;
try {
@@ -69,7 +70,7 @@ export const SandboxDockerSchema = z
z.object({
soft: z.number().int().nonnegative().optional(),
hard: z.number().int().nonnegative().optional(),
}),
}).strict(),
]),
)
.optional(),
@@ -79,6 +80,7 @@ export const SandboxDockerSchema = z
extraHosts: z.array(z.string()).optional(),
binds: z.array(z.string()).optional(),
})
.strict()
.optional();
export const SandboxBrowserSchema = z
@@ -98,6 +100,7 @@ export const SandboxBrowserSchema = z
autoStart: z.boolean().optional(),
autoStartTimeoutMs: z.number().int().positive().optional(),
})
.strict()
.optional();
export const SandboxPruneSchema = z
@@ -105,6 +108,7 @@ export const SandboxPruneSchema = z
idleHours: z.number().int().nonnegative().optional(),
maxAgeDays: z.number().int().nonnegative().optional(),
})
.strict()
.optional();
export const ToolPolicySchema = z
@@ -112,6 +116,7 @@ export const ToolPolicySchema = z
allow: z.array(z.string()).optional(),
deny: z.array(z.string()).optional(),
})
.strict()
.optional();
export const ToolsWebSearchSchema = z
@@ -123,6 +128,7 @@ export const ToolsWebSearchSchema = z
timeoutSeconds: z.number().int().positive().optional(),
cacheTtlMinutes: z.number().nonnegative().optional(),
})
.strict()
.optional();
export const ToolsWebFetchSchema = z
@@ -133,6 +139,7 @@ export const ToolsWebFetchSchema = z
cacheTtlMinutes: z.number().nonnegative().optional(),
userAgent: z.string().optional(),
})
.strict()
.optional();
export const ToolsWebSchema = z
@@ -140,17 +147,20 @@ export const ToolsWebSchema = z
search: ToolsWebSearchSchema,
fetch: ToolsWebFetchSchema,
})
.strict()
.optional();
export const ToolProfileSchema = z
.union([z.literal("minimal"), z.literal("coding"), z.literal("messaging"), z.literal("full")])
.optional();
export const ToolPolicyWithProfileSchema = z.object({
allow: z.array(z.string()).optional(),
deny: z.array(z.string()).optional(),
profile: ToolProfileSchema,
});
export const ToolPolicyWithProfileSchema = z
.object({
allow: z.array(z.string()).optional(),
deny: z.array(z.string()).optional(),
profile: ToolProfileSchema,
})
.strict();
// Provider docking: allowlists keyed by provider id (no schema updates when adding providers).
export const ElevatedAllowFromSchema = z
@@ -169,6 +179,7 @@ export const AgentSandboxSchema = z
browser: SandboxBrowserSchema,
prune: SandboxPruneSchema,
})
.strict()
.optional();
export const AgentToolsSchema = z
@@ -182,6 +193,7 @@ export const AgentToolsSchema = z
enabled: z.boolean().optional(),
allowFrom: ElevatedAllowFromSchema,
})
.strict()
.optional(),
exec: z
.object({
@@ -199,15 +211,19 @@ export const AgentToolsSchema = z
enabled: z.boolean().optional(),
allowModels: z.array(z.string()).optional(),
})
.strict()
.optional(),
})
.strict()
.optional(),
sandbox: z
.object({
tools: ToolPolicySchema,
})
.strict()
.optional(),
})
.strict()
.optional();
export const MemorySearchSchema = z
@@ -218,6 +234,7 @@ export const MemorySearchSchema = z
.object({
sessionMemory: z.boolean().optional(),
})
.strict()
.optional(),
provider: z.union([z.literal("openai"), z.literal("local"), z.literal("gemini")]).optional(),
remote: z
@@ -233,8 +250,10 @@ export const MemorySearchSchema = z
pollIntervalMs: z.number().int().nonnegative().optional(),
timeoutMinutes: z.number().int().positive().optional(),
})
.strict()
.optional(),
})
.strict()
.optional(),
fallback: z
.union([z.literal("openai"), z.literal("gemini"), z.literal("local"), z.literal("none")])
@@ -245,6 +264,7 @@ export const MemorySearchSchema = z
modelPath: z.string().optional(),
modelCacheDir: z.string().optional(),
})
.strict()
.optional(),
store: z
.object({
@@ -255,14 +275,17 @@ export const MemorySearchSchema = z
enabled: z.boolean().optional(),
extensionPath: z.string().optional(),
})
.strict()
.optional(),
})
.strict()
.optional(),
chunking: z
.object({
tokens: z.number().int().positive().optional(),
overlap: z.number().int().nonnegative().optional(),
})
.strict()
.optional(),
sync: z
.object({
@@ -272,6 +295,7 @@ export const MemorySearchSchema = z
watchDebounceMs: z.number().int().nonnegative().optional(),
intervalMinutes: z.number().int().nonnegative().optional(),
})
.strict()
.optional(),
query: z
.object({
@@ -284,25 +308,32 @@ export const MemorySearchSchema = z
textWeight: z.number().min(0).max(1).optional(),
candidateMultiplier: z.number().int().positive().optional(),
})
.strict()
.optional(),
})
.strict()
.optional(),
cache: z
.object({
enabled: z.boolean().optional(),
maxEntries: z.number().int().positive().optional(),
})
.strict()
.optional(),
})
.strict()
.optional();
export const AgentModelSchema = z.union([
z.string(),
z.object({
primary: z.string().optional(),
fallbacks: z.array(z.string()).optional(),
}),
z
.object({
primary: z.string().optional(),
fallbacks: z.array(z.string()).optional(),
})
.strict(),
]);
export const AgentEntrySchema = z.object({
export const AgentEntrySchema = z
.object({
id: z.string(),
default: z.boolean().optional(),
name: z.string().optional(),
@@ -323,14 +354,16 @@ export const AgentEntrySchema = z.object({
z.object({
primary: z.string().optional(),
fallbacks: z.array(z.string()).optional(),
}),
}).strict(),
])
.optional(),
})
.strict()
.optional(),
sandbox: AgentSandboxSchema,
tools: AgentToolsSchema,
});
})
.strict();
export const ToolsSchema = z
.object({
@@ -353,27 +386,33 @@ export const ToolsSchema = z
prefix: z.string().optional(),
suffix: z.string().optional(),
})
.strict()
.optional(),
})
.strict()
.optional(),
broadcast: z
.object({
enabled: z.boolean().optional(),
})
.strict()
.optional(),
})
.strict()
.optional(),
agentToAgent: z
.object({
enabled: z.boolean().optional(),
allow: z.array(z.string()).optional(),
})
.strict()
.optional(),
elevated: z
.object({
enabled: z.boolean().optional(),
allowFrom: ElevatedAllowFromSchema,
})
.strict()
.optional(),
exec: z
.object({
@@ -391,18 +430,23 @@ export const ToolsSchema = z
enabled: z.boolean().optional(),
allowModels: z.array(z.string()).optional(),
})
.strict()
.optional(),
})
.strict()
.optional(),
subagents: z
.object({
tools: ToolPolicySchema,
})
.strict()
.optional(),
sandbox: z
.object({
tools: ToolPolicySchema,
})
.strict()
.optional(),
})
.strict()
.optional();