Skip to content

Unnecessary structuredClone on small, single-use config objects #8

@s2x

Description

@s2x

Description

The clone() helper in models.config.mjs:116-118 uses structuredClone() and is called in every getter function:

export function clone(value) {
  return value === undefined ? undefined : structuredClone(value);
}

Called from:

  • getModelLimit() (line 131) — clones { context: N, output: N }
  • getModelCost() (line 152, 156) — clones { input: N, output: N, cache_read: N, cache_write: N }
  • getModelVariants() (line 163) — clones variant objects
  • getModelOptions() (line 170) — clones { reasoningEffort: "none" }

Analysis

structuredClone() is designed for deep-cloning complex objects with circular references, typed arrays, Maps, Sets, etc. Here it's used on flat objects with 2-5 numeric/string fields.

In processModels(), these cloned objects are immediately assigned to models[displayName] and never mutated afterwards. The clone exists purely as defensive programming against a mutation that never happens.

Impact

  • structuredClone() is ~10-50x slower than object spread for small flat objects.
  • With 15+ supported models, that's 60+ unnecessary structuredClone calls per run.
  • In practice, the total wall-clock impact is sub-millisecond, so this is a code quality issue, not a performance bottleneck.

Proposed fix

Option A: Replace structuredClone with spread for flat objects:

export function clone(value) {
  return value === undefined ? undefined : { ...value };
}

Option B: Remove clone() entirely — the objects from SUPPORTED_MODELS are literals that are never mutated:

export function getModelLimit(displayName, apiModel = null) {
  const config = getModelConfig(displayName);
  if (config?.limit) return config.limit;
  // ...
}

Option C: Keep clone() but document why defensive copying is needed (if there's a downstream mutation scenario I'm not seeing).

Acceptance criteria

  • structuredClone() is replaced with a lighter-weight approach or removed.
  • All existing unit tests pass without modification.
  • SUPPORTED_MODELS values are not mutated by any code path (verify or add a freeze-based test).

🤖 Generated with Claude Code

Metadata

Metadata

Assignees

No one assigned

    Labels

    enhancementNew feature or request

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions