Configuration

A SMRT project is configured by a single smrt.config.ts file at the project root. defineConfig() gives you typed editing of that file, and helpers like getModuleConfig() read it back — merged with runtime overrides — wherever you need it.

smrt.config.ts

smrt init scaffolds the file. defineConfig() is an identity function — it returns its argument unchanged — so its only job is to type-check the object literal and power editor autocompletion.

typescript
// smrt.config.ts
import { defineConfig } from '@happyvertical/smrt-config';

export default defineConfig({
  // Global SMRT settings — the lowest-priority base for every module.
  smrt: {
    logLevel: 'info',
    environment: 'development',
    schemaMigration: { strategy: 'auto-add' },
    embeddings: { provider: 'local' }
  },

  // Package-scoped config, keyed by package name.
  packages: {
    cli: {
      database: {
        type: 'sqlite',
        url: process.env.DATABASE_URL || './data/app.db'
      }
    },
    ai: process.env.OPENAI_API_KEY
      ? { provider: 'openai', apiKey: process.env.OPENAI_API_KEY }
      : undefined
  },

  // Module-scoped config, keyed by a name you choose.
  modules: {
    'my-agent': { cronSchedule: '0 2 * * *', maxRetries: 3 }
  }
});

The five top-level sections

Every key in SmrtConfig is optional. The five sections are:

KeyPurposeRead with
smrtGlobal framework options (log level, environment, schema migration, embeddings).Merged into every module/package lookup as the base layer.
modulesYour own module configs, keyed by a name you pick.getModuleConfig(name)
packagesConfig sections owned by @happyvertical/smrt-* packages.getPackageConfig(name)
siteSite identity for the site templates (name, navigation, theme).getSiteConfig()
exportStatic-site-generation options.Read by the export tooling.

Reading config at runtime

getModuleConfig(name, defaults) returns the resolved config for a module, merging four layers in ascending priority:

  1. defaults you pass at the call site (lowest priority)
  2. the global smrt section
  3. the modules[name] section of the loaded file
  4. runtime overrides set via setConfig() (highest priority)
typescript
import { getModuleConfig } from '@happyvertical/smrt-config';
import { Agent } from '@happyvertical/smrt-agents';
import { smrt } from '@happyvertical/smrt-core';

@smrt()
class MyAgent extends Agent {
  // Reads modules['my-agent'] from smrt.config.ts, falling back to defaults.
  protected config = getModuleConfig('my-agent', {
    cronSchedule: '0 2 * * *',
    maxRetries: 3
  });

  async run(): Promise<void> {
    for (let attempt = 0; attempt < this.config.maxRetries; attempt++) {
      // ...
    }
  }
}

getPackageConfig(name, defaults) is identical but reads from packages[name] instead. Packages use it to expose their own section without clashing with your module names.

typescript
// Inside an @happyvertical/smrt-* package
import { getPackageConfig } from '@happyvertical/smrt-config';

const config = getPackageConfig('ai', {
  defaultModel: 'gpt-4o-mini',
  maxTokens: 2048
});

Loading and overriding

In a Vite/SvelteKit project the bundler transpiles smrt.config.ts for you. Tools that run outside the bundler load it explicitly with loadConfig(), which searches upward from the working directory and caches the result.

typescript
import { loadConfig, getConfig, setConfig } from '@happyvertical/smrt-config';

// Load once at startup (e.g. in a CLI entrypoint or test setup)
await loadConfig();

// Read the whole resolved config
const config = getConfig();

// Apply a runtime override — wins over the file for subsequent reads
setConfig({ smrt: { logLevel: 'debug' } });

Common global settings

SettingValuesEffect
smrt.logLevel'debug' | 'info' | 'warn' | 'error'Framework log verbosity.
smrt.environment'development' | 'production' | 'test'Environment-aware behavior.
smrt.schemaMigration.strategy'warn' | 'auto-add'Whether to auto-apply additive schema changes or only warn.
smrt.embeddings.provider'local' | 'ai' | 'auto'Default embedding provider for semantic search.
smrt.embeddings.storage'json' | 'native'Store vectors as JSON (portable) or use native vector ops when available.

Related

Verified against SMRT v0.29.34.