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

enterprise-ai-sdk

v0.8.0

Published

Enterprise AI SDK — provider-agnostic, capability-based (chat, tools, knowledge, learning, local FAQ cache) untuk Node.js/TypeScript.

Readme

Enterprise AI SDK — TypeScript / Node.js

Reference implementation dari Enterprise AI SDK. Dokumen ini adalah panduan lengkap stack TS/Node: instalasi, konfigurasi, seluruh fitur, catatan operasional produksi, dan status verifikasi.

Referensi API lengkap per-method: docs/public-api.md (disertakan dalam paket; tautan disajikan via CDN unpkg — juga tersedia di node_modules/enterprise-ai-sdk/docs/public-api.md setelah install).

Catatan: npmjs.com tidak mendukung tautan relatif ke berkas paket (jadi tautan mengarah ke unpkg). Tautan aktif setelah versi yang menyertakan docs/public-api.md (≥ 0.1.1) ter-publish.


Daftar Isi

  1. Kebutuhan
  2. Instalasi & optional dependencies
  3. Mulai cepat
  4. Konfigurasi 3 lapis
  5. Provider
  6. Tools + discovery + permission
  7. Identity
  8. Session, Memory, Knowledge, Prompt
  9. Feedback, Learning, Local Provider (FAQ cache)
  10. Storage
  11. Error handling
  12. Catatan operasional produksi
  13. Status verifikasi & checklist produksi
  14. Skrip pengembangan

1. Kebutuhan

  • Node.js ≥ 22 (ESM).
  • Package manager: pnpm (repo memakai workspace pnpm).

2. Instalasi & optional dependencies

SDK inti tidak punya dependency runtime wajib — semua provider SDK, driver DB, dan library retrieval bersifat optionalDependencies. Pasang HANYA yang kamu pakai. Bila fitur dipakai tanpa package-nya terpasang, SDK melempar error jelas yang menyebut package mana harus di-install (bukan crash misterius).

| Fitur | Package yang perlu di-install | |---|---| | Provider DeepSeek / OpenAI (kompatibel) | openai | | Provider Anthropic | @anthropic-ai/sdk | | Provider Google | @google/genai | | Knowledge / Local Provider / rerank (embedding lokal) | @huggingface/transformers | | Storage SQLite (default zero-config) | better-sqlite3 | | Storage PostgreSQL | pg | | Storage MySQL | mysql2 | | Storage MongoDB | mongodb | | Cache Redis (cache.driver:'redis') | ioredis |

Contoh (DeepSeek + SQLite + knowledge):

pnpm add enterprise-ai-sdk openai better-sqlite3 @huggingface/transformers

apiKey via .env (JANGAN di-commit): DEEPSEEK_API_KEY, OPENAI_API_KEY, ANTHROPIC_API_KEY, GOOGLE_API_KEY.

3. Mulai cepat

Facade statis (boot otomatis dari eai.config.json + .env):

import { AI } from 'enterprise-ai-sdk';
const res = await AI.chat('Halo, siapa kamu?');
console.log(res.getFinalMessage());

Instance eksplisit (multi-config / DI / test):

const sdk = await AI.create({
    provider: { defaultProvider: 'deepseek', defaultModel: 'deepseek-v4-pro' },
    providers: { deepseek: { apiKey: process.env.DEEPSEEK_API_KEY } },
});
const res = await sdk.chat('Halo');

4. Konfigurasi 3 lapis

| Lapis | Cara | Scope | |---|---|---| | 1 Global | AI.create / AI.configure / eai.config.json / env | Lifetime | | 2 Session | sdk.setConfig(partial) | Sisa lifetime (provider/tool tetap) | | 3 Per-call | sdk.use('x').model('m').temperature(0.2).session('s').as({userId}).chat(...) | 1 panggilan, auto-reset |

Precedence: Lapis 3 > 2 > programmatic > file > env > default. Contoh file lengkap ada di #4.2; tabel field per-item: docs/api/public-api.md #2.

4.1 Config file & environment

  • File: SDK membaca eai.config.json dari cwd aplikasi (opsional — SDK jalan tanpa file config, cukup AI.create({...})).
  • Override path file: set env EAI_CONFIG_PATH (absolut, atau relatif terhadap cwd) untuk memakai file di lokasi lain.
  • API key: JANGAN taruh di file config. Pakai environment: DEEPSEEK_API_KEY, OPENAI_API_KEY, ANTHROPIC_API_KEY, GOOGLE_API_KEY (pola <PROVIDER-ID>_API_KEY). Nilai env menang atas file untuk apiKey.

