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

@vibe-bot/sdk

v0.1.1

Published

Zero-dependency, OpenAI-compatible TypeScript SDK for VibeBot.

Readme

@vibe-bot/sdk

Tiny, zero-dependency TypeScript SDK for the VibeBot API. Wire-compatible with OpenAI Chat Completions, so anything that speaks OpenAI speaks VibeBot.

  • 0 runtime dependencies — standard web APIs only (fetch, ReadableStream, TextDecoder, AbortSignal)
  • Node 18+, browsers, Cloudflare Workers / Vercel Edge
  • ESM + CJS dual build with .d.ts
  • Streaming via for await, automatic retries, typed errors

Install

npm i @vibe-bot/sdk

One line

import { VibeBot } from '@vibe-bot/sdk';

const vb = new VibeBot({ apiKey: process.env.VIBEBOT_KEY });

console.log(await vb.ask('agt_9f2c', '환불 되나요?'));
// → "네, 배송 후 7일 이내면 됩니다."

Chat completions

const res = await vb.chat.completions.create({
  model: 'agt_9f2c',                                  // the agentId goes in `model`
  messages: [{ role: 'user', content: '환불 되나요?' }],
  temperature: 0.3,
  user: 'sess_abc',                                   // conversation/session id
});

res.choices[0].message.content;
res.vibebot?.sources;      // [{ id, title, url, score }]
res.vibebot?.confidence;   // 0.91
res.vibebot?.escalate;     // false

Streaming

stream: true returns an async iterable of ChatCompletionChunk. The vibebot extension (sources, confidence) rides on the final chunk.

const stream = await vb.chat.completions.create({
  model: 'agt_9f2c',
  messages: [{ role: 'user', content: '환불 되나요?' }],
  stream: true,
});

let sources;
for await (const chunk of stream) {
  process.stdout.write(chunk.choices[0]?.delta?.content ?? '');
  if (chunk.vibebot?.sources) sources = chunk.vibebot.sources;
}

// stop early
stream.abort();

Widget bootstrap

const cfg = await vb.agents.get('agt_9f2c');
// { id, name, greeting, suggestions, theme: { accent, position, radius }, branding }

GET /v1/agents/:id is public — no API key needed. Omit apiKey and the SDK runs in public mode (no Authorization header); the server authorises by Origin.

Management API

Create agents and feed them sources from code — useful for refreshing content in CI, or spinning up one agent per customer.

These calls require an API key. Unlike chat, they are never callable without one: a key exposed in a browser would let anyone delete the agent. Keep them server-side.

const vb = new VibeBot({ apiKey: process.env.VIBEBOT_KEY });

const agent = await vb.agents.create({ name: '문서봇', persona: '짧게 답한다.' });

// A URL crawls same-host links (up to 8 pages) unless you pass `crawl: false`
await vb.agents.sources.create(agent.id, { url: 'https://mysite.com' });
await vb.agents.sources.create(agent.id, { kind: 'text', title: '환불정책', text: '…' });

// What could it not answer?
const log = await vb.agents.conversations(agent.id, { limit: 50 });
log.filter((c) => c.escalated).forEach((c) => console.log(c.question));

| Method | Endpoint | | |---|---|---| | agents.list() | GET /v1/agents | Every agent the key's owner has | | agents.create(body) | POST /v1/agents | Enforces the plan's agent limit | | agents.get(id) | GET /v1/agents/:id | Public bootstrap — no key needed | | agents.update(id, body) | PATCH /v1/agents/:id | | | agents.delete(id) | DELETE /v1/agents/:id | | | agents.sources.list(id) | GET /v1/agents/:id/sources | | | agents.sources.create(id, body) | POST /v1/agents/:id/sources | Enforces the plan's source limit | | agents.sources.delete(id, srcId) | DELETE /v1/agents/:id/sources/:sourceId | | | agents.conversations(id, params) | GET /v1/agents/:id/conversations | |

Adding a URL can create several sources at once, so the result is a union rather than a flat array. That is deliberate: flattening would hide the fact that one call just consumed several of your plan's source slots.

const res = await vb.agents.sources.create(id, { url: 'https://mysite.com' });
// { sources: Source[], count: number }   ← URL
// Source                                 ← text

