import { z } from "zod"; import * as Path from "@std/path"; // NOTE: This is where we define the environment variable types and defaults. const EnvSchema = z.object({ ENV: z.string().default("development"), HOST: z.string().default("0.0.0.0"), PORT: z.coerce.number().default(8000), LOG_LEVEL: z.enum([ "fatal", "error", "warn", "info", "debug", "trace", "silent", ]).default("info"), DISABLE_LOG_REQ_RES: z.coerce.boolean().default(false), CACHE_DIR: z.string().default("./cache"), // =========================================================================== // OpenTelemetry Configuration // =========================================================================== OTEL_ENABLED: z.coerce.boolean().default(true), OTEL_SERVICE_NAME: z.string().default("toolshed"), OTEL_EXPORTER_OTLP_ENDPOINT: z.string().default("http://localhost:4318"), OTEL_TRACES_SAMPLER: z.string().default("always_on"), OTEL_TRACES_SAMPLER_ARG: z.string().default("1.0"), // =========================================================================== // =========================================================================== // (/routes/ai/llm) Environment variables for LLM Providers // =========================================================================== CTTS_AI_LLM_ANTHROPIC_API_KEY: z.string().default(""), CTTS_AI_LLM_GROQ_API_KEY: z.string().default(""), CTTS_AI_LLM_OPENAI_API_KEY: z.string().default(""), CTTS_AI_LLM_CEREBRAS_API_KEY: z.string().default(""), CTTS_AI_LLM_PERPLEXITY_API_KEY: z.string().default(""), CTTS_AI_LLM_AWS_ACCESS_KEY_ID: z.string().default(""), CTTS_AI_LLM_AWS_SECRET_ACCESS_KEY: z.string().default(""), CTTS_AI_LLM_GOOGLE_APPLICATION_CREDENTIALS: z.string().default(""), CTTS_AI_LLM_GOOGLE_VERTEX_PROJECT: z.string().default(""), CTTS_AI_LLM_GOOGLE_VERTEX_LOCATION: z.string().default(""), CTTS_AI_LLM_XAI_API_KEY: z.string().default(""), // LLM Observability Tool CTTS_AI_LLM_PHOENIX_PROJECT: z.string().default(""), CTTS_AI_LLM_PHOENIX_URL: z.string().default(""), CTTS_AI_LLM_PHOENIX_API_URL: z.string().default(""), CTTS_AI_LLM_PHOENIX_API_KEY: z.string().default(""), // =========================================================================== // =========================================================================== // FAL AI API Key // * /routes/ai/img // * /routes/ai/voice // =========================================================================== FAL_API_KEY: z.string().default(""), // =========================================================================== // =========================================================================== // Jina API Key // * /routes/ai/webreader // =========================================================================== JINA_API_KEY: z.string().default(""), // =========================================================================== // // =========================================================================== // Discord Webhook URL // * /routes/integration/discord // =========================================================================== DISCORD_WEBHOOK_URL: z.string().default(""), LLM_HEALTH_DISCORD_WEBHOOK: z.string().default(""), HOSTNAME: z.string().default(""), // =========================================================================== // Memory Store // - MEMORY_DIR is used by toolshed to access sqlite files for common-memory // (directory mode - default, backwards compatible) // - DB_PATH is an optional absolute path to a single SQLite database file // (single-file mode - for clusterduck clustering) // - MEMORY_URL is used by toolshed to connect to memory endpoint // =========================================================================== MEMORY_DIR: z.string().default( new URL(`./cache/memory/`, Path.toFileUrl(`${Deno.cwd()}/`)).href, ), DB_PATH: z.string().refine( (path) => !path || Path.isAbsolute(path), { message: "DB_PATH must be an absolute path" }, ).optional(), MEMORY_URL: z.string().default("http://localhost:8000"), GOOGLE_CLIENT_ID: z.string().default(""), GOOGLE_CLIENT_SECRET: z.string().default(""), // =========================================================================== // Plaid Integration // * /routes/integrations/plaid-oauth // =========================================================================== PLAID_CLIENT_ID: z.string().default(""), PLAID_SECRET: z.string().default(""), PLAID_ENV: z.enum(["sandbox", "development", "production"]).default( "sandbox", ), PLAID_PRODUCTS: z.string().default("transactions"), PLAID_COUNTRY_CODES: z.string().default("US"), PLAID_REDIRECT_URI: z.string().optional(), PLAID_SYNC_ALL_TRANSACTIONS: z.coerce.boolean().default(false), // =========================================================================== // URL of the toolshed API, for self-referring requests API_URL: z.string().default("http://localhost:8000"), // DEPRECATED: Identity signer passphrase for storage authentication IDENTITY_PASSPHRASE: z.string().default("implicit trust"), // Path to an identity key. IDENTITY: z.string().default(""), // In development, you can optionally proxy the upstream SHELL SHELL_URL: z.string().optional(), }); export type env = z.infer; const { data: env, error } = EnvSchema.safeParse(Deno.env.toObject()); if (error) { console.error("❌ Invalid env:"); console.error(JSON.stringify(error.flatten().fieldErrors, null, 2)); Deno.exit(1); } export default env!;