Paket npm tidak menyertakan file contoh (hanya dist). Buat sendiri eai.config.json di root project-mu — salin templat di bawah, ubah seperlunya. Semua field opsional; yang tidak diisi memakai default.

4.2 Contoh eai.config.json (LENGKAP — nilai = default)

{
  "namespace": null,
  "provider": { "defaultProvider": "deepseek", "defaultModel": "deepseek-v4-pro", "allowedProviders": [] },
  "providers": { "deepseek": { "model": "deepseek-v4-pro", "baseUrl": null, "temperature": null, "maxTokens": null } },
  "timeout":  { "requestTimeoutMs": 30000, "providerTimeoutMs": 25000 },
  "retry":    { "enabled": false, "maxRetries": 2, "retryDelayMs": 1000 },
  "fallback": { "enabled": false, "fallbackProviders": [] },
  "streaming":{ "enabled": false },
  "logging":  { "enabled": true, "level": "info", "redactionEnabled": true },
  "cost":     { "trackingEnabled": true, "pricing": null },
  "security": { "redactionEnabled": true, "promptDebuggingEnabled": false },
  "storage":  { "enabled": false, "defaultConnection": "sqlite",
                "databases": { "sqlite": { "adapter": "sqlite", "connectionString": null, "prefix": "eai_" } } },
  "session":  { "enabled": false, "maxMessages": 20, "fields": {} },
  "memory":   { "enabled": false, "maxEntries": 100 },
  "knowledge":{ "enabled": false, "maxEntries": 500 },
  "learning": { "enabled": false, "autoRecord": false },
  "cache":    { "enabled": false, "ttlMs": 300000, "maxEntries": 500, "driver": "memory", "redisUrl": null },
  "embedding":{ "model": "Xenova/multilingual-e5-small", "threshold": 0.8, "scanLimit": 500, "candidateLimit": 100 },
  "rerank":   { "model": "Xenova/bge-reranker-base", "threshold": 0.1, "topK": 10 },
  "prompt":   { "systemPrompt": null },
  "tools":    { "autoExec": true, "maxDiscoveryIterations": 1 },
  "localProvider": { "enabled": false, "similarityThreshold": 0.9, "rerankThreshold": 0.3, "scanLimit": 500 }
}

5. Provider

Bawaan (auto-register bila apiKey ter-resolve): deepseek, openai, anthropic, google. Kustom: sdk.registerProvider(id, adapter).

await sdk.use('anthropic').chat('...');            // per-call
const sdk2 = await AI.create({ provider: { defaultProvider: 'openai' }, providers: { openai: { apiKey: '...' } } });

baseUrl per provider: tiap provider punya default endpoint; override via providers.<id>.baseUrl (proxy/gateway/Azure/self-hosted). Berlaku di AI.create maupun setConfig. Detail + tabel default: docs/public-api.md.

await AI.create({ providers: { openai: { apiKey: '...', baseUrl: 'https://openrouter.ai/api/v1' } } });

6. Tools + discovery + permission

sdk.registerTool({
    name: 'getSalary',
    description: 'Ambil gaji karyawan. WAJIB untuk pertanyaan gaji.',
    placeholders: ['salary_info'],
    roles: ['hr'],                                   // izin berbasis role (opsional)
    handler: async () => ({ success: true, data: { salary_info: 'Rp 15.000.000' } }),
});

// autoExec default true → SDK eksekusi tool + isi placeholder otomatis:
const res = await sdk.as({ userId: 'u1', roles: ['hr'] }).chat('Berapa gaji saya?');
console.log(res.getFinalMessage());                  // "{salary_info}" sudah terisi
  • Discovery (meta-tools): schema tool tak dijejalkan ke tiap prompt; SDK menawarkan listTools, menyaring (embed+rerank), lalu menyuntik yang relevan.
  • Permission: roles:[] = publik; non-kosong → identity wajib punya ≥1 role.
  • autoExec=false: aplikasi panggil res.executeTools() lalu (opsional) res.saveToHistory().

⚠️ Reliabilitas discovery — lihat #12.

7. Identity

SDK tidak melakukan authentication — aplikasi menyetel identity tervalidasi.

sdk.setIdentity({ userId: 'u-1', displayName: 'John Doe', roles: ['admin'] }); // default
await sdk.as({ userId: 'u-2', roles: ['hr'] }).chat('...');                     // per-call

Resolusi: per-call as() → default setIdentity → anonymous. roles = basis permission tool.

8. Session, Memory, Knowledge, Prompt

