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

@webskill/chatbot

v0.23.0

Published

An embeddable agent-chat workbench for the browser, built on [`@webskill/sdk`](https://www.npmjs.com/package/@webskill/sdk). It renders a full conversational UI — assistant-ui message-part pipeline, streaming markdown, chain-of-thought grouping, human-in-

Readme

@webskill/chatbot

An embeddable agent-chat workbench for the browser, built on @webskill/sdk. It renders a full conversational UI — assistant-ui message-part pipeline, streaming markdown, chain-of-thought grouping, human-in-the-loop interaction cards (missing-parameter forms, confirmations, authorization), generative-UI surfaces, and session management — driven by the SDK's ChatEngine.

@webskill/chatbot is an upper-layer product, not part of @webskill/sdk. It consumes the SDK as a peer dependency, so your application carries exactly one SDK instance shared between the chatbot, the console, and your own code.

0.0.x phase — the public API may change between patch releases. Not recommended for production-critical paths until 0.1.0. See the versioning plan in the repository docs (0.0.1 → 0.0.2 → 0.1.0, strict semver from 0.1.0).

Install

npm install @webskill/chatbot @webskill/sdk react react-dom

Optional peers

| Package | Install it to… | Without it | | --------------------------------------------------------------------- | ----------------------------------------------------- | --------------------------------------------------------------------- | | @a2ui/lit + @a2ui/web_core + @a2ui/markdown-it + @lit/context | enable the A2UI renderer track (BYOC Lit catalog) | A2UI track is greyed out in Settings; surfaces fall back to native | | @openuidev/react-lang + zod | enable the OpenUI renderer track | OpenUI track is greyed out; surfaces/interactions fall back to native |

Missing peers never break the native track — the chatbot probes availability and degrades to native rendering with an install hint (UI_UNAVAILABLE).

Vite integration

The optional peers above are loaded through dynamic import() so a host without them still builds. Vite's dev server pre-bundles dependencies lazily, so the first dynamic import of an un-optimized package triggers a full re-optimization and a page reload — mid-conversation that aborts in-flight module requests. Declare the ones you installed up front:

// vite.config.ts
import { defineConfig } from 'vite';

export default defineConfig({
  optimizeDeps: {
    // Only list the tracks you actually installed; an entry for a package that
    // is not installed makes the dev server fail to start.
    // Subpaths matter: the A2UI track imports `@a2ui/*/v0_9`, and both tracks
    // pull zod (A2UI needs `zod/v3` specifically).
    include: [
      '@a2ui/web_core/v0_9',
      '@a2ui/lit/v0_9',
      '@a2ui/markdown-it',
      '@lit/context',
      'lit',
      'zod',
      'zod/v3',
      '@openuidev/react-lang'
    ]
  }
});

This matters only for the dev server; production builds resolve the same imports statically.

Minimal example

The snippet below is compiled as-is by this repository's consumer typecheck probe (pnpm test:install-smoke), against the published .d.ts.

import { Chatbot, type ChatbotHostAdapter } from '@webskill/chatbot';
import { OpfsProvider } from '@webskill/sdk/browser';
import '@webskill/chatbot/chatbot.css';

// ChatbotHostAdapter: wire storage, skill roots and a navigation port
// (openConsole / openConsoleTrace). <Chatbot> constructs its own ChatEngine
// from the adapter; pass config for options like generativeUi.
// Model configuration lives in the runtime config store (config.runtimeConfig):
// RuntimeConfig.llm.entries holds the model list, llm.defaultId the default one.
const adapter: ChatbotHostAdapter = {
  storage: new OpfsProvider({ rootName: 'my-app' }),
  skillRoots: ['/skills'],
  navigation: {
    openConsole() {
      /* route to your console surface */
    }
  }
};

export function App() {
  return (
    // Layout contract: the host gives the chatbot its height; the chatbot owns
    // the single main scroll region (h-full min-h-0 on the theme wrapper).
    <div className="h-full min-h-0">
      <Chatbot adapter={adapter} config={{ generativeUi: true }} />
    </div>
  );
}

See examples/chatbot-playground for a complete ChatbotHostAdapter implementation (OPFS storage, skills, demo/model providers, console embedding).

Session list ordering and paging

ChatEngine.listSessions() forwards straight to the SessionStore, so the default FsSessionStore decides what you see:

  • Sessions come back newest first: items[0] is the most recently created session, and the first screen holds the newest page.
  • The page size is the store's (FS_SESSION_PAGE_SIZE, 50). <Chatbot> does not override it — pass your own sessionStore if you need another size.
  • nextCursor points further back in history, and the page it returns is appended to the end of the list. While it is set, the session list shows a Load earlier sessions entry below the existing rows; when it is absent the list is at the end and the entry disappears, so "no button" always means "nothing older".
  • Session files that cannot be parsed are skipped rather than failing the whole list. Their file names come back in skipped and are shown above the list, so a session you expected to see but cannot is always accounted for.

If you supply your own SessionStore, its list() must return the page newest-first. This is a behavioural contract that the type system cannot check: a store that still returns ascending order will render the oldest session at the top.

Embedding models

  • As a component inside an existing web app — mount <Chatbot> in your own layout, pass a ChatEngine configured with your storage / skills / LLM. You control routing; the chatbot is one region on the page.
  • As a full-page foundation (e.g. a webskill.ai/chat-style app) — pair <Chatbot> with @webskill/console for the operations surface, and let the console own navigation across its 22 pages.

Stability

Every public export carries a @stable or @experimental JSDoc tag. The tag is part of the checked-in API snapshot (api-snapshots/chatbot/index.d.ts.snap), so a symbol cannot be quietly downgraded — the change shows up in the diff.

  • @stable — covered by the semver contract from 0.1.0: bug fixes ship in a patch, backwards-compatible capabilities in a minor, breaking changes only in a major with release notes. This covers the surface you wire a host against: Chatbot, ChatEngine, ChatbotHostAdapter, the message/event/session data types, CompositeUiBridge, the layout, theme and i18n exports, and the shell components (InteractionCard, ResultBlocksPro, SettingsDrawer, …).
  • @experimental — may change in a minor or patch release. Only three kinds of symbol qualify, and each one is here for a stated reason:
    • Non-native renderer tiers — the A2UI, OpenUI and Vercel surface hosts, their snapshot variants, VercelPayloadPreview, SpecInteraction, configureA2uiMarkdown, the probe* helpers, RendererKind, RendererCapability and DEFAULT_RENDERER_CAPABILITIES. Their shape tracks upstream ecosystems this package does not own.
    • Surfaces not yet exercised by consumersChatAttachmentInput and ChatAttachmentMeta (multimodal attachments), ChatThinking and ChatTokenUsage (thinking segments and token usage persisted on messages, 0.7.0), and pickUsableLlmEntry (usable-model entry criterion, 0.7.0).
    • RunSnapshot — the resume snapshot format, @experimental in @webskill/sdk for the same reason.

Anything a README example or the published-.d.ts consumer probe imports is @stable by rule: once we teach a call site, we stop calling it experimental. pnpm lint enforces that rule against this file.

License

MIT