Skip to content

Releases: SmooAI/config

v6.7.0

02 Jun 20:25
003a202

Choose a tag to compare

Minor Changes

  • ad2c77f: SMOODEV-1526: Port the ESO manifest generator (buildClusterSecretStore + buildExternalSecret) to the Go, Python, Rust, and C# SDKs for language parity with the TypeScript reference. Each emits the same ClusterSecretStore (webhook → real api.smoo.ai config-values endpoint) and per-workload ExternalSecret (secret-tier config keys → UPPER_SNAKE_CASE env vars, with overrides + duplicate guard), using each language's native snakecase util. Epic SMOODEV-1522.
  • ad2c77f: SMOODEV-1526: Port the ESO bearer-token refresher core (the refresh algorithm + SecretWriter abstraction) to the Go, Python, Rust, and C# SDKs for parity with the TypeScript reference. Each mirrors the same behavior — invalidate-then-mint each cycle so the bootstrap Secret always holds a near-full-TTL token, fail-loud initial write, non-fatal loop-tick retries — driven by the language's own TokenProvider and unit-tested with a fake writer (no live cluster). The k8s-backed writer is intentionally an optional adapter so base SDK consumers don't pull a heavy k8s client; the TypeScript sidecar remains the canonical deployable. Epic SMOODEV-1522.

v6.6.0

02 Jun 19:25
552eac2

Choose a tag to compare

Minor Changes

  • bb64793: SMOODEV-1524: Add an ESO manifest generator (@smooai/config/eso-manifests). buildClusterSecretStore() emits a ClusterSecretStore whose webhook provider points at the real api.smoo.ai config-values endpoint (org + environment baked in, bearer from the bootstrap Secret the eso-refresher keeps fresh), and buildExternalSecret() emits a per-workload ExternalSecret mapping secret-tier config keys to env-var names (UPPER_SNAKE_CASE by default, with per-key overrides like DASHSCOPE_API_KEYalibabaModelStudioApiKey). Replaces the hand-maintained ESO YAML and makes ESO sync a first-class output of the config system. Epic SMOODEV-1522.

v6.5.0

02 Jun 18:50
d8f2d21

Choose a tag to compare

Minor Changes

  • 8fe21bd: SMOODEV-1523: Add an ESO bearer-token refresher (@smooai/config/eso-refresher + smooai-config-eso-refresher bin). It re-mints the OAuth2 client_credentials access token on a short interval (reusing TokenProvider) and writes it into the ExternalSecrets bootstrap Kubernetes Secret, so ESO's webhook provider always reads a fresh, non-expired bearer. This is what lets workload secrets sync via ESO instead of being Pulumi-baked at SST deploy time — decoupling @smooai/config secret-value changes from the ~1h platform deploy (epic SMOODEV-1522).

v6.4.0

01 Jun 01:19
ef385ed

Choose a tag to compare

Minor Changes

  • 2bff2d9: SMOODEV-1494: Add container/runtime mode to the Rust SDK (smooai_config::container) — parity with the TypeScript reference (SMOODEV-1490) and the five-language contract (SMOODEV-1489).

    Container mode makes the HTTP config API the first-class, fail-loud path for long-lived containers (EKS/ECS) instead of the Lambda-oriented baked blob:

    • init_container_config(InitContainerConfigOptions) -> Result<ContainerConfigHandle, ConfigError> — validates the container env contract, mints an M2M OAuth token, and performs an initial config fetch so auth/network/missing-env failures surface at startup (not first read). Missing/blank required env returns ConfigError::Bootstrap(ConfigBootstrapError { missing }) listing exactly which vars are absent.

    • Fail-loud reads — handle.secret_config()/public_config()/feature_flag() each expose get(key).await and get_sync(key) that return Err(ConfigError::KeyUnresolved(ConfigKeyUnresolvedError { key, env, tried_tiers })) for a required key that resolves absent, instead of silently returning Ok(None) (the SMOODEV-1478 CrashLoop class). optional_keys opts specific keys out (returning Ok(None)).

    • config_health(&handle) / handle.health() -> ConfigHealth — non-failing status for Kubernetes readiness/liveness probes; serves last-good within the 30s cache TTL, reports Unhealthy { reason } past hard-expiry.

    • select_mode(Option<SelectModeInputs>) -> Mode — mode selection (explicit SMOOAI_CONFIG_MODE=container, blob/file present → Default, or auto-select on M2M creds).

    • Typed errors ConfigBootstrapError, ConfigKeyUnresolvedError, and ConfigTier (blob|env|http|file) mirror the TS shapes/fields; constants DEFAULT_CACHE_TTL (30s) and DEFAULT_TOKEN_REFRESH_BUFFER_SECONDS (60). On a 401 the token is invalidated and the request retried once.

      README gains a "Container / Runtime Mode" section linking the shared docs/Container-Runtime-Mode.md.

v6.3.0

01 Jun 01:13
d59f22a

Choose a tag to compare

