npm package discovery and stats viewer.

Discover Tips

  • General search

    [free text search, go nuts!]

  • Package details

    pkg:[package-name]

  • User packages

    @[username]

Sponsor

Optimize Toolset

I’ve always been into building performant and accessible sites, but lately I’ve been taking it extremely seriously. So much so that I’ve been building a tool to help me optimize and monitor the sites that I build to make sure that I’m making an attempt to offer the best experience to those who visit them. If you’re into performant, accessible and SEO friendly sites, you might like it too! You can check it out at Optimize Toolset.

About

Hi, 👋, I’m Ryan Hefner  and I built this site for me, and you! The goal of this site was to provide an easy way for me to check the stats on my npm packages, both for prioritizing issues and updates, and to give me a little kick in the pants to keep up on stuff.

As I was building it, I realized that I was actually using the tool to build the tool, and figured I might as well put this out there and hopefully others will find it to be a fast and useful way to search and browse npm packages as I have.

If you’re interested in other things I’m working on, follow me on Twitter or check out the open source projects I’ve been publishing on GitHub.

I am also working on a Twitter bot for this site to tweet the most popular, newest, random packages from npm. Please follow that account now and it will start sending out packages soon–ish.

Open Software & Tools

This site wouldn’t be possible without the immense generosity and tireless efforts from the people who make contributions to the world and share their work via open source initiatives. Thank you 🙏

© 2026 – Pkg Stats / Ryan Hefner

@creative-tim/agents

v0.3.0

Published

Official Creative Tim Agents SDK — programmatically create and control OpenClaw AI agents and other agent models

Downloads

322

Readme

@creative-tim/agents

Official SDK for Creative Tim — two namespaces:

  • client.agents — spawn long-running AI agents you talk to via chat (your own Anthropic key, your own runtime)
  • client.apps — generate complete React + Vite web apps from a prompt (shared App Builder runtime, billed in credits)
import { CreativeTimAgent } from '@creative-tim/agents'

const client = new CreativeTimAgent({ apiKey: 'sk-ct-...' })

// Spawn an AI agent
const agent = await client.agents.create({
  name: 'My Agent',
  anthropicApiKey: process.env.ANTHROPIC_API_KEY!,
})
const { text } = await agent.chat('Hello!')

// Generate a real React + Vite app from a prompt
const project = await client.apps.create({
  prompt: 'SaaS landing page for a tax-prep tool',
  type: 'website',
  theme: 'verdant',
})
await project.waitForReady()
console.log(project.previewUrl)

What's new in 0.3.0: added client.apps — programmatic access to the same App Builder that powers creative-tim.com/ui/build. Generate websites, slide decks, dashboards, and marketing-ads grids from a single prompt. See App Builder section below.

Installation

npm install @creative-tim/agents
# or
pnpm add @creative-tim/agents
# or
bun add @creative-tim/agents

Getting an API Key

  1. Go to creative-tim.com/ui/dashboard/api-keys
  2. Scroll to Creative Tim Agent API Keys
  3. Click Create API key — copy your sk-ct-... key (shown once)

Usage

Initialize

import { CreativeTimAgent } from '@creative-tim/agents'

const client = new CreativeTimAgent({
  apiKey: process.env.CREATIVE_TIM_API_KEY!, // sk-ct-...
})

Create an agent

agents.create() provisions a new persistent agent. Call it once per user or use-case, store the returned agent.id, and reconnect to the same agent on every subsequent request using agents.get().

const agent = await client.agents.create({
  name: 'Research Bot',
  anthropicApiKey: process.env.ANTHROPIC_API_KEY!,
  model: 'claude-sonnet-4-6', // optional, default: claude-sonnet-4-6
})

// Persist the ID — you will need it to reconnect later
await db.save({ agentId: agent.id })

Cold start: A new agent takes ~60–80 seconds to provision. If a pre-warmed instance is available it takes ~15–20 seconds instead. Poll agent.status() until status === 'active' before chatting.

Agent lifecycle

Every agent moves through these states:

| status | lifecycleState | Meaning | |----------|-----------------|---------| | provisioning | initializing | Agent record created, machine starting | | provisioning | container_starting | Machine is up, services initialising (~60–80s) | | active | active | Ready to chat | | error | error_recoverable | Transient error — call agent.restart() to recover |

Poll agent.status() after create() until status === 'active':

let agentStatus
do {
  await new Promise(r => setTimeout(r, 5000))
  agentStatus = await agent.status()
} while (agentStatus.status === 'provisioning')

