@imgly/codesign-sdk
v1.83.0
Published
A design agent's tools for your own agent runner: CE.SDK design editing, preview and export over designs your product stores, on IMG.LY's executor.
Readme
@imgly/codesign-sdk
Give an AI agent the tools to design with CE.SDK, IMG.LY's design engine, on designs your product owns.
prepareCoDesign hands your agent loop every tool the model needs (skill
for the handbook, edit, preview, and more when you ask for them) and a few
sentences for your system prompt. It opens nothing and holds nothing: every
tool call reads its design from your store, runs on an executor, and
writes the design back after every successful change, so a call can arrive on
any process, twice, or next to another. You bring your designs, your asset
sources, your model and agent loop, your prompt and your own tools; everything
else comes from the SDK.
The words this page uses:
- CE.SDK: IMG.LY's design engine, and the browser editor built on it.
- Design, or scene: one CE.SDK document (pages, text, images), saved
as a string, or as an
.imglyarchive that carries its images. - Executor: where CE.SDK runs and the model's code runs against it:
IMG.LY's Docker image (
imgly/codesign-executor), which you run unchanged on your infrastructure. It charges every exported file to your IMG.LY account. - Conversation: your id for one chat, job or request. All its designs open in one executor, which serves no other conversation, because a user's file can steer the model and the model's code runs there.
- Handbook: the instructions the model reads through the
skilltool, shipped inside this package. - Asset source: CE.SDK's name for a searchable list of things a design can
use (photos, brand typefaces, colours, templates). You describe yours once,
as a CE.SDK plugin: a JavaScript module with no imports whose default
export is
(options) => EnginePlugin(CE.SDK's own plugin type). The executor applies it for each design, and your editor applies the same file, so the agent finds, places and stores into what the person's editor shows.
To get a CoDesign licence and the integration guides, contact IMG.LY: https://img.ly/codesign.
npm install --save-exact @imgly/[email protected]--save-exact because the package must match the executor you run (see
Requirements).
On your server, with the executor image
import {
googleFonts,
prepareCoDesign,
remoteExecutors
} from '@imgly/codesign-sdk';
const codesign = prepareCoDesign({
// yours: the chat, job or request this work is for, with your tenant in front
conversation: `${tenantId}.${chatId}`,
executors: remoteExecutors({
// yours: the URL of this conversation's executor, the same one while it
// lives, and one no other conversation used for a new one
acquire: ({ conversation }) => executorFor(conversation),
token: process.env.EXECUTOR_TOKEN // the value your executors were started with
}),
// The CE.SDK plugins every engine applies, in order; the sources they register
// are everything the agent can find, place or store into. `[googleFonts()]`
// is the smallest list. Yours is your editor's plugin file, as text, with this
// person's options.
plugins: [
{ module: acmeSourcesText, options: { api, token: personToken } },
googleFonts()
],
designs, // yours, optional: a DesignStore over your design table (below); without it, designs live in memory
design: designId, // yours, optional: the design the tools start on
uploadExport, // yours, optional: stores a file the model exported; adds `export`
tools: [brandTool], // yours, optional
// required: your IMG.LY AI gateway credential adds `asset_generate`; false leaves it out
gateway: { bearer: async () => process.env.IMGLY_GATEWAY_API_KEY }
});
// optional: start from a file, as bytes or a URL (.imgly, .scene, PNG/JPEG/WebP/GIF/SVG,
// PDF, IDML, PPTX, PSD); tell the model its version so its first edit is not refused
const loaded = file ? await codesign.load(file) : undefined;
await runYourAgent({
system: `${yourProductPrompt}\n\n${codesign.instructions}`,
tools: codesign.tools, // { name, description, inputSchema, call }: any tool-calling framework
prompt: loaded
? `${brief}\n\nThe design is at version ${loaded.version}.`
: brief
});
await codesign.release(); // optional: frees the engine now instead of at its idle timeoutEvery name the snippet does not import is yours: runYourAgent is your agent
loop, executorFor hands out your containers, designs, uploadExport and
brandTool are your storage and tools.
Your designs
designs is a DesignStore: two functions over your own table, called only
by the SDK in your runner, never by the model's code.
import type { DesignStore } from '@imgly/codesign-sdk';
const designs: DesignStore = {
// the design, its version (yours: any string that changes on every write) and
// the CE.SDK that saved it (null if you do not know); undefined if there is none
async read(id) {
const row = await db.designs.get(id); // yours
return (
row && {
content: { scene: row.scene }, // or { archive: bytes } for an .imgly
version: String(row.revision),
cesdkVersion: row.cesdkVersion ?? null
}
);
},
// store the content only if the design is still at `ifMatch` (absent: only if
// nothing is stored under `id` yet); return the new version, or undefined when
// someone saved meanwhile: nothing is written, and the model is told the
// design changed
async write(id, content, { ifMatch, cesdkVersion, title }) {
return db.designs.compareAndSet(id, ifMatch, {
...content,
cesdkVersion,
title
}); // yours
}
};testDesignStore(designs) from @imgly/codesign-sdk/testing checks a store
against these rules, without an executor or a licence; it rejects with an
AggregateError that lists every problem. The version a tool result names is
your store's own, so codesign.edit(code, { version: row.revision }) works
from what you stored.
Outside the code: one container of imgly/codesign-executor:1.83.0 per
conversation, started with your CoDesign licence key (IMGLY_CESDK_LICENSE)
and EXECUTOR_TOKEN. The licence key stays in the executor, never in your
runner, and the executor charges every file export to your IMG.LY account, so
billing needs no code of yours.
Entry points
| Entry | What it is for |
| --------------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| @imgly/codesign-sdk | The tools: prepareCoDesign, remoteExecutors, googleFonts, assertCanSave, CESDK_VERSION, the errors and the CE.SDK types they use. |
| @imgly/codesign-sdk/testing | fakeExecutors(), testAssetSource and testDesignStore: test your sources, your design store and your agent loop without an executor or a licence. |
| @imgly/codesign-sdk/cesdk-utils | Helpers for your own CE.SDK editor on the same plugins: addPluginModules(cesdk.engine, plugins) applies them and resolves your sources' own uris; loadDesign refuses an editor on another CE.SDK than the executor's, or a design a newer CE.SDK saved, saveDesign returns the content with its cesdkVersion (an archive stays an archive), and unloadDesign frees it. Your save route still checks the version (If-Match) and the saving CE.SDK (assertCanSave). |
The tool list and instructions depend on your options alone, never on the
executor. Every design tool takes the design it works on, and edit takes
the version the last result gave; an edit on any other version is refused
and told the current one, so a person's save in your editor, a parallel call
or a retry never builds on a design the model did not see. uploadExport adds
export; gateway: { bearer } adds asset_generate (images, video clips,
speech, music and sound effects from IMG.LY's AI gateway, a paid service).
asset_search, import and designs are always there, and refuse in words
the model understands when your sources or store cannot answer them.
Versions
Each version runs exactly one CE.SDK version, never a range.
1.83.0 is built for, and its executor runs, CE.SDK 1.83.0.
CESDK_VERSION exports the same value.
Requirements
- Node.js 22 or newer for a runner on a server, tested on 22 and 24. ESM
only: CommonJS code loads it with
import()../cesdk-utilsis tested in desktop Chrome; other browsers are untested. - The executor of the same version as this package: the image
imgly/codesign-executor:1.83.0. The runner and the executor share the design API the model's code calls, so a pair from different builds can fail mid-design with an error that names neither. Install an exact version, never a range. LogSDK_VERSIONwhen your runner starts: it is the package version plus a hash of the source it was built from. - A CoDesign licence from IMG.LY. Every file export (PDF, PNG and so on)
is charged to your IMG.LY account. Previews, edits, saving the design and
.imglyfiles are free. - CE.SDK 1.83.0, exactly, in every program that saves your designs: your
editor and any job that saves designs. An older CE.SDK silently drops what a
newer one wrote, and a newer one writes what the executor then drops. The SDK
refuses such a save itself (
older_saver) for the designs it writes; your editor's save route applies the same rule withassertCanSave.
The package declares no dependencies. Your runner needs no CE.SDK: the package
exports checked copies of the CE.SDK types it uses (Asset, Typeface, …).
No entry runs an engine; ./cesdk-utils works on your editor's, at exactly
CESDK_VERSION (the optional peer @cesdk/engine).
Not supported yet: exporting video or audio files (MP4, WAV, M4A); the
executor encodes no video yet and says so when a session opens.
asset_generate can still put generated clips into a design.
Read next
IMG.LY gives you the integration guides with your licence: an overview of what runs where, a quickstart, guides for a design chat and for a design API, hosting the executor image, your editor, versions and upgrades, and the API reference.