Minor Changes

  • 68a1737: SMOODEV-1491: Add container/runtime mode to the .NET SDK (SmooAI.Config.Container) — brings the C# client to parity with the TypeScript reference (SMOODEV-1490) of the five-language contract (SMOODEV-1489).

    Container mode makes the HTTP config API the first-class, fail-loud path for long-lived containers (EKS/ECS) instead of the Lambda-oriented baked blob:

    • ContainerConfig.InitContainerConfigAsync(options) — validates the container env contract, mints an M2M OAuth token, and does an initial fetch-all-values so auth/network failures surface at startup (not first read). Missing/blank required env throws a typed ConfigBootstrapException carrying Missing (the exact env var names).
    • Fail-loud reads — SecretConfig.GetAsync/GetSync (and the public/flag analogs) throw ConfigKeyUnresolvedException { Key, Env, TriedTiers } for a required key that resolves absent, instead of silently returning null (the SMOODEV-1478 CrashLoop class). OptionalKeys opts specific keys out. Per the TS design fork, all schema keys are required by default.
    • ContainerConfig.Health(handle) / handle.Health() — non-throwing ConfigHealth { Status, Reason } for Kubernetes readiness/liveness probes; serves last-good within the 30s cache TTL, reports unhealthy past hard-expiry.
    • ContainerConfig.SelectMode(inputs) — mode selection (explicit SMOOAI_CONFIG_MODE=container, blob/file present → default, or auto-select on M2M creds).
    • Same exact SMOOAI_CONFIG_* env contract, env-over-http tier precedence, UPPER_SNAKE_CASE(key) env overrides, 30s cache TTL, 60s token refresh buffer, and 401 → refresh → retry as the TypeScript reference.
    • README "Container / Runtime Mode" section linking the shared docs/Container-Runtime-Mode.md.
  • fedbabf: SMOODEV-1492: Add container/runtime mode to the Go SDK (github.com/SmooAI/config/go/config/container) — bringing it to parity with the TypeScript reference (SMOODEV-1490) under the five-language contract (SMOODEV-1489).

    Container mode makes the HTTP config API the first-class, fail-loud path for long-lived containers (EKS/ECS) instead of the Lambda-oriented baked blob, with idiomatic Go semantics (error returns + context.Context, no panics on the error-returning path):

    • InitContainerConfig(ctx, opts) (*ContainerConfigHandle, error) — validates the container env contract, mints an M2M OAuth token, and does an initial fetch so auth/network failures surface at startup (not first read). Missing/blank required env returns a typed *ConfigBootstrapError listing exactly which vars are missing.
    • Fail-loud reads — handle.SecretConfig/PublicConfig/FeatureFlag: Get(key) (value, ok, err) returns *ConfigKeyUnresolvedError{ Key, Env, TriedTiers } for a required key that resolves absent (the SMOODEV-1478 CrashLoop class); MustGet(key) (value, ok) is the fail-loud sync analog that panics on the same. OptionalKeys opts specific keys out (returns the zero value, ok=false, no error).
    • handle.Health() ConfigHealth and container.ConfigHealthOf(handle) — non-erroring status for Kubernetes readiness/liveness probes; serves last-good within the 30s cache TTL, reports unhealthy past hard-expiry.
    • container.SelectMode(*SelectModeInputs) string — mode selection (explicit SMOOAI_CONFIG_MODE=container, blob/file present → default, or auto-select on M2M creds).
    • Same defaults as every SDK: 30s cache TTL, 60s token refresh buffer, 401→invalidate→retry once. New ConfigClient.SeedCache / ConfigClient.GetCachedValue helpers back the env-tier override + last-good serving.

v6.1.0

01 Jun 00:55
c6f00ef

Choose a tag to compare

Minor Changes

  • 5c9de91: SMOODEV-1490: Add container/runtime mode (@smooai/config/container) — the TypeScript reference implementation of the five-language parity contract (SMOODEV-1489).

    Container mode makes the HTTP config API the first-class, fail-loud path for long-lived containers (EKS/ECS) instead of the Lambda-oriented baked blob:

    • initContainerConfig(options?) — validates the container env contract, mints an M2M OAuth token, and does an initial config fetch so auth/network failures surface at startup (not first read). Missing/blank required env throws a typed ConfigBootstrapError listing exactly which vars are missing.
    • Fail-loud reads — secretConfig.get/getSync (and public/flag analogs) throw ConfigKeyUnresolvedError { key, env, triedTiers } for a required key that resolves absent, instead of silently returning undefined (the SMOODEV-1478 CrashLoop class). optionalKeys opts specific keys out.
    • configHealth() / handle.health() — non-throwing status for Kubernetes readiness/liveness probes; serves last-good within the 30s cache TTL, reports Unhealthy past hard-expiry.
    • selectMode() — mode selection (explicit SMOOAI_CONFIG_MODE=container, blob/file present → default, or auto-select on M2M creds).
    • New canonical doc docs/Container-Runtime-Mode.md with the env contract, an ExternalSecret (External Secrets Operator) recipe, and a readiness-probe example.

v6.0.1

