New:Introducing Socket Scanning for VS Code Marketplace Extensions.Learn more →
Get Started

char-ai-sdk

Package Overview
Dependencies
Maintainers
1
Versions
2
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install
Package was removed
Sorry, it seems this package was removed from the registry
Malware was recently detected in this package.

Affected versions:

1.0.0

char-ai-sdk

Char AI SDK: default personas, durable character memory, and Bedrock/OpenAI adapters in one package.

latest
Source
npmnpm
Version
1.0.0
Version published
Weekly downloads
0
Maintainers
1
Weekly downloads
 
Created
Source

✦ Char AI SDK

Default personas, durable character memory, and provider adapters in a single package

Pick a persona, wire a model, and ship a character that remembers. The package combines the Tavern Labs persona catalog with a provider-neutral memory and response runtime.

Version 1.0.0 Node.js 20 or newer TypeScript strict MIT license

Amazon Bedrock OpenAI Responses API Eight persona cards SQLite supported SillyTavern compatible

Quick start · Personas · Choose your stack · Documentation · API reference · Contributing

[!NOTE] char-ai-sdk is published to npm as char-ai-sdk. One install includes the memory runtime, the persona catalog, and the provider adapters.

What is this?

char-ai-sdk is a TypeScript SDK for applications where an AI character should remain recognizably itself and remember what matters across conversations. It separates five concerns that are often tangled together:

LayerResponsibilityReplaceable?
PersonasReady-made cards: prompts, traits, greetings, and memory seeds✓
MemoryExtraction, provenance, consolidation, visibility, recall, and lifecycle✓
ModelCharacter response generation✓
PersistenceMemory records and persona state✓
InterfaceChat, voice, game, HTTP service, or SillyTavern✓

The persona catalog and runtime share one versioned package, so applications can adopt a bundled character without coupling its identity or memory to one provider.

Why use it?

  • One package: the runtime, provider adapters, and eight bundled personas together.
  • Provider-neutral: mix OpenAI extraction with Bedrock generation, or supply your own adapters.
  • Portable characters: persona cards do not depend on an OpenAI or AWS request shape.
  • Evidence-backed memory: every record retains the message IDs that support it.
  • Lifecycle-aware: duplicates merge, mutable state can be superseded, and contradictions are reported instead of silently overwritten.
  • Privacy-conscious: memories support character-only and user-only visibility.
  • Migration-friendly: import SillyTavern Character Card V1/V2/V3 files and JSONL chat histories.

How it fits together

flowchart LR
    Cards[Persona cards · atlas · sage · …] --> Manifest[Persona manifest]
    UI[Chat · Voice · Game · SillyTavern] --> Runtime[Persona Runtime]
    Runtime --> Compiler[Persona Compiler]
    Runtime --> Recall[Memory Recall]
    Runtime --> Model[Character Model]
    Model --> OA[OpenAI]
    Model --> BR[Amazon Bedrock]
    Recall --> Store[(Memory Store)]
    Runtime --> Ingest[Memory Extraction]
    Ingest --> Store
    Store --> MEM[In-memory]
    Store --> JSON[Atomic JSON]
    Store --> SQL[SQLite]

The persona runtime recalls relevant memories, compiles character instructions, asks a model for the next response, ingests the completed turn, evolves relationship state, and returns both text and voice delivery metadata.

Quick start

Requirements

  • Node.js 20 or newer
  • An OpenAI API key or AWS credentials with Bedrock model access
  • better-sqlite3 when using the SQLite adapter

Install

npm install char-ai-sdk

From a source checkout:

npm install
npm run build

1. Pick a persona

import { getPersona, listPersonas, DEFAULT_PERSONAS } from "char-ai-sdk";

// the two personas used in Tavern Labs demos
const atlas = getPersona("atlas");
const sage = getPersona("sage");
console.log("defaults:", DEFAULT_PERSONAS.join(", "));

// or see everything in the SDK
for (const p of listPersonas()) {
  console.log(p.id, "-", p.tagline);
}

2. Create a memory runtime

import { createCharacterMemoryRuntime } from "char-ai-sdk";
import { createBedrockExtractor, createBedrockTitanEmbeddings } from "char-ai-sdk/bedrock";
import { JsonFileMemoryStore } from "char-ai-sdk/stores/json-file";

