llm-kb 0.4.0 → 0.4.2
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 +183 -42
- package/bin/anthropic-5TIU2EED.js +5515 -0
- package/bin/azure-openai-responses-ZVUVMK3G.js +190 -0
- package/bin/chunk-2WV6TQRI.js +4792 -0
- package/bin/chunk-3YMNGUZZ.js +262 -0
- package/bin/chunk-5PYKQQLA.js +14295 -0
- package/bin/chunk-65KFH7OI.js +31 -0
- package/bin/chunk-DHOXVEIR.js +7261 -0
- package/bin/chunk-EAQYK3U2.js +41 -0
- package/bin/chunk-IFS3OKBN.js +428 -0
- package/bin/chunk-LDHOKBJA.js +86 -0
- package/bin/chunk-SLYBG6ZQ.js +32681 -0
- package/bin/chunk-UEODFF7H.js +17 -0
- package/bin/chunk-XCXTZJGO.js +174 -0
- package/bin/chunk-XFV534WU.js +7056 -0
- package/bin/cli.js +30 -4
- package/bin/dist-3YH7P2QF.js +1244 -0
- package/bin/google-JFC43EFJ.js +371 -0
- package/bin/google-gemini-cli-K4XNMYDI.js +712 -0
- package/bin/google-vertex-Y42F254G.js +414 -0
- package/bin/indexer-KSYRIVVN.js +10 -0
- package/bin/mistral-ZU2JS5XZ.js +38406 -0
- package/bin/multipart-parser-CO464TZY.js +371 -0
- package/bin/openai-codex-responses-NW2LELBH.js +712 -0
- package/bin/openai-completions-TW3VKTHO.js +662 -0
- package/bin/openai-responses-VGL522MK.js +198 -0
- package/bin/src-Y22OHE3S.js +1408 -0
- package/package.json +6 -1
- package/PHASE2_SPEC.md +0 -274
- package/PHASE3_SPEC.md +0 -245
- package/PHASE4_SPEC.md +0 -358
- package/SPEC.md +0 -275
- package/plan.md +0 -300
- package/src/auth.ts +0 -55
- package/src/cli.ts +0 -257
- package/src/config.ts +0 -61
- package/src/eval.ts +0 -548
- package/src/indexer.ts +0 -152
- package/src/md-stream.ts +0 -133
- package/src/pdf.ts +0 -119
- package/src/query.ts +0 -408
- package/src/resolve-kb.ts +0 -19
- package/src/scan.ts +0 -59
- package/src/session-store.ts +0 -22
- package/src/session-watcher.ts +0 -89
- package/src/trace-builder.ts +0 -168
- package/src/tui-display.ts +0 -281
- package/src/utils.ts +0 -17
- package/src/watcher.ts +0 -87
- package/src/wiki-updater.ts +0 -136
- package/test/auth.test.ts +0 -65
- package/test/config.test.ts +0 -96
- package/test/md-stream.test.ts +0 -98
- package/test/resolve-kb.test.ts +0 -33
- package/test/scan.test.ts +0 -65
- package/test/trace-builder.test.ts +0 -215
- package/tsconfig.json +0 -14
- package/vitest.config.ts +0 -8
|
@@ -1,215 +0,0 @@
|
|
|
1
|
-
import { describe, it, expect, beforeEach, afterEach } from "vitest";
|
|
2
|
-
import { buildTrace, saveTrace, appendToQueryLog, KBTrace } from "../src/trace-builder.js";
|
|
3
|
-
import { mkdtemp, rm, writeFile, readFile, mkdir } from "node:fs/promises";
|
|
4
|
-
import { join } from "node:path";
|
|
5
|
-
import { tmpdir } from "node:os";
|
|
6
|
-
import { existsSync } from "node:fs";
|
|
7
|
-
|
|
8
|
-
describe("trace-builder", () => {
|
|
9
|
-
let tempDir: string;
|
|
10
|
-
let sourcesDir: string;
|
|
11
|
-
|
|
12
|
-
beforeEach(async () => {
|
|
13
|
-
tempDir = await mkdtemp(join(tmpdir(), "llm-kb-test-"));
|
|
14
|
-
sourcesDir = join(tempDir, ".llm-kb", "wiki", "sources");
|
|
15
|
-
await mkdir(sourcesDir, { recursive: true });
|
|
16
|
-
// Create some source files
|
|
17
|
-
await writeFile(join(sourcesDir, "doc1.md"), "# Doc 1");
|
|
18
|
-
await writeFile(join(sourcesDir, "doc2.md"), "# Doc 2");
|
|
19
|
-
});
|
|
20
|
-
|
|
21
|
-
afterEach(async () => {
|
|
22
|
-
await rm(tempDir, { recursive: true, force: true });
|
|
23
|
-
});
|
|
24
|
-
|
|
25
|
-
function makeSessionJsonl(entries: {
|
|
26
|
-
header?: any;
|
|
27
|
-
modelChange?: any;
|
|
28
|
-
sessionInfo?: any;
|
|
29
|
-
messages?: any[];
|
|
30
|
-
}): string {
|
|
31
|
-
const lines: string[] = [];
|
|
32
|
-
const header = entries.header ?? {
|
|
33
|
-
type: "session", version: 3, id: "test-session-id",
|
|
34
|
-
timestamp: "2026-04-06T10:00:00Z", cwd: tempDir,
|
|
35
|
-
};
|
|
36
|
-
lines.push(JSON.stringify(header));
|
|
37
|
-
|
|
38
|
-
if (entries.modelChange) lines.push(JSON.stringify(entries.modelChange));
|
|
39
|
-
if (entries.sessionInfo) lines.push(JSON.stringify(entries.sessionInfo));
|
|
40
|
-
for (const msg of entries.messages ?? []) lines.push(JSON.stringify(msg));
|
|
41
|
-
|
|
42
|
-
return lines.join("\n");
|
|
43
|
-
}
|
|
44
|
-
|
|
45
|
-
describe("buildTrace", () => {
|
|
46
|
-
it("returns null for incomplete sessions (no stop message)", async () => {
|
|
47
|
-
const jsonl = makeSessionJsonl({
|
|
48
|
-
messages: [
|
|
49
|
-
{
|
|
50
|
-
type: "message", id: "m1", parentId: null, timestamp: "2026-04-06T10:00:01Z",
|
|
51
|
-
message: { role: "user", content: [{ type: "text", text: "Hello" }], timestamp: 1 },
|
|
52
|
-
},
|
|
53
|
-
{
|
|
54
|
-
type: "message", id: "m2", parentId: "m1", timestamp: "2026-04-06T10:00:02Z",
|
|
55
|
-
message: { role: "assistant", content: [{ type: "text", text: "Hi" }], stopReason: "toolUse", timestamp: 2 },
|
|
56
|
-
},
|
|
57
|
-
],
|
|
58
|
-
});
|
|
59
|
-
const file = join(tempDir, "session.jsonl");
|
|
60
|
-
await writeFile(file, jsonl);
|
|
61
|
-
expect(await buildTrace(file, sourcesDir)).toBeNull();
|
|
62
|
-
});
|
|
63
|
-
|
|
64
|
-
it("parses a complete query session", async () => {
|
|
65
|
-
const jsonl = makeSessionJsonl({
|
|
66
|
-
modelChange: { type: "model_change", id: "mc1", parentId: null, timestamp: "2026-04-06T10:00:00Z", provider: "anthropic", modelId: "claude-sonnet-4-6" },
|
|
67
|
-
sessionInfo: { type: "session_info", id: "si1", parentId: "mc1", timestamp: "2026-04-06T10:00:00Z", name: "query: What is doc1?" },
|
|
68
|
-
messages: [
|
|
69
|
-
{
|
|
70
|
-
type: "message", id: "m1", parentId: "si1", timestamp: "2026-04-06T10:00:01Z",
|
|
71
|
-
message: { role: "user", content: [{ type: "text", text: "What is doc1?" }], timestamp: 1000 },
|
|
72
|
-
},
|
|
73
|
-
{
|
|
74
|
-
type: "message", id: "m2", parentId: "m1", timestamp: "2026-04-06T10:00:05Z",
|
|
75
|
-
message: {
|
|
76
|
-
role: "assistant",
|
|
77
|
-
content: [
|
|
78
|
-
{ type: "toolCall", id: "tc1", name: "read", arguments: { path: ".llm-kb/wiki/sources/doc1.md" } },
|
|
79
|
-
{ type: "text", text: "Doc 1 is about X." },
|
|
80
|
-
],
|
|
81
|
-
model: "claude-sonnet-4-6", stopReason: "stop", timestamp: 5000,
|
|
82
|
-
},
|
|
83
|
-
},
|
|
84
|
-
],
|
|
85
|
-
});
|
|
86
|
-
|
|
87
|
-
const file = join(tempDir, "session.jsonl");
|
|
88
|
-
await writeFile(file, jsonl);
|
|
89
|
-
const trace = await buildTrace(file, sourcesDir);
|
|
90
|
-
|
|
91
|
-
expect(trace).not.toBeNull();
|
|
92
|
-
expect(trace!.mode).toBe("query");
|
|
93
|
-
expect(trace!.question).toBe("What is doc1?");
|
|
94
|
-
expect(trace!.answer).toBe("Doc 1 is about X.");
|
|
95
|
-
expect(trace!.model).toBe("claude-sonnet-4-6");
|
|
96
|
-
expect(trace!.filesRead).toContain(".llm-kb/wiki/sources/doc1.md");
|
|
97
|
-
expect(trace!.filesAvailable).toContain("doc1.md");
|
|
98
|
-
expect(trace!.filesSkipped).toContain("doc2.md");
|
|
99
|
-
expect(trace!.durationMs).toBe(4000);
|
|
100
|
-
});
|
|
101
|
-
|
|
102
|
-
it("identifies index sessions by session name", async () => {
|
|
103
|
-
const jsonl = makeSessionJsonl({
|
|
104
|
-
sessionInfo: { type: "session_info", id: "si1", parentId: null, timestamp: "2026-04-06T10:00:00Z", name: "index: 2026-04-06" },
|
|
105
|
-
messages: [
|
|
106
|
-
{
|
|
107
|
-
type: "message", id: "m1", parentId: "si1", timestamp: "2026-04-06T10:00:01Z",
|
|
108
|
-
message: { role: "user", content: "Build the index", timestamp: 1 },
|
|
109
|
-
},
|
|
110
|
-
{
|
|
111
|
-
type: "message", id: "m2", parentId: "m1", timestamp: "2026-04-06T10:00:05Z",
|
|
112
|
-
message: { role: "assistant", content: [{ type: "text", text: "Done" }], stopReason: "stop", timestamp: 2 },
|
|
113
|
-
},
|
|
114
|
-
],
|
|
115
|
-
});
|
|
116
|
-
|
|
117
|
-
const file = join(tempDir, "session.jsonl");
|
|
118
|
-
await writeFile(file, jsonl);
|
|
119
|
-
const trace = await buildTrace(file, sourcesDir);
|
|
120
|
-
expect(trace!.mode).toBe("index");
|
|
121
|
-
});
|
|
122
|
-
|
|
123
|
-
it("returns null for files with fewer than 2 lines", async () => {
|
|
124
|
-
const file = join(tempDir, "empty.jsonl");
|
|
125
|
-
await writeFile(file, '{"type":"session"}\n');
|
|
126
|
-
expect(await buildTrace(file, sourcesDir)).toBeNull();
|
|
127
|
-
});
|
|
128
|
-
});
|
|
129
|
-
|
|
130
|
-
describe("saveTrace", () => {
|
|
131
|
-
it("writes trace JSON to .llm-kb/traces/", async () => {
|
|
132
|
-
const trace: KBTrace = {
|
|
133
|
-
sessionId: "abc123",
|
|
134
|
-
sessionFile: "session.jsonl",
|
|
135
|
-
timestamp: "2026-04-06T10:00:00Z",
|
|
136
|
-
mode: "query",
|
|
137
|
-
question: "test?",
|
|
138
|
-
answer: "yes",
|
|
139
|
-
filesRead: [],
|
|
140
|
-
filesAvailable: [],
|
|
141
|
-
filesSkipped: [],
|
|
142
|
-
model: "test-model",
|
|
143
|
-
};
|
|
144
|
-
|
|
145
|
-
await saveTrace(tempDir, trace);
|
|
146
|
-
const path = join(tempDir, ".llm-kb", "traces", "abc123.json");
|
|
147
|
-
expect(existsSync(path)).toBe(true);
|
|
148
|
-
|
|
149
|
-
const saved = JSON.parse(await readFile(path, "utf-8"));
|
|
150
|
-
expect(saved.sessionId).toBe("abc123");
|
|
151
|
-
expect(saved.question).toBe("test?");
|
|
152
|
-
});
|
|
153
|
-
});
|
|
154
|
-
|
|
155
|
-
describe("appendToQueryLog", () => {
|
|
156
|
-
it("creates queries.md with header on first call", async () => {
|
|
157
|
-
const trace: KBTrace = {
|
|
158
|
-
sessionId: "abc",
|
|
159
|
-
sessionFile: "s.jsonl",
|
|
160
|
-
timestamp: "2026-04-06T10:00:00Z",
|
|
161
|
-
mode: "query",
|
|
162
|
-
question: "What is X?",
|
|
163
|
-
answer: "X is Y.",
|
|
164
|
-
filesRead: ["doc1.md"],
|
|
165
|
-
filesAvailable: ["doc1.md"],
|
|
166
|
-
filesSkipped: [],
|
|
167
|
-
model: "test",
|
|
168
|
-
};
|
|
169
|
-
|
|
170
|
-
await appendToQueryLog(tempDir, trace);
|
|
171
|
-
const logPath = join(tempDir, ".llm-kb", "wiki", "queries.md");
|
|
172
|
-
expect(existsSync(logPath)).toBe(true);
|
|
173
|
-
|
|
174
|
-
const content = await readFile(logPath, "utf-8");
|
|
175
|
-
expect(content).toContain("# Query Log");
|
|
176
|
-
expect(content).toContain("## What is X?");
|
|
177
|
-
expect(content).toContain("X is Y.");
|
|
178
|
-
});
|
|
179
|
-
|
|
180
|
-
it("skips non-query traces", async () => {
|
|
181
|
-
const trace: KBTrace = {
|
|
182
|
-
sessionId: "abc",
|
|
183
|
-
sessionFile: "s.jsonl",
|
|
184
|
-
timestamp: "2026-04-06T10:00:00Z",
|
|
185
|
-
mode: "index",
|
|
186
|
-
filesRead: [],
|
|
187
|
-
filesAvailable: [],
|
|
188
|
-
filesSkipped: [],
|
|
189
|
-
};
|
|
190
|
-
|
|
191
|
-
await appendToQueryLog(tempDir, trace);
|
|
192
|
-
const logPath = join(tempDir, ".llm-kb", "wiki", "queries.md");
|
|
193
|
-
expect(existsSync(logPath)).toBe(false);
|
|
194
|
-
});
|
|
195
|
-
|
|
196
|
-
it("prepends new entries to existing log", async () => {
|
|
197
|
-
const trace1: KBTrace = {
|
|
198
|
-
sessionId: "a", sessionFile: "s.jsonl", timestamp: "2026-04-06T10:00:00Z",
|
|
199
|
-
mode: "query", question: "First?", answer: "One", filesRead: [], filesAvailable: [], filesSkipped: [],
|
|
200
|
-
};
|
|
201
|
-
const trace2: KBTrace = {
|
|
202
|
-
sessionId: "b", sessionFile: "s.jsonl", timestamp: "2026-04-06T11:00:00Z",
|
|
203
|
-
mode: "query", question: "Second?", answer: "Two", filesRead: [], filesAvailable: [], filesSkipped: [],
|
|
204
|
-
};
|
|
205
|
-
|
|
206
|
-
await appendToQueryLog(tempDir, trace1);
|
|
207
|
-
await appendToQueryLog(tempDir, trace2);
|
|
208
|
-
|
|
209
|
-
const content = await readFile(join(tempDir, ".llm-kb", "wiki", "queries.md"), "utf-8");
|
|
210
|
-
const firstIdx = content.indexOf("Second?");
|
|
211
|
-
const secondIdx = content.indexOf("First?");
|
|
212
|
-
expect(firstIdx).toBeLessThan(secondIdx); // newest first
|
|
213
|
-
});
|
|
214
|
-
});
|
|
215
|
-
});
|
package/tsconfig.json
DELETED
|
@@ -1,14 +0,0 @@
|
|
|
1
|
-
{
|
|
2
|
-
"compilerOptions": {
|
|
3
|
-
"target": "ES2022",
|
|
4
|
-
"module": "ES2022",
|
|
5
|
-
"moduleResolution": "bundler",
|
|
6
|
-
"strict": true,
|
|
7
|
-
"esModuleInterop": true,
|
|
8
|
-
"outDir": "dist",
|
|
9
|
-
"rootDir": "src",
|
|
10
|
-
"declaration": true,
|
|
11
|
-
"sourceMap": true
|
|
12
|
-
},
|
|
13
|
-
"include": ["src"]
|
|
14
|
-
}
|