// Session (butuh session.enabled):
await sdk.session('sesi-42').chat('Namaku John Doe');
await sdk.session('sesi-42').chat('Siapa namaku?');   // → "John Doe"

// Memory PER-USER (butuh memory.enabled + identity non-anonim):
sdk.setIdentity({ userId: 'u-1' });
await sdk.remember('User suka jawaban singkat');       // anonim tanpa scope → TIDAK disimpan

// Knowledge (butuh knowledge.enabled; retrieval embed→rerank):
await sdk.addKnowledge({ title: 'Jam kerja', content: 'Kantor buka 09.00-17.00 WIB.' });

// Prompt global (persona/aturan, selalu dibawa):
sdk.setPrompt('Kamu asisten HR. Jawab dalam Bahasa Indonesia.');

9. Feedback, Learning, Local Provider (FAQ cache)

AI menandai jawaban cacheable (stabil). Hanya cacheable:true yang direkam ke learning. Feedback diberikan admin, asinkron:

const items = await sdk.listHistory(20);
await sdk.historyFeedback(items[0].id, 'positive');    // positive|neutral|negative

Local Provider (FAQ cache lokal-first) menjawab dari learning ber-feedback SEBELUM memanggil provider berbayar (hemat biaya):

const sdk = await AI.create({
    storage: { enabled: true }, learning: { enabled: true, autoRecord: true },
    localProvider: { enabled: true },                  // WAJIB storage.enabled
});
const res = await sdk.chat('berapa hari cuti tahunan');
res.usedLocalProvider();                               // true bila dijawab dari cache

Seleksi kandidat: positive dulu (acak bila >1, sengaja — agar terasa manusiawi), neutral fallback, negative/null tak pernah.

⚠️ Batasan Local Provider: untuk FAQ stabil, bukan pemahaman bahasa umum. Cache kosong sampai admin memberi feedback. Threshold tinggi (minim false-positive) → recall lebih rendah. Jawaban terhitung/promo time-limited otomatis cacheable:false. Detail: public-api.md #8.

9b. Vision (analisis gambar)

Analisis gambar oleh model multimodal. Provider: OpenAI (diverifikasi), Anthropic, Google (kode siap; DeepSeek dukungan vision terbatas). Tiga tipe input — SDK menyesuaikan format per provider:

const res = await sdk.vision('Bacakan nominal & nomor referensi.', [
    { type: 'file', path: './bukti-transfer.jpg' },   // dirFile
    // { type: 'url', url: 'https://…/receipt.png' },  // di-fetch SDK
    // { type: 'base64', data: 'iVBOR…', mimeType: 'image/png' },
]);
console.log(res.getFinalMessage());

Output terstandar via fields — samakan nama field lintas format (mis. jumlah/amount → satu nama kanonik). Model mengisi data.payload pakai nama kamu persis; dalam session, payload otomatis tersimpan ke session data (§9c):

const res = await sdk.session('trx-42').vision('Baca bukti transfer.',
    [{ type: 'file', path: './bukti.jpg' }],
    { fields: { pengirim: 'nama pengirim', nominal: 'nominal (angka)', noRef: 'no. referensi' } },
);
res.raw.data.payload;   // → { pengirim:'Budi', nominal:'170000', noRef:'FT…' }

⚠️ Keputusan & risiko ada pada aplikasi — SDK hanya menyiapkan alat:

  • Gambar BUKAN bukti final (bisa dipalsukan). Pakai vision untuk MEMBACA; verifikasi kebenaran ke sistem asli (mis. lookup nomor referensi ke gateway).
  • Vision bisa salah baca (mirip OCR). Minta field terstruktur lalu cocokkan di aplikasi; jangan andalkan interpretasi bebas untuk keputusan penting.

Detail + tabel tipe input: public-api.md #12.

9c. Session Data (fakta terstruktur per-session)

Beda dari history (pesan, dipotong maxMessages), session data = fakta mesin (nama, nominal, hasil vision) yang selalu disuntik penuh ke prompt — tak pernah terpotong selama session hidup. Akumulatif; kunci sessionId.

Isi otomatis dari chat & vision via skema session-global setSessionFields: selama session aktif, tiap request mengekstrak field ke payload → auto-store (dedup, record identik dibuang).

sdk.setSessionFields({ userId: 'user yang dicek', tanggal: 'tanggal (YYYY-MM-DD)' });
// User chatting biasa: "cek transaksi dian tanggal 2026-04-02"
//   → tersimpan { userId:'dian', tanggal:'2026-04-02' }. "cek anto 2026-05-02" → record ke-2.

