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 +171 -0
- package/dist/index.cjs +566 -139
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +59 -9
- package/dist/index.d.ts +59 -9
- package/dist/index.js +566 -139
- package/dist/index.js.map +1 -1
- package/dist/rag.cjs +61 -0
- package/dist/rag.cjs.map +1 -0
- package/dist/rag.d.cts +16 -0
- package/dist/rag.d.ts +16 -0
- package/dist/rag.js +59 -0
- package/dist/rag.js.map +1 -0
- package/dist/widget.d.ts +58 -8
- package/dist/widget.js +574 -67
- package/dist/widget.js.map +1 -1
- package/dist/worker.js +22693 -0
- package/dist/worker.js.map +1 -0
- package/package.json +35 -7
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
|