Navigation: Developer Index Providers OverviewAtlasCloud

Audience: contributors and coding agents adding AtlasCloud models or node classes. No familiarity with the runtime internals is assumed; you need to edit JSON and run two commands.

TL;DR

  1. Add an entry to packages/atlascloud-nodes/src/atlascloud-manifest.json.
  2. Run npm run build:packages to copy the manifest into dist/.
  3. Run npm run typecheck && npm run test --workspace=packages/atlascloud-nodes.

That’s it. No TypeScript code is required for most new models. Skip to Add a new model/node for the exact steps.


Where things live

What Path
Manifest (hand-maintained JSON, single source of truth) packages/atlascloud-nodes/src/atlascloud-manifest.json
Manifest copy in dist/ (generated by build) packages/atlascloud-nodes/dist/atlascloud-manifest.json
Node class factory (reads manifest at runtime) packages/atlascloud-nodes/src/atlascloud-factory.ts
HTTP helpers, poll/submit/download packages/atlascloud-nodes/src/atlascloud-base.ts
Package entry point (exports ATLASCLOUD_NODES) packages/atlascloud-nodes/src/index.ts
Runtime provider (image/video model lists, textToImage etc.) packages/runtime/src/providers/atlascloud-provider.ts
Provider registration packages/runtime/src/providers/index.ts line 222
Manifest-to-model-list helper (shared with KIE, FAL) packages/runtime/src/providers/manifest-models.ts

How AtlasCloud models/nodes are defined

There is no codegen script. atlascloud-manifest.json is hand-maintained. It is the single file you edit to add a model.

Manifest → node class

packages/atlascloud-nodes/src/index.ts reads the manifest with readFileSync at module load time and passes it to loadAtlasNodesFromManifest. That function calls createAtlasNodeClass once per manifest entry. createAtlasNodeClass (in atlascloud-factory.ts) produces a BaseNode subclass whose nodeType is atlascloud.<moduleName>.<className>, whose input props match the fields array, and whose process() method calls atlasSubmit → atlasPoll → atlasDownload.

The build script in package.json compiles TypeScript then copies src/atlascloud-manifest.json to dist/:

"build": "node ../../scripts/build-typescript-workspace.mjs && node -e \"require('node:fs').cpSync('src/atlascloud-manifest.json', 'dist/atlascloud-manifest.json')\""

The manifest export declared in package.json is:

"./atlascloud-manifest.json": "./dist/atlascloud-manifest.json"

Manifest → model list (provider)

AtlasCloudProvider.getAvailableImageModels() and getAvailableVideoModels() call loadImageModels / loadVideoModels from manifest-models.ts, which requires the manifest via @nodetool-ai/atlascloud-nodes/atlascloud-manifest.json. The model-list functions read outputType, modelId, and title from each entry. buildModelMap() in the provider reads the same manifest to know which fields each model accepts for the generic textToImage / imageToVideo etc. methods.

Key point: the manifest drives both the node UI (fields, defaults, enum values) and the model picker (image/video model lists). Editing the manifest is sufficient for both.

Wire protocol

  • Submit: POST https://api.atlascloud.ai/api/v1/model/generateImage or .../generateVideo
  • Body: flat JSON — { model: "<modelId>", ...fields } (not nested under input)
  • Poll: GET https://api.atlascloud.ai/api/v1/model/prediction/<id>
  • Terminal statuses: completed, succeeded, success, done, complete, canceled, failed, error
  • Submit is never retried — a 5xx may have already created and billed the job upstream.

Add a new model/node

Step 1: Identify the model

From the AtlasCloud docs or API, collect:

  • The model id string, e.g. "bytedance/seedance-3.0/text-to-video"
  • The modality: "image" or "video"
  • The field names and types the endpoint accepts

Step 2: Choose a className and moduleName

  • className: PascalCase identifier used as the TypeScript class name and the last segment of the node type. Example: "Seedance3TextToVideo".
  • moduleName: one of "image" or "video" (matches the output type). Used in the node type: atlascloud.video.Seedance3TextToVideo.

Step 3: Append an entry to the manifest

Open packages/atlascloud-nodes/src/atlascloud-manifest.json. Append an object following this shape (copy the closest existing entry and adjust):

