kanha-ai 0.1.3 → 0.1.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md ADDED
@@ -0,0 +1,171 @@
1
+ # kanha-ai
2
+
3
+ Drop-in AI chatbot widget for bots custom-trained on your own website content with [Kanha](https://kanha.ai).
4
+
5
+ The model runs on-device in the visitor's browser over WebGPU. There is no inference API in the loop, so conversations stay on the device and you are not billed per message.
6
+
7
+ ## Install
8
+
9
+ ```bash
10
+ npm install kanha-ai
11
+ ```
12
+
13
+ React is a peer dependency for the React entry point. The CDN widget and Web Component have no framework dependency.
14
+
15
+ ## React component
16
+
17
+ ```tsx
18
+ import { KanhaBot } from "kanha-ai";
19
+
20
+ export default function App() {
21
+ return (
22
+ <KanhaBot
23
+ modelUrl="https://huggingface.co/your-org/your-bot/resolve/main/"
24
+ botName="Acme Assistant"
25
+ welcomeMessage="Ask me anything about Acme."
26
+ suggestions={["What do you sell?", "How does pricing work?"]}
27
+ theme={{ primaryColor: "#0d9488", position: "bottom-right" }}
28
+ />
29
+ );
30
+ }
31
+ ```
32
+
33
+ ## React hook
34
+
35
+ `useKanhaChat` gives you the same engine with no UI, so you can build your own. `loadProgress` is a
36
+ percentage that restarts on each phase of the first load, so pair it with `loadStage` ("Downloading
37
+ model", "Loading cached model", "Preparing GPU", "Almost ready") to explain the number going down.
38
+
39
+ ```tsx
40
+ import { useKanhaChat } from "kanha-ai";
41
+
42
+ function Chat() {
43
+ const { messages, input, setInput, send, stop, clear, isLoading, mode, loadProgress, loadStage, error } =
44
+ useKanhaChat({ modelUrl: "https://huggingface.co/your-org/your-bot/resolve/main/" });
45
+
46
+ return (
47
+ <form onSubmit={(e) => { e.preventDefault(); send(); }}>
48
+ {messages.map((m, i) => <p key={i}><b>{m.role}</b>: {m.content}</p>)}
49
+ <input value={input} onChange={(e) => setInput(e.target.value)} disabled={isLoading} />
50
+ </form>
51
+ );
52
+ }
53
+ ```
54
+
55
+ ## CDN and vanilla JS
56
+
57
+ ```html
58
+ <div id="chat"></div>
59
+ <script type="module">
60
+ import { mount } from "https://cdn.jsdelivr.net/npm/kanha-ai/dist/widget.js";
61
+
62
+ const bot = mount("#chat", {
63
+ modelUrl: "https://huggingface.co/your-org/your-bot/resolve/main/",
64
+ botName: "Acme Assistant",
65
+ });
66
+ </script>
67
+ ```
68
+
69
+ `mount()` returns `{ stop, clear, destroy }` so you can tear the widget down again.
70
+
71
+ The widget build has no bundler requirement. It pulls the WebGPU runtime at load time from
72
+ `https://cdn.jsdelivr.net/npm/@mlc-ai/web-llm@<version>/+esm`, pinned at publish time to the version
73
+ the package was built against, so a plain `<script type="module">` tag is all you need.
74
+
75
+ ## Web Component
76
+
77
+ Loading `widget.js` registers `<kanha-bot>` automatically.
78
+
79
+ ```html
80
+ <script type="module" src="https://cdn.jsdelivr.net/npm/kanha-ai/dist/widget.js"></script>
81
+
82
+ <kanha-bot
83
+ model-url="https://huggingface.co/your-org/your-bot/resolve/main/"
84
+ bot-name="Acme Assistant"
85
+ primary-color="#0d9488"
86
+ position="bottom-right"
87
+ ></kanha-bot>
88
+ ```
89
+
90
+ Props map to kebab-case attributes (`modelUrl` becomes `model-url`, `ragCorpusUrl` becomes `rag-corpus-url`, `repetitionPenalty` becomes `repetition-penalty`). `suggestions` takes a JSON array string. `theme.primaryColor` and `theme.position` are flattened to `primary-color` and `position`.
91
+
92
+ ## Grounded answers with sources
93
+
94
+ Point `ragCorpusUrl` at the grounding corpus published with your bot and the widget retrieves the
95
+ matching passages before every answer, restricts the model to that context, and renders the source
96
+ pages under the reply.
97
+
98
+ ```html
99
+ <kanha-bot
100
+ model-url="https://huggingface.co/your-org/your-bot/resolve/main/"
101
+ rag-corpus-url="https://huggingface.co/your-org/your-bot/resolve/main/rag-corpus.json"
102
+ bot-name="Acme Assistant"
103
+ ></kanha-bot>
104
+ ```
105
+
106
+ When nothing in the corpus matches the question the bot says so instead of guessing, and no model
107
+ call is made. Assistant messages carry the pages they were drawn from as `sources`, so a custom UI
108
+ built on `useKanhaChat` can render its own citations:
109
+
110
+ ```tsx
111
+ {messages.map((m, i) => (
112
+ <div key={i}>
113
+ {m.content}
114
+ {m.sources?.map((s) => <a key={s.url} href={s.url}>{s.title}</a>)}
115
+ </div>
116
+ ))}
117
+ ```
118
+
119
+ `onRetrieveContext` takes precedence when both are set.
120
+
121
+ ## Props
122
+
123
+ | Prop | Type | Default | Description |
124
+ |------|------|---------|-------------|
125
+ | `modelUrl` | `string` | - | Base URL for your bot's model artifacts |
126
+ | `modelLib` | `string` | auto | URL of the matching WebGPU library file, resolved from `modelSize` when omitted |
127
+ | `modelSize` | `string` | `"small"` | Model identity used for runtime selection and metrics |
128
+ | `systemPrompt` | `string` | - | System prompt for the bot |
129
+ | `temperature` | `number` | `0.7` | Sampling temperature (0-2) |
130
+ | `topP` | `number` | `0.8` | Top-p sampling threshold |
131
+ | `repetitionPenalty` | `number` | `1.1` | Penalty on already generated tokens, which suppresses repeated phrasing |
132
+ | `maxTokens` | `number` | `1024` | Max tokens generated per response |
133
+ | `enableThinking` | `boolean` | `false` | Hidden reasoning where the bot supports it |
134
+ | `maxHistoryMessages` | `number` | `12` | Non-system messages sent to the model |
135
+ | `streamUpdateIntervalMs` | `number` | `50` | Minimum delay between visible streaming updates |
136
+ | `cacheBackend` | `"cache" \| "indexeddb"` | `"indexeddb"` | Browser cache backend for downloaded weights |
137
+ | `workerUrl` | `string \| URL` | - | Run inference in a dedicated Web Worker |
138
+ | `contextWindowSize` | `number` | - | Context window override |
139
+ | `onMetrics` | `(m: KanhaChatMetrics) => void` | - | Token usage and latency callback |
140
+ | `onRetrieveContext` | `(query: string) => Promise<string \| null>` | - | Retrieval hook called before generating |
141
+ | `ragPromptTemplate` | `string` | - | Template for retrieved context, with `{context}` and `{query}` |
142
+ | `ragCorpusUrl` | `string` | - | Grounding corpus to retrieve from, which also turns on source links |
143
+ | `botName` | `string` | `"AI Assistant"` | Display name (widget only) |
144
+ | `welcomeMessage` | `string` | `"Ask me anything!"` | Empty-state message (widget only) |
145
+ | `suggestions` | `string[]` | `[]` | Suggested prompts (widget only) |
146
+ | `theme` | `{ primaryColor?, position? }` | teal, bottom-right | Widget theming |
147
+
148
+ `minRamGb` and `weightBytes` are deprecated and ignored.
149
+
150
+ ## Optional entry points
151
+
152
+ | Import | What it gives you |
153
+ |--------|-------------------|
154
+ | `kanha-ai` | `KanhaBot`, `useKanhaChat`, types |
155
+ | `kanha-ai/widget` | `mount()` and the `<kanha-bot>` element, no React |
156
+ | `kanha-ai/rag` | `LocalRAG` for in-browser retrieval over your own documents |
157
+ | `kanha-ai/worker` | Prebuilt Web Worker script to pass as `workerUrl` |
158
+
159
+ `LocalRAG` needs the optional `@huggingface/transformers` peer dependency installed. Pair it with `onRetrieveContext` to ground answers in documents you supply at runtime.
160
+
161
+ ## Browser requirements
162
+
163
+ WebGPU is required. That means a recent Chrome, Edge, or Chromium-based browser, Safari 18+, or Firefox with WebGPU enabled. Model weights download once and are cached in the browser, so the first message is slower than the rest.
164
+
165
+ ## Docs
166
+
167
+ Full setup guide, including how to get your bot's model URLs: [kanha.ai/docs/sdk](https://kanha.ai/docs/sdk)
168
+
169
+ ## License
170
+
171
+ MIT