UNPKG

@stackmemoryai/stackmemory

Version:

Lossless, project-scoped memory for AI coding tools. Durable context across sessions with 56 MCP tools, FTS5 search, conductor orchestrator, loop/watch monitoring, snapshot capture, pre-flight overlap checks, Claude/Codex/OpenCode wrappers, Linear sync, a

91 lines (90 loc) 2.95 kB
import { fileURLToPath as __fileURLToPath } from 'url'; import { dirname as __pathDirname } from 'path'; const __filename = __fileURLToPath(import.meta.url); const __dirname = __pathDirname(__filename); import { z } from "zod"; import { logConfigInvalid } from "./security-logger.js"; const AutoBackgroundConfigSchema = z.object({ enabled: z.boolean(), timeoutMs: z.number().int().min(1e3).max(6e5), alwaysBackground: z.array(z.string().max(200)).max(100), neverBackground: z.array(z.string().max(200)).max(100), verbose: z.boolean().optional() }); const ModelProviderSchema = z.enum([ "anthropic", "qwen", "openai", "ollama", "cerebras", "deepinfra", "openrouter", "anthropic-batch", "custom" ]); const ModelConfigSchema = z.object({ provider: ModelProviderSchema, model: z.string().max(100), baseUrl: z.string().url().max(500).optional(), apiKeyEnv: z.string().max(100), headers: z.record(z.string().max(500)).optional(), params: z.record(z.unknown()).optional() }); const ModelRouterConfigSchema = z.object({ enabled: z.boolean(), defaultProvider: ModelProviderSchema, taskRouting: z.object({ plan: ModelProviderSchema.optional(), think: ModelProviderSchema.optional(), code: ModelProviderSchema.optional(), review: ModelProviderSchema.optional(), linting: ModelProviderSchema.optional(), context: ModelProviderSchema.optional(), testing: ModelProviderSchema.optional() }).optional().default({}), fallback: z.object({ enabled: z.boolean(), provider: ModelProviderSchema, onRateLimit: z.boolean(), onError: z.boolean(), onTimeout: z.boolean(), maxRetries: z.number().int().min(0).max(10), retryDelayMs: z.number().int().min(100).max(3e4) }), providers: z.object({ anthropic: ModelConfigSchema.optional(), qwen: ModelConfigSchema.optional(), openai: ModelConfigSchema.optional(), ollama: ModelConfigSchema.optional(), cerebras: ModelConfigSchema.optional(), deepinfra: ModelConfigSchema.optional(), openrouter: ModelConfigSchema.optional(), "anthropic-batch": ModelConfigSchema.optional(), custom: ModelConfigSchema.optional() }).optional().default({}), thinkingMode: z.object({ enabled: z.boolean(), budget: z.number().int().min(1e3).max(1e5).optional(), temperature: z.number().min(0).max(2).optional(), topP: z.number().min(0).max(1).optional() }) }); function parseConfigSafe(schema, data, defaultValue, configName) { const result = schema.safeParse(data); if (result.success) { return result.data; } const errors = result.error.issues.map( (i) => `${i.path.join(".")}: ${i.message}` ); logConfigInvalid(configName, errors); console.error(`[hooks] Invalid ${configName} config:`, errors.join(", ")); return defaultValue; } export { AutoBackgroundConfigSchema, ModelConfigSchema, ModelProviderSchema, ModelRouterConfigSchema, parseConfigSafe };