New to Claude Skills? Learn how to install them →

Acivitai on GitHub

Add Ecosystem

Free

Streamline onboarding of new model families.

by civitai7.2k stars on civitai/civitai
1 views
Updated Aug 10, 2026
Get this skill

Free · Opens the source repo

What Add Ecosystem does

The Add Ecosystem skill is designed to simplify the process of integrating new model families into the Civitai framework. It specifically targets the addition of new ecosystems and base model entries in the basemodel.constants.ts file. This skill is particularly useful when onboarding models from various providers such as Baidu, ByteDance, or Google, ensuring that the necessary constants and records are created accurately. The skill can also trigger additional support for model generation if needed, making it a comprehensive solution for model integration.

When using this skill, developers are guided through a structured workflow that begins with gathering essential model information. This includes details about the model's provider, licensing, and type, as well as an assessment of how the model is shipped. The skill emphasizes the importance of determining whether a new ecosystem is necessary based on compatibility, ensuring that resources are appropriately grouped. This prevents issues that could arise from incorrectly merging incompatible models, which could lead to resource conflicts.

The skill also provides a clear methodology for selecting IDs for new ecosystems and base models, ensuring that they fit within the existing structure of the Civitai ecosystem. By following a systematic approach to confirm the plan with the user before making any changes, it minimizes the risk of errors during the integration process. Overall, Add Ecosystem is a valuable tool for developers looking to expand the capabilities of the Civitai platform with new model families while maintaining compatibility and organization.

When to use it

Use this skill when integrating a new model from a provider or adding a variant that requires its own ecosystem due to compatibility issues.

When not to use it

Avoid using this skill for minor updates or when the model can share an ecosystem with existing models without compatibility concerns.

What you can build with it

Onboarding a New Model Provider

When adding a model from a new provider like Baidu, this skill ensures all necessary constants are created.

Creating a New Model Variant

If a new variant requires its own ecosystem due to incompatibility, this skill helps establish it correctly.

Ensuring Compatibility of Resources

Use this skill to verify that resources can be shared between models before integrating them into Civitai.

How to install Add Ecosystem

View source

1. Install with the skills CLI

npx skills add civitai/civitai/add-ecosystem --agent claude-code

2. Or install it manually

Download the skill folder and drop it into ~/.claude/skills/ for all projects, or .claude/skills/ to scope it to one repo. Restart Claude Code so it picks up the new skill.

Anthropic's agentic coding CLI, and the reference implementation of Agent Skills. Drop a skill folder into ~/.claude/skills and Claude Code loads it automatically whenever a task matches the skill's description. Claude Code docs

Inside SKILL.md

Written by civitai

Add Ecosystem

Adds a new ecosystem and base model entry to basemodel.constants.ts. Everything else downstream (generation support, graph, handler, workflow wiring) is handled by the add-generation-support skill.

When to use

Use when a new model provider or variant is being added to Civitai — e.g., new provider (Baidu's Ernie), new architecture (Flux's Kontext), or a variant of an existing family whose resources aren't interchangeable with its siblings.

The test: does this need its own ecosystem?

Answer this before picking IDs. The ecosystem is the compatibility key, not a UI grouping and not a media label:

A variant needs its own ecosystem when a LoRA (or other addon) trained for it would NOT work on every model carrying the sibling's baseModel.

That is the whole test. getGenerationSupport returns 'full' unconditionally for same-ecosystem pairs — there is no media dimension and no per-model nuance in it. Putting two things in one ecosystem asserts "resources cross freely between these," so only do it when that's true.

Architecture is not weights. The most common way to get this wrong is reading a vendor's "one unified model" marketing as "one checkpoint." Providers routinely ship a shared architecture as separate weight releases, and a LoRA is trained against weights. Check what actually ships — distinct releases, distinct sizes, distinct endpoints — not what the announcement calls the family.

Do not split on output media. "Image vs video" is not the question; "do resources cross" is. If one checkpoint does both, that's one ecosystem with a type: ['image', 'video'] base model (Grok). If they're separate checkpoints that happen to differ in output media, that's two ecosystems (Wan Image 2.7 / Wan Video 2.7 — note there are deliberately no crossEcosystemRules between them).

When genuinely unsure, split. The two mistakes are not symmetric:

ChoiceIf wrongCost to fix
Split, but they're compatibleResources don't crossAdd crossEcosystemRules entries — additive, that's what the mechanism is for
Merged, but they're incompatibleIncompatible resources offered as compatibleChange the ecosystem key → changes the AIR URN namespace on already-published resources

Splitting is reversible; merging is not. This is doubly true for API-only / modelLocked ecosystems, where no community resources exist yet — the split costs nothing today and preserves the option.

Media-specific labelling for creators is a BaseModelRecord concern, not an ecosystem one — several base models can share one ecosystem, each with its own name and type.

Workflow (interactive after research)

Do research first, then ask the user only for what can't be inferred.

1. Gather model info

Ask the user for the model name and a reference link (HuggingFace page, official repo, announcement). Then research before asking anything else:

  • WebFetch the reference link to extract:
    • Provider/company (drives family selection)
    • License (match against existing licenses array or flag as new)
    • Model type (image vs video — sometimes both)
    • How it actually ships — one checkpoint or several separate weight releases? This decides the ecosystem split (see "The test" above), so read for distinct releases/sizes/endpoints rather than trusting the family name.
    • Short description for the base model record
  • Search the codebase for prior patterns: Grep for the provider name to see if a family already exists

2. Pick IDs