Di prompt, data tampil dua bentuk — per-field unik (userId: dian, anto) + kombinasi records — sehingga AI bisa merekomendasikan pilihan yang sudah pernah diproses ("mau cek dian 2026-04-02 atau anto 2026-05-02?").

Isi manual (WAJIB .session(id), tanpa itu → session_id_required):

await sdk.session('trx-42').rememberData({ pengirim: 'Budi', bank: 'BCA' });
const facts = await sdk.session('trx-42').sessionData();          // baca semua

Data hanya disuntik ke prompt (bukan dilempar ke tool). Belum ada TTL — bertahan sampai storage di-clear.

Hapus session. sessionId menyatukan history + session data + pending-tool. clearSession(id) menghapus ketiganya sekaligus (idempoten):

await sdk.clearSession('trx-42');   // history + session data + pending-tool → hilang

Detail + tabel perbandingan: public-api.md #7a.

10. Storage

Multi-connection gaya Laravel:

storage: {
    enabled: true,
    defaultConnection: 'main',
    databases: {
        main: { adapter: 'postgres', connectionString: 'postgres://…', prefix: 'eai_' },
    },
}

storage.enabled:false → in-memory ephemeral. Adapter: sqlite (default, fallback ./.eai/llm-storage.sqlite), postgres, mysql, mongodb — install driver terkait (lihat #2).

pgvector (opsional, PostgreSQL). Bila ekstensi vector terpasang, recall cosine knowledge & FAQ cache dihitung di database (<=>) — otomatis, tanpa migration. Aktifkan sekali: CREATE EXTENSION IF NOT EXISTS vector; (SDK juga mencobanya saat init). Tanpa pgvector → tetap jalan (fetch + cosine). Detail: public-api.md #7.

Penamaan: MemoryStorageAdapter = adapter storage in-memory (RAM), BEDA dari subsystem memory (sdk.remember).

10b. Multi-tenant (namespace + berbagi resource)

Pola sah: satu instance SDK per tenant (karena setPrompt/setSessionFields/ baseUrl di level instance), sering berbagi satu database. Tiga penopang:

  • namespace — set sdk.setNamespace('site-42') (atau config namespace): di-fold ke scope-key semua subsistem storage (memory/session/session-data/ knowledge/learning) → tenant berbagi tabel tak saling melihat data. null = perilaku lama.
  • Model retrieval di-share otomatis (berkunci identitas model) → N instance model sama = 1 sesi ONNX di RAM, bukan N × ~400 MB. setConfig ganti model kini berlaku saat runtime.
  • Pool koneksi di-share otomatis (berkunci adapter|connectionString|prefix) → instance koneksi sama = 1 pool (hindari kehabisan max_connections). Refcount; graceful shutdown: import { closeAllStorage } from 'enterprise-ai-sdk'.
  • Cache Redis (cache.driver:'redis' + redisUrl, butuh ioredis) — cache response dibagi lintas server; memory (default) untuk single server. Key dinamespace eai:cache:{namespace}:; fail-open bila Redis mati.
    await AI.create({ cache: { enabled: true, driver: 'redis', redisUrl: 'redis://localhost:6379' } });
  • Embed/rerank remote (TEI) (embedding.driver:'remote' / rerank.driver:'remote'
    • remoteUrl) — model tak dimuat di app server; panggil layanan TEI bersama (multi-server, bisa GPU). Fail-soft (TEI mati → retrieval kosong, chat jalan). Hanya TEI yang didukung — pasang sendiri (dok TEI). Multi-model otomatis (prefix per model + threshold:null=auto). Tanpa dependency npm baru.
    await AI.create({
      embedding: { driver: 'remote', remoteUrl: 'http://tei-embed:8080', model: 'intfloat/multilingual-e5-small' },
      rerank:    { driver: 'remote', remoteUrl: 'http://tei-rerank:8081', model: 'BAAI/bge-reranker-base' },
    });

Cache response, ConfigState, ToolRegistry, provider registry tetap per-instance (sengaja). Detail: public-api.md #13.

11. Error handling

chat() TIDAK melempar untuk kegagalan runtime — selalu envelope. Cek res.status; detail res.raw.error (code, category, retryable, …). Kategori: validation, configuration, provider, timeout, rate_limit, tool, runtime, internal. Yang MELEMPAR: setup invalid (AI.create/ setConfig), registerTool invalid, pemakaian salah executeTools/ saveToHistory/recordToLearning.

12. Catatan operasional produksi

12.1 Cold-start model lokal

Embedding & rerank (@huggingface/transformers) mengunduh + memuat model saat pemakaian PERTAMA (puluhan detik + memori). Request knowledge/ localProvider pertama lambat; berikutnya cepat (model ter-cache di proses).

  • Rekomendasi: panggil await sdk.warmup() (atau AI.warmup()) sekali saat boot aplikasi — preload model embedding+rerank sebelum melayani trafik, sehingga request pertama tidak lambat.
    const sdk = await AI.create({ /* ... */ });
    await sdk.warmup();   // model siap
  • Ini hanya latensi hit-pertama; wajar untuk deployment yang di-test sebelum go-live.

12.2 Reliabilitas tool discovery (meta-tools)

Discovery adalah loop agentic: model harus (a) meminta listTools, lalu (b) memilih tool + params yang benar. Mekaniknya benar & deterministik di dev, TAPI bergantung kepatuhan model saat itu — model yang lambat/kurang patuh bisa gagal memicu tool atau timeout di tengah.

  • Cara aplikasi menangani:
    • Aktifkan retry (retry.enabled: true) untuk request ber-tool.
    • Selalu cek res.hasAction() — jangan asumsikan tool pasti terpilih.
    • Sediakan fallback ketika tool tak terpanggil (mis. minta user memperjelas).
    • Naikkan timeout.providerTimeoutMs untuk alur discovery (2 panggilan).
    • tools.maxDiscoveryIterations (default 1) menjaga dari loop.
  • Alternatif bila butuh determinisme tinggi: model lebih patuh, atau strategi native function-calling (lebih boros token, mengikat ke provider).

12.3 Skala retrieval

Tanpa vector query native, learning/knowledge besar = fetch semua kandidat

  • cosine di Node tiap query (O(n); vektor sudah di-precompute saat tulis, jadi tak ada re-embed). Aman untuk kecil–menengah; ada plafon skala. Native pgvector/Atlas ditunda ke slice terpisah.

13. Status verifikasi & checklist produksi

Terverifikasi terhadap backend nyata:

  • DeepSeek (chat, resiliency, tools, subsystem) ✅
  • Storage SQLite / PostgreSQL / MySQL / MongoDB (CRUD) ✅
  • Retrieval embed/rerank lokal, feedback, Local Provider, identity, permission ✅
  • Adapter Anthropic — terverifikasi sampai batas API (chat penuh butuh kredit API) ✅

Belum diuji real (butuh kredensial): provider OpenAI & Google (execute()).

Checklist sebelum production:

  • [ ] Smoke test provider yang dipakai dengan API key + kredit nyata.
  • [ ] Pasang driver DB yang dipakai (optional dep).
  • [ ] Warmup model lokal saat boot bila pakai knowledge/localProvider.
  • [ ] Aktifkan retry untuk alur ber-tool + tangani hasAction() false.
  • [ ] Tetapkan license, versi rilis, CI (belum disiapkan).

TODO by design: capability stream/reason/embedding/vision/ocr (stub), vector query native, telemetry backend, LocalProviderAdapter sebagai provider 'local'.

14. Skrip pengembangan

pnpm build            # tsc → dist/
pnpm typecheck        # tsc --noEmit (source)
pnpm typecheck:test   # typecheck test
pnpm test             # vitest (real DeepSeek bila DEEPSEEK_API_KEY ada; sisanya di-skip)
pnpm test:coverage    # + coverage
pnpm lint             # eslint

Test REAL terhadap provider/DB nyata aktif otomatis bila env kredensial diisi (mis. DEEPSEEK_API_KEY, POSTGRES_TEST_URL, MYSQL_TEST_URL, MONGODB_TEST_URL).

15. Publikasi (npm publik)

Paket ini di-publish publik ke npm (nama unscoped enterprise-ai-sdk, lisensi MIT, publishConfig.access: "public"). prepublishOnly menjalankan typecheck + lint + build otomatis sebelum publish; hanya dist/ + README.md

  • LICENSE yang masuk tarball.
# 1. Login npm (sekali):
npm login
npm whoami                 # verifikasi ter-autentikasi

# 2. Publish (dari implementations/typescript-node/):
npm publish

# Rilis berikutnya: naikkan versi dulu
npm version patch          # 0.1.0 → 0.1.1 (atau minor/major)
npm publish

ESM-only — consumer harus mendukung ESM ("type": "module" atau import dinamis).


Referensi API lengkap ada di docs/public-api.md (disertakan dalam paket). Dokumen desain (ADR & review per-slice) berada di repositori sumber (privat/internal).