@kbforge/sdk 0.1.0 → 0.1.1

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.
Files changed (2) hide show
  1. package/README.md +347 -0
  2. package/package.json +1 -1
package/README.md ADDED
@@ -0,0 +1,347 @@
1
+ # @kbforge/sdk
2
+
3
+ TypeScript SDK for the [KBForge](https://kbforge.app) API — semantic search and RAG chat over your knowledge bases.
4
+
5
+ ## Installation
6
+
7
+ ```bash
8
+ npm install @kbforge/sdk
9
+ ```
10
+
11
+ ## Quick Start
12
+
13
+ ```typescript
14
+ import { KBForge } from "@kbforge/sdk";
15
+
16
+ const kb = new KBForge({ apiKey: "kbf_..." });
17
+
18
+ // Semantic search
19
+ const results = await kb.retrieve({
20
+ query: "how to configure OAuth",
21
+ knowledgeBase: "my-docs",
22
+ });
23
+
24
+ // RAG chat (streaming)
25
+ for await (const event of await kb.chat({
26
+ knowledgeBase: "my-docs",
27
+ messages: [{ role: "user", content: "How does auth work?" }],
28
+ })) {
29
+ process.stdout.write(event.content);
30
+ }
31
+
32
+ // RAG chat (full text)
33
+ const answer = await kb.chatText({
34
+ knowledgeBase: "my-docs",
35
+ messages: [{ role: "user", content: "Summarize the docs" }],
36
+ });
37
+ ```
38
+
39
+ ## Authentication
40
+
41
+ All API calls require an API key. Create one from the KBForge dashboard under **Settings > API Keys**.
42
+
43
+ ```typescript
44
+ const kb = new KBForge({
45
+ apiKey: "kbf_...",
46
+ baseUrl: "https://kbforge.app", // optional, defaults to https://kbforge.app
47
+ });
48
+ ```
49
+
50
+ ### API Key Permissions
51
+
52
+ Each API key can be configured with granular permissions:
53
+
54
+ | Permission | Access |
55
+ |-----------|--------|
56
+ | `retrieve` | Semantic search and RAG chat |
57
+ | `ingest` | Upload and process documents |
58
+ | `manage` | CRUD on knowledge bases, documents, tags, segments |
59
+ | `chunks` | Edit, split, merge, pin, boost chunks |
60
+ | `admin` | Analytics and settings |
61
+
62
+ API keys can also be **scoped to a specific knowledge base**, restricting all operations to that KB only.
63
+
64
+ ## API Reference
65
+
66
+ ### Retrieve
67
+
68
+ Search your knowledge base using semantic similarity.
69
+
70
+ ```typescript
71
+ const results = await kb.retrieve({
72
+ query: "how to deploy", // required
73
+ knowledgeBase: "my-docs", // required — KB id or slug
74
+ limit: 5, // optional, default 5
75
+ threshold: 0.3, // optional, min similarity score (0-1)
76
+ segment: "getting-started", // optional — segment id or name
77
+ tag: "deployment", // optional — tag id or name
78
+ });
79
+
80
+ // results.chunks[0].content — matched text
81
+ // results.chunks[0].score — similarity score
82
+ // results.chunks[0].documentTitle
83
+ // results.chunks[0].chunkId
84
+ // results.latencyMs
85
+ ```
86
+
87
+ ### Chat
88
+
89
+ RAG-powered chat with streaming responses. Automatically retrieves relevant context from your knowledge base.
90
+
91
+ ```typescript
92
+ // Streaming
93
+ const stream = await kb.chat({
94
+ knowledgeBase: "my-docs", // required
95
+ messages: [ // required
96
+ { role: "user", content: "What is KBForge?" },
97
+ ],
98
+ systemPrompt: "Be concise.", // optional — override default prompt
99
+ segment: "faq", // optional
100
+ tag: "general", // optional
101
+ });
102
+
103
+ for await (const event of stream) {
104
+ process.stdout.write(event.content);
105
+ }
106
+
107
+ // Or get the full response at once
108
+ const answer = await kb.chatText({
109
+ knowledgeBase: "my-docs",
110
+ messages: [{ role: "user", content: "What is KBForge?" }],
111
+ });
112
+ console.log(answer);
113
+ ```
114
+
115
+ ### Knowledge Bases
116
+
117
+ **Permission required:** `manage`
118
+
119
+ ```typescript
120
+ // List all knowledge bases
121
+ const { knowledgeBases } = await kb.knowledgeBases.list();
122
+
123
+ // Create a knowledge base
124
+ const newKB = await kb.knowledgeBases.create({
125
+ name: "Product Docs",
126
+ description: "Internal product documentation",
127
+ });
128
+
129
+ // Delete a knowledge base
130
+ await kb.knowledgeBases.delete("kb-id");
131
+ ```
132
+
133
+ ### Documents
134
+
135
+ **Permission required:** `ingest` (upload), `manage` (list, delete)
136
+
137
+ ```typescript
138
+ // List documents in a knowledge base
139
+ const { documents, total } = await kb.documents.list("kb-id");
140
+
141
+ // Upload a file
142
+ const file = new File(["content"], "guide.pdf", { type: "application/pdf" });
143
+ const doc = await kb.documents.upload({
144
+ knowledgeBaseId: "kb-id",
145
+ file: file,
146
+ });
147
+ // doc.status === "pending" — processing starts automatically
148
+
149
+ // Upload plain text
150
+ const textDoc = await kb.documents.uploadText({
151
+ knowledgeBaseId: "kb-id",
152
+ title: "Quick Start Guide",
153
+ content: "# Getting Started\n\nWelcome to...",
154
+ });
155
+
156
+ // Delete a document
157
+ await kb.documents.delete("doc-id");
158
+ ```
159
+
160
+ ### Chunks
161
+
162
+ **Permission required:** `chunks`
163
+
164
+ ```typescript
165
+ // List chunks for a document
166
+ const { chunks, total } = await kb.chunks.list("doc-id");
167
+ const activeOnly = await kb.chunks.list("doc-id", { activeOnly: true });
168
+
169
+ // Get a single chunk
170
+ const chunk = await kb.chunks.get("chunk-id");
171
+
172
+ // Create a manual chunk
173
+ const newChunk = await kb.chunks.create({
174
+ documentId: "doc-id",
175
+ knowledgeBaseId: "kb-id",
176
+ content: "This is a new chunk of text.",
177
+ insertAfterIndex: 2, // optional — position to insert at
178
+ });
179
+
180
+ // Update a chunk
181
+ await kb.chunks.update("chunk-id", {
182
+ content: "Updated text", // triggers re-embedding
183
+ pinned: true, // pin to boost in search
184
+ boost: 1.5, // relevance multiplier (0.1 - 3.0)
185
+ isActive: true, // activate/deactivate
186
+ });
187
+
188
+ // Delete a chunk
189
+ await kb.chunks.delete("chunk-id");
190
+
191
+ // Split a chunk at a character position
192
+ const splitResult = await kb.chunks.split("chunk-id", 150);
193
+ // splitResult.chunks — array of 2 new chunks
194
+
195
+ // Merge adjacent chunks
196
+ const mergeResult = await kb.chunks.merge(["chunk-id-1", "chunk-id-2"]);
197
+ // mergeResult.chunk — the merged chunk
198
+
199
+ // Bulk operations
200
+ await kb.chunks.bulk({
201
+ action: "pin", // "activate" | "deactivate" | "pin" | "unpin" | "boost" | "delete"
202
+ chunkIds: ["chunk-1", "chunk-2", "chunk-3"],
203
+ boostValue: 2.0, // only used with action: "boost"
204
+ });
205
+ ```
206
+
207
+ ### Tags
208
+
209
+ **Permission required:** `manage`
210
+
211
+ ```typescript
212
+ // List tags in a knowledge base
213
+ const { tags } = await kb.tags.list("kb-id");
214
+
215
+ // Create a tag
216
+ const tag = await kb.tags.create({
217
+ knowledgeBaseId: "kb-id",
218
+ name: "deployment",
219
+ description: "Deployment-related docs",
220
+ color: "#3B82F6",
221
+ });
222
+
223
+ // Update a tag
224
+ await kb.tags.update("tag-id", { name: "deploy", color: "#10B981" });
225
+
226
+ // Delete a tag
227
+ await kb.tags.delete("tag-id");
228
+
229
+ // Assign documents to a tag
230
+ await kb.tags.addDocuments("tag-id", ["doc-id-1", "doc-id-2"]);
231
+
232
+ // Remove a document from a tag
233
+ await kb.tags.removeDocument("tag-id", "doc-id");
234
+ ```
235
+
236
+ ### Segments
237
+
238
+ **Permission required:** `manage`
239
+
240
+ Segments work exactly like tags — they group documents for filtered search.
241
+
242
+ ```typescript
243
+ // List segments
244
+ const { segments } = await kb.segments.list("kb-id");
245
+
246
+ // Create a segment
247
+ const segment = await kb.segments.create({
248
+ knowledgeBaseId: "kb-id",
249
+ name: "Getting Started",
250
+ description: "Onboarding docs",
251
+ color: "#8B5CF6",
252
+ });
253
+
254
+ // Update / Delete
255
+ await kb.segments.update("segment-id", { name: "Onboarding" });
256
+ await kb.segments.delete("segment-id");
257
+
258
+ // Assign / Remove documents
259
+ await kb.segments.addDocuments("segment-id", ["doc-id-1", "doc-id-2"]);
260
+ await kb.segments.removeDocument("segment-id", "doc-id");
261
+ ```
262
+
263
+ ### Analytics
264
+
265
+ **Permission required:** `admin`
266
+
267
+ ```typescript
268
+ // Overview stats
269
+ const overview = await kb.analytics.overview("kb-id");
270
+ // overview.totalQueries, .queriesToday, .queriesThisWeek
271
+ // overview.avgLatencyMs, .avgResultCount, .avgTopScore
272
+
273
+ // Queries per day (last 30 days)
274
+ const { data: daily } = await kb.analytics.queriesPerDay("kb-id", 30);
275
+ // daily[0] = { date: "2026-03-01", count: 42 }
276
+
277
+ // Top queries
278
+ const { data: topQueries } = await kb.analytics.topQueries("kb-id", 10);
279
+ // topQueries[0] = { queryText: "how to deploy", count: 15, avgScore: 0.82 }
280
+
281
+ // Most retrieved documents
282
+ const { data: topDocs } = await kb.analytics.topDocuments("kb-id", 10);
283
+ // topDocs[0] = { documentId: "...", documentTitle: "Deploy Guide", hitCount: 30 }
284
+
285
+ // Gap analysis (low-scoring queries)
286
+ const { data: gaps } = await kb.analytics.gaps("kb-id", 10);
287
+ // gaps[0] = { queryText: "pricing info", count: 5, avgScore: 0.12, lastSeen: "..." }
288
+ ```
289
+
290
+ ## Error Handling
291
+
292
+ All methods throw `KBForgeError` on failure:
293
+
294
+ ```typescript
295
+ import { KBForge, KBForgeError } from "@kbforge/sdk";
296
+
297
+ try {
298
+ await kb.retrieve({ query: "test", knowledgeBase: "nonexistent" });
299
+ } catch (err) {
300
+ if (err instanceof KBForgeError) {
301
+ console.error(err.message); // "Knowledge base not found"
302
+ console.error(err.status); // 404
303
+ }
304
+ }
305
+ ```
306
+
307
+ ### Common error codes
308
+
309
+ | Status | Meaning |
310
+ |--------|---------|
311
+ | 400 | Invalid request (missing fields, bad input) |
312
+ | 401 | Invalid, revoked, or expired API key |
313
+ | 403 | Missing permission or KB scope mismatch |
314
+ | 404 | Resource not found |
315
+ | 409 | Conflict (duplicate name) |
316
+ | 429 | Monthly retrieval limit exceeded |
317
+ | 500 | Internal server error |
318
+
319
+ ## TypeScript
320
+
321
+ All types are exported:
322
+
323
+ ```typescript
324
+ import type {
325
+ RetrieveOptions,
326
+ RetrieveResponse,
327
+ RetrieveChunk,
328
+ ChatMessage,
329
+ ChatOptions,
330
+ KnowledgeBase,
331
+ Document,
332
+ Chunk,
333
+ Tag,
334
+ Segment,
335
+ AnalyticsOverview,
336
+ // ... and more
337
+ } from "@kbforge/sdk";
338
+ ```
339
+
340
+ ## Requirements
341
+
342
+ - Node.js 18+ (uses native `fetch`)
343
+ - Works in browsers, Deno, Bun, and Cloudflare Workers
344
+
345
+ ## License
346
+
347
+ MIT
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kbforge/sdk",
3
- "version": "0.1.0",
3
+ "version": "0.1.1",
4
4
  "description": "TypeScript SDK for the KBForge API — semantic search and RAG chat over your knowledge bases",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",