if (agentStatus.status === 'error') {
  // Recover by restarting — no data is lost
  await agent.restart()
}
// agent is now active — safe to chat

Reconnect to an existing agent

agents.get() returns a handle to an already-running agent without any API call. Use this on every page load instead of calling create() again.

// Retrieve the stored ID from your database
const agentId = await db.get(userId).agentId

// Instant — no provisioning, no cold start
const agent = client.agents.get(agentId)
const { text } = await agent.chat('Hello!')

| Scenario | Time | |----------|------| | create() with pre-warmed instance | ~15–20 s | | create() cold (no pre-warm available) | ~60–80 s | | get(id).chat() on a running agent | ~1–2 s (LLM only) |

Chat

The first chat() call after a cold start transparently retries until the agent is fully warmed up — you don't need to add any retry logic yourself.

const { text, sessionKey } = await agent.chat('Summarise this paper: ...')

// Continue the same conversation thread
const followUp = await agent.chat('Can you expand on point 3?', { sessionId: sessionKey })

Stream responses

for await (const chunk of agent.stream('Write me a poem about the ocean')) {
  process.stdout.write(chunk)
}

List agents

const agents = await client.agents.list()
// [{ id, name, status, lifecycleState, createdAt, ... }]

Restart an agent

Restarts the agent process without touching any data — skills, conversation history, and configuration are all preserved. Use this to recover from an error state or after a transient failure.

await agent.restart()
// Agent moves back to provisioning → active automatically
// The next chat() call will wait for the agent to be ready

Restart only restarts the running process. It does not affect stored skills, conversation history, or any other agent data.

Skills

Skills extend an agent with custom capabilities defined in markdown.

// Install a skill
await agent.skills.install('web-search', `
# Web Search Skill
You can search the web using the provided search API.
When asked to find something online, call this skill.
`)

// List installed skills
const skills = await agent.skills.list()

// Remove a skill
await agent.skills.remove('web-search')

Delete an agent

await agent.delete()

App Builder (client.apps)

The App Builder generates real React + Vite apps from a prompt and gives you back a preview URL you can iframe, share, or deploy. Same builder that powers creative-tim.com/ui/build — but called programmatically from your code.

Four app types supported: website, slides, dashboard, ads.

Create a project

const project = await client.apps.create({
  prompt: 'SaaS landing page for a tax-prep tool — minimal modern design',
  type: 'website',          // or 'slides' | 'dashboard' | 'ads'
  theme: 'verdant',            // optional — agent picks one if omitted
  name: 'TaxPrep Landing',     // optional, shown in your project list
  model: 'claude-haiku-4-5',   // optional — also: claude-sonnet-4-6, claude-opus-4-7
})

console.log(project.id)         // session id, e.g. 'eVPeiLtrzJ'
console.log(project.status)     // 'pending' | 'building' | 'ready' | 'failed'

The first generation runs immediately on the server. Use waitForReady() to block until the build finishes:

await project.waitForReady({ timeoutMs: 5 * 60 * 1000 })  // default 5 min
const detail = await project.refresh()
console.log(detail.previewUrl)  // 'https://www.creative-tim.com/ui/preview/<uid>/<sid>/'
console.log(detail.pages)       // [{ id: 'home', name: 'Home' }, ...]

Iterate on the project

Every follow-up message is a turn in the same conversation. The agent has full context of the workspace and previous edits.

await project.messages.create({ content: 'add a Pricing page with three tiers' })
await project.waitForReady()

await project.messages.create({
  content: 'swap the hero to a darker theme',
  model: 'claude-sonnet-4-6',  // optional model override per-message
})
await project.waitForReady()

List, fetch, delete

// List all projects you own (across all your API keys)
const list = await client.apps.list({ limit: 50 })
list.forEach(p => console.log(p.id, p.name, p.deployedUrl))

// Re-attach to an existing project by id
const project = await client.apps.get('eVPeiLtrzJ')
const detail = await project.refresh()

// Permanent delete
await project.delete()

Themes

14 themes available — pick what fits the brand:

| Theme | Vibe | Best for | |---|---|---| | frost | Clean white minimal | General default, tools, utilities | | verdant | Fresh green | SaaS, fintech, health, sustainability | | abyss | Deep indigo/blue | Analytics, monitoring, dark SaaS | | obsidian | Pure black sharp corners | Dev tools, CLIs, technical | | harbor | Deep navy serif | Corporate, legal, finance, consulting | | blush | Pink/rose serif | Beauty, lifestyle, fashion, agencies | | terra | Warm amber | Food, education, friendly consumer | | emerald, midnight, neutral, rose, slate, stark, warm | Extra variations | — |