const region = process.env.AWS_REGION ?? "us-east-1";
const modelId = process.env.BEDROCK_MODEL_ID;
if (!modelId) throw new Error("BEDROCK_MODEL_ID is required");

const card = getPersona("atlas");
const memory = createCharacterMemoryRuntime({
  extractor: createBedrockExtractor({
    region,
    modelId,
  }),
  embeddings: createBedrockTitanEmbeddings({ region }),
  store: new JsonFileMemoryStore({ path: "./data/atlas-memory.json" }),
});

3. Generate a character response

import { createBedrockCharacterModel } from "char-ai-sdk/bedrock";
import { createPersonaRuntime } from "char-ai-sdk/persona";

const runtime = createPersonaRuntime({
  persona: toManifest(card), // map the card onto a persona manifest - see below
  memory,
  model: createBedrockCharacterModel({
    region,
    modelId,
  }),
});

const response = await runtime.respond({
  conversationId: "demo",
  message: "Give me a read on charging for support personas.",
});

console.log(response.text);
console.log(response.delivery); // emotion, pace, expressiveness, style, pauseAfterMs
console.log(response.trace); // provider, model, timings, recalled memory IDs

That single call performs recall, prompt compilation, generation, turn ingestion, and relationship state progression.

A card maps onto the persona manifest with its prompt, traits, and greeting:

function toManifest(card) {
  return {
    id: card.id,
    version: card.version,
    name: card.name,
    description: `${card.tagline}. ${card.description}`,
    identity: {
      role: card.name,
      backstory: card.description,
      worldview: card.systemPrompt,
      traits: Object.entries(card.traits).map(([k, v]) => `${k}: ${v}`),
      goals: [],
    },
    speech: {
      tone: [card.traits.tone],
      vocabulary: "neutral",
      verbosity: 0.5,
      humor: 0.3,
      signaturePhrases: [],
      forbiddenPhrases: [],
    },
    behavior: {
      warmth: 0.6,
      assertiveness: 0.5,
      curiosity: 0.6,
      emotionalRange: 0.5,
      stayInCharacter: true,
    },
    boundaries: { discloseAi: true, rules: [], prohibitedTopics: [] },
    relationships: {
      stages: ["stranger", "acquaintance", "trusted"],
      defaultStage: "stranger",
      progression: "gradual",
    },
    voice: {
      voiceId: null,
      style: card.traits.tone,
      pace: 1,
      expressiveness: 0.5,
    },
    examples: [{ user: "Hello", assistant: card.greeting }],
    metadata: { suggestedModel: card.suggestedModel },
  };
}

Submit a card's memorySeeds through the normal extraction and validation pipeline:

for (const [index, seed] of card.memorySeeds.entries()) {
  await memory.ingest({
    characterId: card.id,
    conversationId: "seed",
    messages: [{ id: `seed-${index}`, role: "system", content: seed.content }],
  });
}

Seeds are suggestions, not privileged records. The configured extractor may normalize, merge, or reject them according to confidence and provenance rules.

Personas

idnamerole
atlasAtlasstrategic analyst, executive briefings
sageSagecustomer support agent
veraVerasales development rep
scoutScoutresearch assistant, citation-first
wrenWrenonboarding guide for new hires
emberEmberbrand copywriter
lumenLumentechnical explainer
micaMicaoperations dispatcher, incident triage

DEFAULT_PERSONAS is ["atlas", "sage"]—the pair used in Tavern Labs demos. getPersona(id) returns Atlas when an unknown ID is supplied; call personaIds() first when unknown IDs should be treated as errors.

Card format

{
  "id": "atlas",
  "name": "Atlas",
  "tagline": "one line",
  "description": "two or three sentences",
  "traits": {
    "tone": "analytical",
    "formality": "professional",
    "verbosity": "concise"
  },
  "systemPrompt": "the prompt that defines behavior",
  "greeting": "first line the persona says",
  "memorySeeds": [{ "content": "a starting memory", "importance": 0.9 }],
  "suggestedModel": "provider.model-id",
  "version": "1.0.0",
  "author": "Tavern Labs"
}