Someone else's agent always answers 404, never 403 — we don't confirm that an id exists.

Errors

Everything throws VibeBotError, with subclasses per status.

import { VibeBotError, RateLimitError, NotFoundError } from '@vibe-bot/sdk';

try {
  await vb.ask('agt_nope', 'hi');
} catch (err) {
  if (err instanceof NotFoundError) { /* err.status 404, err.code 'agent_not_found' */ }
  if (err instanceof VibeBotError) console.error(err.status, err.code, err.type, err.message);
}

| HTTP | class | code | type | |---|---|---|---| | 400 | BadRequestError | invalid_request_error | invalid_request_error | | 401 | AuthenticationError | invalid_api_key | authentication_error | | 403 | PermissionDeniedError | — | permission_error | | 404 | NotFoundError | agent_not_found | invalid_request_error | | 429 | RateLimitError | rate_limit_exceeded | rate_limit_error | | 5xx | InternalServerError | internal_error | api_error | | — | APIConnectionError / APIConnectionTimeoutError | — | — | | — | APIUserAbortError | — | — |

Server-provided code/type always win; the table is the fallback.

Retries

429, 408, 409 and 5xx are retried with exponential backoff + jitter (2 retries by default). A Retry-After header (seconds or HTTP-date) overrides the computed delay. 4xx (other than those) and user aborts are never retried.

const vb = new VibeBot({ maxRetries: 5 });
await vb.ask('agt_9f2c', 'hi', { maxRetries: 0 });   // per-request override

Abort & timeout

const ac = new AbortController();
setTimeout(() => ac.abort(), 2000);

await vb.chat.completions.create(params, { signal: ac.signal });   // → APIUserAbortError
await vb.chat.completions.create(params, { timeout: 5000 });       // → APIConnectionTimeoutError

Use the official openai package instead

The endpoint is wire-compatible, so this works — and is covered by our test suite:

import OpenAI from 'openai';

const openai = new OpenAI({
  apiKey: process.env.VIBEBOT_KEY,
  baseURL: 'https://vibebot.store/v1',
});

const res = await openai.chat.completions.create({
  model: 'agt_9f2c',
  messages: [{ role: 'user', content: '환불 되나요?' }],
});
// res.vibebot?.sources is passed through untouched

Options

new VibeBot(options)

| Option | Type | Default | Description | |---|---|---|---| | apiKey | string | — | Secret key (vb_sk_…). Omit for public/widget mode. | | baseURL | string | http://localhost:3000/v1 | API root. Trailing slashes are trimmed. | | maxRetries | number | 2 | Retries on 429/408/409/5xx and network errors. | | timeout | number | 60000 | Per-request timeout in ms. 0 disables. | | defaultHeaders | Record<string,string> | {} | Headers added to every request. | | fetch | (url, init) => Promise<Response> | global fetch | Injectable fetch — for tests, proxies, custom runtimes. | | retryDelayMs | number | 500 | Base backoff delay. Doubles each attempt, ±25% jitter. | | maxRetryDelayMs | number | 8000 | Ceiling for a single backoff sleep. |

Request options (2nd argument of create / agents.get / ask)

| Option | Type | Description | |---|---|---| | signal | AbortSignal | Cancels the request (and any active stream). | | timeout | number | Overrides the client timeout for this call. | | maxRetries | number | Overrides the client retry count for this call. | | headers | Record<string,string> | Extra headers, merged over the defaults. |

create params

| Field | Type | Required | Description | |---|---|---|---| | model | string | ✓ | The agentId, e.g. agt_9f2c. | | messages | ChatCompletionMessageParam[] | ✓ | role: system | user | assistant. | | stream | boolean | | true returns Stream<ChatCompletionChunk>. | | temperature | number | | | | user | string | | Conversation/session identifier. |

Exports

VibeBot (also default), Stream, SSEDecoder, LineDecoder, DEFAULT_BASE_URL, all error classes, and the types ChatCompletion, ChatCompletionChunk, ChatCompletionMessageParam, ChatCompletionCreateParams*, AgentConfig, VibeBotSource, VibeBotExtension, ClientOptions, RequestOptions, FetchLike.

Development

npm run build     # dist/esm + dist/cjs + .d.ts
npm test          # node --test (no external runner)

Every test runs against an injected fetch — no server required.