Pass theme: undefined and the agent picks one based on the prompt.

App types

| Type | What it produces | Agent's job | |---|---|---| | website | Multi-page marketing site composed from a block catalog (hero, features, pricing, testimonials, footer, etc.) | Picks blocks → writes Home.jsx → customizes block content | | slides | Presentation deck — 5+ slides, each its own page (h-[900px] format) | Edits slide blocks for content + chart data | | dashboard | Single-page admin (sidebar shell + KPI cards + charts + tables) | Edits dashboard-sidebar.tsx content | | ads | Grid of social ads (Instagram / TikTok / FB) — 5 layouts × 4 concepts × 4 sizes | Writes only src/ad-seeds.js (4 concepts) — everything else is pre-baked |

Pricing

Each run is billed in App Builder credits — same wallet as the dashboard. Plans:

  • Basic — 3,900 credits / month
  • Pro — 6,900 credits / month
  • Business — 9,900 credits / month

Typical first-message cost on Haiku 4.5: 6–25 credits per build (≈ $0.06–$0.25). Free-tier API keys can't use the App Builder; upgrade to Basic, Pro, or Business at creative-tim.com/pricing.

API Reference

new CreativeTimAgent(config)

| Option | Type | Required | Description | |--------|------|----------|-------------| | apiKey | string | Yes | Your sk-ct-... API key | | baseUrl | string | No | Override API base URL (defaults to https://www.creative-tim.com/ui) |

client.agents

| Method | Returns | Description | |--------|---------|-------------| | create(options) | Promise<AgentHandle> | Provision a new agent | | list() | Promise<Agent[]> | List all agents for this API key | | get(agentId) | AgentHandle | Get a handle to an existing agent (no API call) |

client.apps

| Method | Returns | Description | |--------|---------|-------------| | create(options) | Promise<App> | Create a new App Builder project; runs the first generation if prompt is provided | | list({ limit? }) | Promise<AppSummary[]> | List your projects, most-recently-updated first | | get(sessionId) | Promise<App> | Re-attach to an existing project by id |

App

| Property / Method | Type | Description | |---|---|---| | id | string | Session id | | previewUrl | string | Public URL of the built app (filled by refresh()) | | status | 'pending' \| 'building' \| 'ready' \| 'failed' \| 'running' \| null | Current lifecycle state | | messages.create({ content, model?, theme? }) | Promise<AppRunStatus> | Send a follow-up message | | refresh() | Promise<AppDetail> | Re-fetch metadata from the server | | getStatus() | Promise<status> | Convenience alias for refresh().then(d => d.status) | | waitForReady({ timeoutMs?, pollMs? }) | Promise<AppDetail> | Poll until status is ready (or throw on failed / timeout) | | delete() | Promise<void> | Permanent delete |

AgentHandle

| Method | Returns | Description | |--------|---------|-------------| | status() | Promise<Agent> | Get current agent status and lifecycle state | | chat(message, options?) | Promise<ChatResponse> | Send a message, get a response | | stream(message, options?) | AsyncGenerator<string> | Stream response tokens | | restart() | Promise<void> | Restart the agent process — no data loss | | skills.list() | Promise<Skill[]> | List installed skills | | skills.install(name, content) | Promise<void> | Install a skill | | skills.remove(name) | Promise<void> | Remove a skill | | delete() | Promise<void> | Permanently delete the agent |

CreateAgentOptions

interface CreateAgentOptions {
  name: string
  anthropicApiKey: string
  model?: string        // default: claude-sonnet-4-6
  systemPrompt?: string // optional system prompt
}

Agent

interface Agent {
  id: string
  name: string
  status: 'provisioning' | 'active' | 'error'
  lifecycleState: string
  model?: string
  createdAt: string
  updatedAt: string
}

ChatResponse

interface ChatResponse {
  text: string       // the agent's reply
  sessionKey: string // pass as sessionId to continue the conversation thread
  raw: unknown       // full response object
}

TypeScript

The package ships with full TypeScript declarations. All types are exported from the root:

import type { Agent, AgentHandle, CreateAgentOptions, ChatResponse, Skill } from '@creative-tim/agents'

License

Apache-2.0 — Creative Tim


OpenClaw is an independent open-source project and is not affiliated with or endorsed by Creative Tim. OpenClaw is licensed under the MIT License. For more information visit openclaw.ai or the OpenClaw GitHub repository.