Read the current state of basemodel.constants.ts to determine the next available IDs. Use Read with offsets — don't load the whole file.

  • ECO.<Name>: next available ecosystem ID. Groupings in ECO:
    • Image models: 1-50 range (first come, first served; find next gap)
    • Video models: 47-66 range
    • Utility: 66+
    • Child ecosystems (parentEcosystemId set): 100+ for SDXL children, 200+ for AuraFlow children
    • Pick the next unused number within the appropriate block
  • BM.<Name>: next available base model ID. Read the BM constant block, find the next unused number.
  • Family ID: try to match an existing family in ecosystemFamilies. If none match, propose creating a new one (confirm with user).
  • License ID: try to match an existing license in licenses by name/URL. If none match, create a new entry (confirm with user).
  • sortOrder: follow the pattern of the family. Image family numbers are usually sequential starting from an offset tied to the family. If the family has existing ecosystems, use the next number in its block. If new family, start at a round number (10, 20, 30, etc. — match surrounding patterns).

3. Confirm the plan with the user

Before editing, present a summary:

Adding ecosystem: <DisplayName>
- ECO.<Name> = <id>
- BM.<Name> = <id>
- Family: <existing family name> (familyId: <id>) OR [new: <name>]
- License: <existing license name> (licenseId: <id>) OR [new: <name>, <url>]
- Type: image | video
- sortOrder: <n>
- Description: "<short description>"

Wait for user confirmation. Accept corrections.

4. Make the edits

Apply all changes in one pass:

  1. ECO constant: add the new key under the appropriate section comment (e.g., // Baidu for Ernie). Keep sections grouped.
  2. BM constant: add the new key in the matching block.
  3. ecosystemFamilies (only if creating new): append at the end. Use the next family ID.
  4. licenses (only if creating new): append at the end. Use the next license ID.
  5. ecosystems: add the new EcosystemRecord under the right family's section comment. Include parentEcosystemId only if it's a child ecosystem (rare).
  6. baseModelRecords: add the new BaseModelRecord in alphabetical or thematic position (scan existing entries for the pattern).

5. Typecheck

pnpm run typecheck

If it fails, fix the error and re-run. Don't continue until clean.

6. Offer generation support

After the ecosystem is added and typecheck passes, ask:

Do you want to add generation support now? This wires the ecosystem into the generation form with a graph, handler, and workflow config. (Runs the add-generation-support skill.)

If yes, invoke the add-generation-support skill. If no, stop — the ecosystem record alone is enough for it to appear in model listings.

Note: making a new ecosystem generatable (GenerationBaseModel) and featurable in auctions (AuctionBase) are manual DB steps that the constants do not handle automatically — miss them and the feature silently half-works (this bit Anima and Krea 2). Those steps are documented in the add-generation-support skill under "Post-onboarding: generation coverage & auction featurability."

Record structures

EcosystemRecord

{
  id: ECO.<Name>,
  key: '<Name>',                // Stable identifier (e.g., 'Ernie')
  name: '<name>',               // lowercase (e.g., 'ernie')
  displayName: '<Display Name>', // UI (e.g., 'Ernie')
  familyId: <id>,
  sortOrder: <n>,
  parentEcosystemId?: <id>,     // Only for child ecosystems
  description?: string,         // Rarely needed
}

BaseModelRecord

{
  id: BM.<Name>,
  name: '<Name>',
  description: "<Provider>'s <type> generation model",
  type: 'image' | 'video' | ['image', 'video'],
  ecosystemId: ECO.<Name>,
  licenseId: <id>,
  hidden?: boolean,      // true if not user-facing yet
  experimental?: boolean,
  disabled?: boolean,
}

BaseModelFamilyRecord (create only if needed)

{
  id: <next id>,
  name: '<Provider Name>',
  description: "<Provider>'s <description of product lineup>",
}

LicenseRecord (create only if needed)

{
  id: <next id>,
  name: '<License Name>',       // Exact name from the source
  url: '<canonical license URL>',
  notice?: string,              // Only if the license requires a copyright notice
  poweredBy?: string,           // Only if attribution is required
  disableMature?: boolean,      // Only if the license prohibits NSFW
}

Notes

  • Do not add to ecosystemSupport, ecosystemSettings, workflows, graph, or handler files in this skill — those are generation-support concerns and belong to the add-generation-support skill.
  • Do not skip the typecheck step. The base model records are validated against ecosystem IDs, and a mismatch breaks the entire constants file.
  • If a new ecosystem is a child of an existing one (e.g., fine-tunes of SDXL), set parentEcosystemId and use a sort order from the child range (100+, 200+).
  • name (lowercase) is used for matching against orchestrator responses — keep it consistent with what the orchestrator returns.

Examples of past additions

  • Ernie (Baidu, image): new family, new license; ECO.Ernie = 67, BM.Ernie = 83, familyId 17, licenseId 13 (Apache 2.0 — matched existing).
  • Seedance (ByteDance, video): family 12 (ByteDance — existed), licenseId 23 (Seedream — shared with Seedream since ByteDance uses the same agreement).
  • Flux 3 Video (BFL, video): ECO.Flux3Video = 79, BM.Flux3Video = 98, family 1, new licenseId 39. A worked example of the split test — BFL announced FLUX-3 as one multimodal model, which reads like a single ecosystem, but it ships as separate weight releases (Video, Image, the open-weight Dev backbone). Shared architecture, different checkpoints ⇒ separate ecosystems, named for the modality so the siblings land without a rename. Same reasoning as the Flux.2 Klein variants, which share parentEcosystemId: ECO.Flux2 purely for AIR identity while their LoRAs do not cross.

Frequently asked questions about Add Ecosystem

Similar skills