@tryhamster/gerbil 1.1.2 → 1.1.3
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 +18 -16
- package/dist/cli.mjs +1 -1
- package/dist/cli.mjs.map +1 -1
- package/dist/gpu/hooks.d.mts +3 -3
- package/dist/gpu/hooks.mjs +5 -5
- package/dist/gpu/hooks.mjs.map +1 -1
- package/dist/index-Dgmb2kE3.d.mts.map +1 -1
- package/package.json +1 -2
- package/docs/PROJECT-STATE.md +0 -321
- package/docs/adding-a-model-family.md +0 -280
- package/docs/ai-sdk.md +0 -205
- package/docs/architecture/README.md +0 -84
- package/docs/architecture/caching.md +0 -227
- package/docs/architecture/inference.md +0 -176
- package/docs/architecture/overview.md +0 -189
- package/docs/architecture/streaming.md +0 -261
- package/docs/architecture/webgpu.md +0 -213
- package/docs/browser.md +0 -762
- package/docs/cli.md +0 -155
- package/docs/embeddings.md +0 -156
- package/docs/frameworks.md +0 -90
- package/docs/gerbil-site-native-migration.md +0 -217
- package/docs/gpu-engine/architectures.md +0 -398
- package/docs/gpu-engine/ir.md +0 -372
- package/docs/gpu-engine/kernels.md +0 -718
- package/docs/gpu-engine/paper.html +0 -1759
- package/docs/gpu-engine/paper.md +0 -2109
- package/docs/gpu-engine/safetensors.md +0 -312
- package/docs/gpu-engine/tokenizer.md +0 -302
- package/docs/kernel-research-queue.md +0 -85
- package/docs/mcp-client.md +0 -224
- package/docs/mcp.md +0 -109
- package/docs/memory-rag.md +0 -91
- package/docs/memory.md +0 -301
- package/docs/metal-safari-intel.md +0 -190
- package/docs/mobile-failure-diagnosis.md +0 -124
- package/docs/mobile.md +0 -99
- package/docs/observability.md +0 -230
- package/docs/onnx-removal-plan.md +0 -339
- package/docs/repl.md +0 -473
- package/docs/research/autoresearch-portable.md +0 -933
- package/docs/research/dispatch-reduction-hivemind.md +0 -84
- package/docs/research/ios-safari-model-caching.md +0 -117
- package/docs/research/mobile-webgpu-speed-fusion.md +0 -135
- package/docs/research/native-stt-model-selection.md +0 -49
- package/docs/research/native-tts-model-selection.md +0 -90
- package/docs/research/native-vs-chromium-decision.md +0 -152
- package/docs/research/nemotron-mamba2-inference.md +0 -910
- package/docs/research/qwen35-multimodal.md +0 -293
- package/docs/research/qwen36-gemma4-targets.md +0 -337
- package/docs/research/sota-embedding-models.md +0 -179
- package/docs/research/sota-mobile-models-2026.md +0 -263
- package/docs/research/sota-modality-models.md +0 -202
- package/docs/research/tps-baselines.md +0 -71
- package/docs/research/webgpu-m4-reference.md +0 -104
- package/docs/site-update-plan.md +0 -155
- package/docs/skills.md +0 -261
- package/docs/structured-output.md +0 -123
- package/docs/stt.md +0 -111
- package/docs/tools.md +0 -304
- package/docs/tts.md +0 -147
- package/docs/vision.md +0 -158
package/docs/mcp-client.md
DELETED
|
@@ -1,224 +0,0 @@
|
|
|
1
|
-
# MCP Client
|
|
2
|
-
|
|
3
|
-
Connect Gerbil to external MCP (Model Context Protocol) servers and use their tools in chat or skills.
|
|
4
|
-
|
|
5
|
-
## Quick Start
|
|
6
|
-
|
|
7
|
-
```typescript
|
|
8
|
-
import { connectMCP, callMCPTool, getMCPHub } from "@tryhamster/gerbil/mcp-client";
|
|
9
|
-
|
|
10
|
-
// Connect to an MCP server
|
|
11
|
-
await connectMCP("filesystem", {
|
|
12
|
-
command: "uvx",
|
|
13
|
-
args: ["mcp-server-filesystem", "/home/user"],
|
|
14
|
-
});
|
|
15
|
-
|
|
16
|
-
// Call a tool
|
|
17
|
-
const files = await callMCPTool("filesystem:list_directory", { path: "/" });
|
|
18
|
-
```
|
|
19
|
-
|
|
20
|
-
## MCPClient
|
|
21
|
-
|
|
22
|
-
Direct client for a single MCP server:
|
|
23
|
-
|
|
24
|
-
```typescript
|
|
25
|
-
import { MCPClient } from "@tryhamster/gerbil/mcp-client";
|
|
26
|
-
|
|
27
|
-
const client = new MCPClient("browser", {
|
|
28
|
-
command: "npx",
|
|
29
|
-
args: ["-y", "@anthropic/mcp-server-puppeteer"],
|
|
30
|
-
});
|
|
31
|
-
|
|
32
|
-
// Connect
|
|
33
|
-
await client.connect();
|
|
34
|
-
|
|
35
|
-
// List available tools
|
|
36
|
-
const tools = client.getTools();
|
|
37
|
-
console.log(tools);
|
|
38
|
-
// [{ name: "navigate", description: "Navigate to URL", parameters: {...} }, ...]
|
|
39
|
-
|
|
40
|
-
// Call a tool
|
|
41
|
-
const result = await client.callTool("navigate", { url: "https://example.com" });
|
|
42
|
-
|
|
43
|
-
// Check connection status
|
|
44
|
-
console.log(client.isConnected()); // true
|
|
45
|
-
|
|
46
|
-
// Disconnect when done
|
|
47
|
-
await client.disconnect();
|
|
48
|
-
```
|
|
49
|
-
|
|
50
|
-
## MCPHub
|
|
51
|
-
|
|
52
|
-
Manage multiple MCP servers:
|
|
53
|
-
|
|
54
|
-
```typescript
|
|
55
|
-
import { MCPHub } from "@tryhamster/gerbil/mcp-client";
|
|
56
|
-
|
|
57
|
-
const hub = new MCPHub();
|
|
58
|
-
|
|
59
|
-
// Add multiple servers
|
|
60
|
-
await hub.addServer("filesystem", {
|
|
61
|
-
command: "uvx",
|
|
62
|
-
args: ["mcp-server-filesystem", "/tmp"],
|
|
63
|
-
});
|
|
64
|
-
|
|
65
|
-
await hub.addServer("browser", {
|
|
66
|
-
command: "npx",
|
|
67
|
-
args: ["-y", "@anthropic/mcp-server-puppeteer"],
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
// List all connected servers
|
|
71
|
-
console.log(hub.listServers()); // ["filesystem", "browser"]
|
|
72
|
-
|
|
73
|
-
// Get all tools from all servers
|
|
74
|
-
const allTools = hub.getAllTools();
|
|
75
|
-
// Tools are prefixed: "filesystem:list_directory", "browser:navigate"
|
|
76
|
-
|
|
77
|
-
// Call tool using server:tool format
|
|
78
|
-
await hub.callTool("filesystem:list_directory", { path: "/" });
|
|
79
|
-
|
|
80
|
-
// Remove a server
|
|
81
|
-
await hub.removeServer("browser");
|
|
82
|
-
```
|
|
83
|
-
|
|
84
|
-
## Singleton Hub
|
|
85
|
-
|
|
86
|
-
Use the global hub for app-wide MCP connections:
|
|
87
|
-
|
|
88
|
-
```typescript
|
|
89
|
-
import { getMCPHub, connectMCP, disconnectMCP, callMCPTool } from "@tryhamster/gerbil/mcp-client";
|
|
90
|
-
|
|
91
|
-
// These all use the same global hub
|
|
92
|
-
await connectMCP("myserver", { command: "...", args: [...] });
|
|
93
|
-
const result = await callMCPTool("myserver:sometool", { arg: "value" });
|
|
94
|
-
await disconnectMCP("myserver");
|
|
95
|
-
|
|
96
|
-
// Or access the hub directly
|
|
97
|
-
const hub = getMCPHub();
|
|
98
|
-
```
|
|
99
|
-
|
|
100
|
-
## Using MCP Tools in Chat
|
|
101
|
-
|
|
102
|
-
When connected, MCP tools are automatically registered in Gerbil's tool registry. In **Agent mode**, the AI can use them:
|
|
103
|
-
|
|
104
|
-
```
|
|
105
|
-
User: Read the file /tmp/notes.txt
|
|
106
|
-
|
|
107
|
-
Gerbil: {"tool": "mcp_call", "params": {"tool_name": "filesystem:read_file", "params": {"path": "/tmp/notes.txt"}}}
|
|
108
|
-
|
|
109
|
-
[Tool Result: Contents of notes.txt...]
|
|
110
|
-
|
|
111
|
-
Gerbil: The file contains your meeting notes from yesterday...
|
|
112
|
-
```
|
|
113
|
-
|
|
114
|
-
### Built-in MCP Tools
|
|
115
|
-
|
|
116
|
-
When MCP servers are connected, these tools become available to the AI:
|
|
117
|
-
|
|
118
|
-
| Tool | Description |
|
|
119
|
-
|------|-------------|
|
|
120
|
-
| `mcp_call` | Call any tool from a connected MCP server |
|
|
121
|
-
| `mcp_list` | List all available tools from connected servers |
|
|
122
|
-
|
|
123
|
-
## Using MCP Tools in Skills
|
|
124
|
-
|
|
125
|
-
Create skills that leverage MCP tools:
|
|
126
|
-
|
|
127
|
-
```typescript
|
|
128
|
-
import { defineSkill } from "@tryhamster/gerbil/skills";
|
|
129
|
-
import { getMCPHub } from "@tryhamster/gerbil/mcp-client";
|
|
130
|
-
import { z } from "zod";
|
|
131
|
-
|
|
132
|
-
export const webScraper = defineSkill({
|
|
133
|
-
name: "web-scraper",
|
|
134
|
-
description: "Scrape and summarize a webpage",
|
|
135
|
-
input: z.object({
|
|
136
|
-
url: z.string().url(),
|
|
137
|
-
}),
|
|
138
|
-
async run(input, gerbil) {
|
|
139
|
-
const hub = getMCPHub();
|
|
140
|
-
|
|
141
|
-
// Navigate to page
|
|
142
|
-
await hub.callTool("browser:navigate", { url: input.url });
|
|
143
|
-
|
|
144
|
-
// Get page content
|
|
145
|
-
const content = await hub.callTool("browser:get_content", {});
|
|
146
|
-
|
|
147
|
-
// Summarize with Gerbil
|
|
148
|
-
const summary = await gerbil.generate(
|
|
149
|
-
`Summarize this webpage:\n\n${content}`,
|
|
150
|
-
{ maxTokens: 300 }
|
|
151
|
-
);
|
|
152
|
-
|
|
153
|
-
return summary.text;
|
|
154
|
-
},
|
|
155
|
-
});
|
|
156
|
-
```
|
|
157
|
-
|
|
158
|
-
## Popular MCP Servers
|
|
159
|
-
|
|
160
|
-
| Server | Install | Description |
|
|
161
|
-
|--------|---------|-------------|
|
|
162
|
-
| Filesystem | `uvx mcp-server-filesystem /path` | Read/write files |
|
|
163
|
-
| Puppeteer | `npx -y @anthropic/mcp-server-puppeteer` | Browser automation |
|
|
164
|
-
| SQLite | `uvx mcp-server-sqlite --db-path db.sqlite` | Database access |
|
|
165
|
-
| GitHub | `npx -y @anthropic/mcp-server-github` | GitHub API |
|
|
166
|
-
| Slack | `npx -y @anthropic/mcp-server-slack` | Slack integration |
|
|
167
|
-
|
|
168
|
-
See [modelcontextprotocol.io](https://modelcontextprotocol.io) for more servers.
|
|
169
|
-
|
|
170
|
-
## Server Configuration
|
|
171
|
-
|
|
172
|
-
```typescript
|
|
173
|
-
interface MCPServerConfig {
|
|
174
|
-
/** Command to run (e.g., "npx", "uvx", "node") */
|
|
175
|
-
command: string;
|
|
176
|
-
|
|
177
|
-
/** Arguments for the command */
|
|
178
|
-
args?: string[];
|
|
179
|
-
|
|
180
|
-
/** Environment variables */
|
|
181
|
-
env?: Record<string, string>;
|
|
182
|
-
|
|
183
|
-
/** Working directory */
|
|
184
|
-
cwd?: string;
|
|
185
|
-
}
|
|
186
|
-
```
|
|
187
|
-
|
|
188
|
-
## Error Handling
|
|
189
|
-
|
|
190
|
-
```typescript
|
|
191
|
-
import { connectMCP, callMCPTool } from "@tryhamster/gerbil/mcp-client";
|
|
192
|
-
|
|
193
|
-
try {
|
|
194
|
-
await connectMCP("myserver", { command: "bad-command" });
|
|
195
|
-
} catch (e) {
|
|
196
|
-
console.error("Failed to connect:", e.message);
|
|
197
|
-
}
|
|
198
|
-
|
|
199
|
-
try {
|
|
200
|
-
const result = await callMCPTool("myserver:unknown_tool", {});
|
|
201
|
-
} catch (e) {
|
|
202
|
-
console.error("Tool call failed:", e.message);
|
|
203
|
-
}
|
|
204
|
-
```
|
|
205
|
-
|
|
206
|
-
## REPL Integration
|
|
207
|
-
|
|
208
|
-
In the Gerbil REPL, you can use MCP tools in **Chat** with Agent mode enabled.
|
|
209
|
-
|
|
210
|
-
```
|
|
211
|
-
[gerbil / Chat]
|
|
212
|
-
Mode: [@] Agent
|
|
213
|
-
|
|
214
|
-
You: Connect to the filesystem server at /tmp and list the files
|
|
215
|
-
|
|
216
|
-
Gerbil: I'll use the mcp_list tool to see available tools, then list files.
|
|
217
|
-
{"tool": "mcp_list", "params": {}}
|
|
218
|
-
|
|
219
|
-
[Available MCP tools: filesystem:list_directory, filesystem:read_file...]
|
|
220
|
-
|
|
221
|
-
{"tool": "mcp_call", "params": {"tool_name": "filesystem:list_directory", "params": {"path": "/tmp"}}}
|
|
222
|
-
|
|
223
|
-
[files listed...]
|
|
224
|
-
```
|
package/docs/mcp.md
DELETED
|
@@ -1,109 +0,0 @@
|
|
|
1
|
-
# MCP Server
|
|
2
|
-
|
|
3
|
-
Gerbil can run as a Model Context Protocol (MCP) server for Claude Desktop, Cursor, and other MCP clients.
|
|
4
|
-
|
|
5
|
-
## Start Server
|
|
6
|
-
|
|
7
|
-
```bash
|
|
8
|
-
gerbil serve --mcp
|
|
9
|
-
```
|
|
10
|
-
|
|
11
|
-
## Claude Desktop Config
|
|
12
|
-
|
|
13
|
-
Add to your Claude Desktop config:
|
|
14
|
-
|
|
15
|
-
**macOS**: `~/Library/Application Support/Claude/claude_desktop_config.json`
|
|
16
|
-
**Windows**: `%APPDATA%\Claude\claude_desktop_config.json`
|
|
17
|
-
**Linux**: `~/.config/claude/claude_desktop_config.json`
|
|
18
|
-
|
|
19
|
-
```json
|
|
20
|
-
{
|
|
21
|
-
"mcpServers": {
|
|
22
|
-
"gerbil": {
|
|
23
|
-
"command": "npx",
|
|
24
|
-
"args": ["-y", "@tryhamster/gerbil", "serve", "--mcp"]
|
|
25
|
-
}
|
|
26
|
-
}
|
|
27
|
-
}
|
|
28
|
-
```
|
|
29
|
-
|
|
30
|
-
## Cursor Config
|
|
31
|
-
|
|
32
|
-
Add to `.cursor/mcp.json` in your project:
|
|
33
|
-
|
|
34
|
-
```json
|
|
35
|
-
{
|
|
36
|
-
"mcpServers": {
|
|
37
|
-
"gerbil": {
|
|
38
|
-
"command": "npx",
|
|
39
|
-
"args": ["-y", "@tryhamster/gerbil", "serve", "--mcp"]
|
|
40
|
-
}
|
|
41
|
-
}
|
|
42
|
-
}
|
|
43
|
-
```
|
|
44
|
-
|
|
45
|
-
## Available Tools
|
|
46
|
-
|
|
47
|
-
Built-in skills are exposed as MCP tools:
|
|
48
|
-
|
|
49
|
-
| Tool | Description |
|
|
50
|
-
|------|-------------|
|
|
51
|
-
| `gerbil_generate` | Generate text with local LLM |
|
|
52
|
-
| `gerbil_summarize` | Summarize content |
|
|
53
|
-
| `gerbil_explain` | Explain code or concepts |
|
|
54
|
-
| `gerbil_review` | Code review |
|
|
55
|
-
| `gerbil_commit` | Generate commit message |
|
|
56
|
-
| `gerbil_translate` | Translate text |
|
|
57
|
-
| `gerbil_embed` | Generate embeddings |
|
|
58
|
-
|
|
59
|
-
## Custom Skills as Tools
|
|
60
|
-
|
|
61
|
-
Custom skills loaded via `loadSkills()` are automatically exposed:
|
|
62
|
-
|
|
63
|
-
```typescript
|
|
64
|
-
// In your MCP server setup
|
|
65
|
-
import { loadSkills } from "@tryhamster/gerbil/skills";
|
|
66
|
-
|
|
67
|
-
await loadSkills("./skills");
|
|
68
|
-
// Now your custom skills are available as MCP tools
|
|
69
|
-
```
|
|
70
|
-
|
|
71
|
-
## Programmatic Usage
|
|
72
|
-
|
|
73
|
-
```typescript
|
|
74
|
-
import { createMCPServer, startMCPServer } from "@tryhamster/gerbil/mcp";
|
|
75
|
-
|
|
76
|
-
// Create server instance
|
|
77
|
-
const server = await createMCPServer({ model: "qwen3-0.6b" });
|
|
78
|
-
|
|
79
|
-
// List tools
|
|
80
|
-
const tools = server.listTools();
|
|
81
|
-
console.log(tools.map(t => t.name));
|
|
82
|
-
|
|
83
|
-
// Call a tool
|
|
84
|
-
const result = await server.callTool("gerbil_summarize", {
|
|
85
|
-
content: "Long text here...",
|
|
86
|
-
length: "short",
|
|
87
|
-
});
|
|
88
|
-
|
|
89
|
-
// Or start stdio server for MCP clients
|
|
90
|
-
await startMCPServer({ model: "qwen3-0.6b" });
|
|
91
|
-
```
|
|
92
|
-
|
|
93
|
-
## Options
|
|
94
|
-
|
|
95
|
-
```typescript
|
|
96
|
-
interface MCPServerOptions {
|
|
97
|
-
/** Model to load (default: "qwen3-0.6b") */
|
|
98
|
-
model?: string;
|
|
99
|
-
|
|
100
|
-
/** Device to use */
|
|
101
|
-
device?: "auto" | "gpu" | "cpu";
|
|
102
|
-
|
|
103
|
-
/** Quantization */
|
|
104
|
-
dtype?: "q4" | "q8" | "fp16" | "fp32";
|
|
105
|
-
|
|
106
|
-
/** Specific tools to expose (default: all) */
|
|
107
|
-
tools?: string[];
|
|
108
|
-
}
|
|
109
|
-
```
|
package/docs/memory-rag.md
DELETED
|
@@ -1,91 +0,0 @@
|
|
|
1
|
-
# Memory / RAG (on-device agent memory)
|
|
2
|
-
|
|
3
|
-
> Note: this is the **RAG / persistent-memory** module (`@tryhamster/gerbil/memory`).
|
|
4
|
-
> For GPU/KV-cache memory management see [memory.md](memory.md).
|
|
5
|
-
|
|
6
|
-
Gerbil's memory module is an on-device, persistent memory layer that turns
|
|
7
|
-
Gerbil into an agent harness: store text + embeddings, retrieve semantically,
|
|
8
|
-
and rebuild a token-budgeted context block every turn.
|
|
9
|
-
|
|
10
|
-
It is engine-agnostic — bring any embedder and any storage backend — but wires
|
|
11
|
-
straight into Gerbil's native embeddings by default.
|
|
12
|
-
|
|
13
|
-
## Quick start
|
|
14
|
-
|
|
15
|
-
```ts
|
|
16
|
-
import { Gerbil } from "@tryhamster/gerbil";
|
|
17
|
-
import { createMemory, createGerbilEmbedder } from "@tryhamster/gerbil/memory";
|
|
18
|
-
|
|
19
|
-
const g = new Gerbil();
|
|
20
|
-
await g.loadModel("embeddinggemma-300m");
|
|
21
|
-
|
|
22
|
-
const mem = createMemory({ embed: createGerbilEmbedder(g) });
|
|
23
|
-
|
|
24
|
-
await mem.add("Paris is the capital of France", { metadata: { topic: "geo" } });
|
|
25
|
-
const hits = await mem.search("French capital", { k: 3 });
|
|
26
|
-
const { context } = await mem.recall("French capital", { tokenBudget: 512 });
|
|
27
|
-
```
|
|
28
|
-
|
|
29
|
-
## Public API
|
|
30
|
-
|
|
31
|
-
`createMemory({ embed, store?, redact?, chunk? }) → Memory`
|
|
32
|
-
|
|
33
|
-
| Method | Description |
|
|
34
|
-
| --- | --- |
|
|
35
|
-
| `add(text, { metadata?, id?, chunk? })` | Redact → (optional) chunk → embed → normalize → store. Returns created ids. |
|
|
36
|
-
| `search(query, { k?, filter?, minScore? })` | Cosine top-k. Returns `{ record, score }[]`. |
|
|
37
|
-
| `recall(query, { tokenBudget?, k?, filter?, minScore?, separator? })` | Retrieve + greedily pack into a token-budgeted context block. |
|
|
38
|
-
| `get(id)` / `delete(id)` / `list(filter?)` / `clear()` / `size()` | CRUD over records. |
|
|
39
|
-
| `export()` / `import(snapshot)` | JSON snapshot round-trip. |
|
|
40
|
-
| `backend` | The underlying `MemoryStore` (for advanced use). |
|
|
41
|
-
|
|
42
|
-
## Backends (pluggable `MemoryStore`)
|
|
43
|
-
|
|
44
|
-
| Factory | Runtime | Durability |
|
|
45
|
-
| --- | --- | --- |
|
|
46
|
-
| `createInMemoryStore()` (default) | Node + browser | none (process lifetime) |
|
|
47
|
-
| `createIndexedDBStore({ dbName?, storeName?, indexedDB? })` | browser | durable across sessions |
|
|
48
|
-
| `createFileStore(path)` | Node | durable JSON on disk |
|
|
49
|
-
|
|
50
|
-
All backends store **pre-normalized** embeddings and perform a brute-force
|
|
51
|
-
cosine top-k scan, which is fine to the thousands-of-records scale. Inject an
|
|
52
|
-
`indexedDB` factory (e.g. `fake-indexeddb`) to exercise the IndexedDB backend
|
|
53
|
-
under Node.
|
|
54
|
-
|
|
55
|
-
## Embedder injection
|
|
56
|
-
|
|
57
|
-
The module only needs `(texts: string[]) => Promise<Float32Array[]>`.
|
|
58
|
-
`createGerbilEmbedder(engine)` adapts any object with a compatible
|
|
59
|
-
`embedBatch` (a `Gerbil` instance, the one-liner `embedBatch`, or the browser
|
|
60
|
-
`useEmbedding().embedBatch`). Any other embedder works by passing the function
|
|
61
|
-
directly.
|
|
62
|
-
|
|
63
|
-
## Chunking
|
|
64
|
-
|
|
65
|
-
`add(text, { chunk: true })` or `add(text, { chunk: { chunkSize, overlap } })`
|
|
66
|
-
splits long documents into overlapping character windows (defaults: 1000 chars,
|
|
67
|
-
200 overlap), one record per chunk, so retrieval targets relevant passages.
|
|
68
|
-
|
|
69
|
-
## Context packing (`recall`)
|
|
70
|
-
|
|
71
|
-
`recall` retrieves a candidate pool (default `k: 20`), then greedily fills a
|
|
72
|
-
context block highest-score-first, stopping before `tokenBudget` is exceeded
|
|
73
|
-
(it skips a too-large candidate and tries smaller ones rather than stopping
|
|
74
|
-
outright). Token counts are **approximate**: the heuristic is ~4 characters per
|
|
75
|
-
token (the common English-ish rule), deliberately avoiding a tokenizer
|
|
76
|
-
dependency. The goal is to stay under a model's context window, not exact
|
|
77
|
-
accounting.
|
|
78
|
-
|
|
79
|
-
## Privacy
|
|
80
|
-
|
|
81
|
-
- `redact` is applied on **write**: a `RegExp` (matches → `[REDACTED]`) or a
|
|
82
|
-
`(text) => string` predicate.
|
|
83
|
-
- `export()` / `import()` move the full corpus as JSON.
|
|
84
|
-
|
|
85
|
-
## Follow-ups
|
|
86
|
-
|
|
87
|
-
- **HNSW/ANN index** for >10k records (current scan is O(n) per query).
|
|
88
|
-
- **Node OPFS / SQLite backend** for larger durable corpora than the JSON
|
|
89
|
-
file store comfortably holds.
|
|
90
|
-
- **Real tokenizer** option for exact budgeting (currently a char heuristic).
|
|
91
|
-
- **TTL / decay & dedup** policies for long-running agents.
|