Traits are advisory: pass them alongside the system prompt so a host application can adapt tone without rewriting the prompt. Treat returned cards as immutable shared catalog data. A card's suggestedModel is a recommendation, not a guarantee that the model is enabled in your provider account or region.

Choose your stack

OpenAI

import {
  createOpenAICharacterModel,
  createOpenAIEmbeddings,
  createOpenAIExtractor,
} from "char-ai-sdk/openai";

The adapters use the Responses API for extraction and character generation and the Embeddings API for vectors. Specify model IDs explicitly so a package upgrade never changes model behavior.

Amazon Bedrock

import {
  createBedrockCharacterModel,
  createBedrockExtractor,
  createBedrockTitanEmbeddings,
} from "char-ai-sdk/bedrock";

const region = process.env.AWS_REGION ?? "us-east-1";
const modelId = process.env.BEDROCK_MODEL_ID;
if (!modelId) throw new Error("BEDROCK_MODEL_ID is required");

const adapters = {
  extractor: createBedrockExtractor({ region, modelId }),
  embeddings: createBedrockTitanEmbeddings({ region }),
  model: createBedrockCharacterModel({ region, modelId }),
};

Bedrock uses the standard AWS SDK credential chain. The execution identity needs permission to invoke the configured models.

Mix providers

Extraction, embeddings, and generation are independent ports. An application can use Bedrock for generation and OpenAI embeddings, or replace embeddings with an entirely local adapter.

Storage

AdapterImportBest forDurability
In-memoryRoot packageUnit tests and ephemeral sessionsProcess lifetime
Atomic JSONchar-ai-sdk/stores/json-filePrototypes and local toolsFile-backed
SQLitechar-ai-sdk/stores/sqliteDesktop, single-node, and small servicesTransactional

SQLite is an optional native dependency:

npm install better-sqlite3

For horizontally scaled deployments, implement the documented MemoryStore contract using a tenant-partitioned database such as PostgreSQL or DynamoDB.

What's inside

ImportProvides
char-ai-sdkCore memory runtime, persona loader, and all bundled persona cards
char-ai-sdk/personasPersona catalog utilities without the core runtime exports
char-ai-sdk/personas/*Direct JSON access to one bundled card
char-ai-sdk/bedrockBedrock Converse extraction, Titan V2 embeddings, character models
char-ai-sdk/openaiOpenAI extraction, embeddings, and character models
char-ai-sdk/personaPersona response runtime with relationship state
char-ai-sdk/serviceFramework-neutral web handlers and the Node adapter
char-ai-sdk/sillytavernCharacter Card and JSONL chat import
char-ai-sdk/evaluationRetrieval and persona evaluation helpers
char-ai-sdk/stores/*Atomic JSON and SQLite persistence

Documentation

GuideUse it when…
Getting startedYou want a complete first integration with environment setup
ConceptsYou need to understand memory scopes, lifecycle, and branches
API referenceYou need imports, parameters, returns, and failure behavior
SillyTavernYou are importing cards/chats or installing the extension
DeploymentYou are running the HTTP service or Studio
Security and privacyYou are handling real users, secrets, tenancy, or erasure
ArchitectureYou are extending providers, stores, or runtime boundaries
ContributingYou are proposing or implementing a change
ChangelogYou need version history and notable changes

Development

npm install
npm run check
npm pack --dry-run

npm run check verifies formatting, TypeScript, deterministic tests, and the distributable build. Live provider tests are opt-in because they consume paid API quota:

RUN_LIVE_PROVIDER_TESTS=1 npm test

Set the appropriate provider credentials and model variables first. See .env.example for the full list.

Project status

Version 1.0.0 includes the memory runtime, both provider adapters, the SQLite store, the persona layer with relationship state, SillyTavern compatibility, the service adapter, and eight default persona cards.

Contributing, citation, and license

Contributions are welcome. Read CONTRIBUTING.md before proposing a change.

When referencing the software, cite the package name, semantic version, and exact Git commit so the result can be reproduced:

char-ai-sdk, version 1.0.0, commit <git-commit>, MIT License.

Released under the MIT License. See CHANGELOG.md for version history.

Built for characters that should remember who they are—and who you are to them.

Keywords

ai

FAQs

Package last updated on 31 Oct 2026

Related posts