{
  "className": "Seedance3TextToVideo",
  "moduleName": "video",
  "modality": "video",
  "modelId": "bytedance/seedance-3.0/text-to-video",
  "outputType": "video",
  "title": "Seedance 3.0 — Text to Video",
  "description": "AtlasCloud / ByteDance Seedance 3.0 — text-to-video with native audio.",
  "pollInterval": 5000,
  "maxAttempts": 600,
  "fields": [
    {
      "name": "prompt",
      "type": "str",
      "default": "",
      "title": "Prompt",
      "description": "Text prompt describing the desired video.",
      "required": true
    },
    {
      "name": "duration",
      "type": "int",
      "default": 5,
      "title": "Duration (seconds)",
      "values": [-1, 4, 5, 6, 7, 8, 9, 10]
    },
    {
      "name": "resolution",
      "type": "enum",
      "default": "720p",
      "title": "Resolution",
      "values": ["480p", "720p", "1080p"]
    },
    {
      "name": "ratio",
      "type": "enum",
      "default": "16:9",
      "title": "Aspect Ratio",
      "values": ["16:9", "9:16", "1:1", "adaptive"]
    }
  ]
}

Field type reference:

type Description
"str" Text input
"int" Integer (coerced from string dropdowns)
"float" Float
"bool" Checkbox
"enum" Dropdown; requires "values" array
"image" Single image ref
"video" Single video ref
"audio" Single audio ref
"list[image]" Multiple image refs
"list[video]" Multiple video refs
"list[audio]" Multiple audio refs

Use "list[image]" (not image with "array": true) for multi-image inputs. Use "null" as the default for optional enum fields without a sensible preselected value (e.g. aspect_ratio on Nano Banana models).

pollInterval: milliseconds between poll requests. Use 3000 for image models, 5000 for video models.

maxAttempts: maximum polls before timing out. 300 is reasonable for image; 600 for long-form video.

Step 4: Build

npm run build:packages

This compiles TypeScript and copies the manifest into dist/. The factory picks it up at module load time — no TypeScript changes needed.

Step 5: Smoke-test the node

ATLASCLOUD_API_KEY=<your_key> \
  npm run dev:nodetool -- node run \
  atlascloud.video.Seedance3TextToVideo \
  --props '{"prompt":"a red balloon floating upward","duration":5,"resolution":"720p","ratio":"16:9"}'

For a hermetic check (no secrets, no API call — verifies the node can be instantiated):

npm run dev:nodetool -- node run atlascloud.video.Seedance3TextToVideo \
  --props '{"prompt":"test"}' --no-secrets 2>&1 | grep -E "error|ATLASCLOUD"

Expected: ATLASCLOUD_API_KEY is not configured (meaning the node loaded and reached the key check).

Step 6: Validate (no API call)

npm run dev:nodetool -- validate workflow.json

If you have a workflow JSON referencing the new node, this verifies the node type is registered and all edges type-check.


Verify

Run these in order after any manifest change:

# 1. Rebuild (copies manifest to dist)
npm run build:packages

# 2. Type check the whole repo
npm run typecheck

# 3. Test atlascloud-nodes
npm run test --workspace=packages/atlascloud-nodes

# 4. Test runtime providers (checks manifest-models and the provider)
npm run test --workspace=packages/runtime

# 5. Full check (runs all three root-level checks)
npm run check

None of these make live API calls. Tests use vitest with mocked HTTP.


How past PRs did it

The atlascloud-nodes package and atlascloud-provider.ts were introduced together in commit d1491abf (“add claude agent package”), which also added the entire file set:

packages/atlascloud-nodes/src/atlascloud-manifest.json   +1248 lines
packages/atlascloud-nodes/src/atlascloud-factory.ts       +637 lines
packages/atlascloud-nodes/src/atlascloud-base.ts          +220 lines
packages/atlascloud-nodes/src/index.ts                    +47 lines
packages/atlascloud-nodes/tests/...                       +1120 lines
packages/runtime/src/providers/atlascloud-provider.ts     +492 lines

The initial manifest shipped with 12 entries covering Seedance 2.0, Seedance 2.0 Fast, GPT Image 2, Nano Banana 2, and Nano Banana Pro. Each subsequent model addition follows the same pattern: one new JSON object in atlascloud-manifest.json, then npm run build:packages.


Contributing

Source: https://github.com/nodetool-ai/nodetool
Discord: https://discord.gg/WmQTWZRcYE

Before opening a PR, run npm run check (typecheck + lint + tests). The PR description should include the AtlasCloud model id, the node type string, and a brief note on which fields were included and why any fields from the API docs were omitted.