14 May 21:25
5cd570f

Choose a tag to compare

Patch Changes

  • 85fafd9: SMOODEV-993: The CLI now honors SMOOAI_CONFIG_CLIENT_ID / SMOOAI_CONFIG_CLIENT_SECRET / SMOOAI_CONFIG_ORG_ID / SMOOAI_CONFIG_API_URL / SMOOAI_CONFIG_AUTH_URL (legacy SMOOAI_CONFIG_API_KEY and SMOOAI_AUTH_URL accepted) when those env vars are fully populated. The env-var-supplied OAuth credentials take precedence over ~/.smooai/credentials.json so smooai-config list/get/set etc. hit the same org as every other tool in the same shell — matches how scripts/bake-config-dev.ts, smoo-secrets/push-secrets.ts, and the prod deploy baker already authenticate. Falls back to ~/.smooai/credentials.json unchanged when env vars are absent. Fixes the silent org mismatch where the CLI could query a totally different account than the surrounding scripts (caused an entire investigation cycle to chase a "missing secrets" mirage that was actually just wrong-org auth).

v6.0.0

13 May 19:57
958e7e8

Choose a tag to compare

Major Changes

  • 722c705: SMOODEV-975/976/977: Python, Go, and Rust ConfigClients now exchange OAuth client_credentials for a JWT (parity with TS / .NET, fixing the silent 401s that previously sent the raw API key as Bearer). Each runtime SDK now requires client_id in addition to client_secret/api_key. New TokenProvider class exported in each language for caching/refresh (60s default refresh window, single-flight under a lock, invalidate-and-retry once on 401). Breaking change in constructors of all three SDKs.

v5.0.0

13 May 14:05
03163ad

Choose a tag to compare

Major Changes

  • aa6b007: SMOODEV-974: ConfigClient (TypeScript runtime) now exchanges OAuth client_credentials for a JWT and uses that JWT as the Bearer token on /config/values calls, matching the .NET SmooConfigClient, the in-package bootstrap, and the CLI.

    Breaking — all four broken language clients in this package previously sent the raw API key as the Bearer token, which the backend rejects with 401 because it expects a JWT. Live feature flag fetches and runtime config reads were therefore silent failures across TypeScript, Python, Go, and Rust. This release fixes TypeScript; Python / Go / Rust ship in follow-up tickets (SMOODEV-9xx).

    TypeScript migration:

    • Set both SMOOAI_CONFIG_CLIENT_ID and SMOOAI_CONFIG_CLIENT_SECRET (or the legacy SMOOAI_CONFIG_API_KEY) on every consumer Lambda / process. The runtime SDK now requires both.

    • new ConfigClient({...}) now requires clientId in addition to clientSecret (or apiKey). Constructing without clientId throws.

    • apiKey is preserved as a deprecated alias for clientSecret. Source-level code that passes apiKey continues to compile, but the value is now treated as the OAuth client secret (which is what it always was in the AuthDynamoTable).

    • New exported class TokenProvider in @smooai/config/platform — mirrors SmooAI.Config.OAuth.TokenProvider (mint, cache, 60s refresh window). Pass new TokenProvider({...}) via the tokenProvider option to override caching or for testing.

      No-change consumers:

    • bootstrap (@smooai/config/bootstrap) and the CLI were already doing the OAuth exchange — their behavior is unchanged.

    • .NET SmooConfigClient was already correct — unchanged.

    • Schema/build/manage tooling is unchanged.

      Behavior change to be aware of:

    • The TS runtime now makes an additional POST /token request on cold start (and after token expiry / 401). The JWT is cached in-memory for the lifetime of the ConfigClient instance, refreshed 60s before expiry. On a 401 response from /config/values or /evaluate, the cached token is invalidated and the call is retried once.

v4.7.4

12 May 17:29
ed999ba

Choose a tag to compare

Patch Changes

  • b36aa04: SMOODEV-957: Extend ConfigKey<T>.ResolveAsync in the .NET SDK to the full SMOODEV-857 priority chain — baked runtime → SMOOAI_CONFIG_<KEY> env var → live HTTP → local .smooai-config/<env>.json. Previously the .NET port only did baked → HTTP, so deployments that needed a single key overridden without a re-bake had no env-var path, and dev laptops without network connectivity had no file-tier fallback.
    • Env-var names follow the existing convention (moonshotApiKeySMOOAI_CONFIG_MOONSHOT_API_KEY). JSON-shaped values are parsed; primitives become JSON strings so the typed deserializer round-trips correctly.
    • File-tier reads from $SMOOAI_CONFIG_FILE_DIR/<env>.json (or ./.smooai-config/<env>.json). Malformed or missing files are silent — same posture as TS / Python / Rust / Go.
    • HTTP failures (HttpRequestException, SmooConfigApiException, request timeouts) fall through to the file tier so an offline laptop can still resolve from local defaults. Caller cancellation still propagates.
    • SmooConfigClient.DefaultEnvironment is now exposed internally so the file-tier lookup aligns with whatever env name the HTTP tier would have used.