llm-kb 0.4.2 → 0.5.0

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 CHANGED
@@ -39,7 +39,7 @@ llm-kb run ./my-documents
39
39
  ```
40
40
 
41
41
  ```
42
- llm-kb v0.4.1
42
+ llm-kb v0.5.0
43
43
 
44
44
  Scanning ./my-documents...
45
45
  Found 9 files (9 PDF)
@@ -7112,6 +7112,40 @@ if (canUseRuntimeCodegen()) {
7112
7112
  }
7113
7113
  }
7114
7114
 
7115
+ // src/model-resolver.ts
7116
+ import { AuthStorage } from "@mariozechner/pi-coding-agent";
7117
+ var ANTHROPIC_TO_OPENROUTER = {
7118
+ "claude-haiku-4-5": "anthropic/claude-haiku-4.5",
7119
+ "claude-sonnet-4-6": "anthropic/claude-sonnet-4.6",
7120
+ "claude-sonnet-4-5": "anthropic/claude-sonnet-4.5",
7121
+ "claude-sonnet-4-0": "anthropic/claude-sonnet-4",
7122
+ "claude-opus-4-5": "anthropic/claude-opus-4.5"
7123
+ };
7124
+ var PROVIDERS = ["anthropic", "openrouter"];
7125
+ async function resolveModel(modelId, authStorage) {
7126
+ const storage = authStorage ?? AuthStorage.create();
7127
+ const anthropicKey = await storage.getApiKey("anthropic");
7128
+ if (anthropicKey) {
7129
+ const model = getModels("anthropic").find((m) => m.id === modelId);
7130
+ if (model) return model;
7131
+ }
7132
+ const openrouterKey = await storage.getApiKey("openrouter");
7133
+ if (openrouterKey) {
7134
+ const orId = ANTHROPIC_TO_OPENROUTER[modelId] ?? modelId;
7135
+ const model = getModels("openrouter").find((m) => m.id === orId);
7136
+ if (model) return model;
7137
+ }
7138
+ return void 0;
7139
+ }
7140
+ async function resolveApiKey(authStorage) {
7141
+ const storage = authStorage ?? AuthStorage.create();
7142
+ for (const provider of PROVIDERS) {
7143
+ const key = await storage.getApiKey(provider);
7144
+ if (key) return { key, provider };
7145
+ }
7146
+ return void 0;
7147
+ }
7148
+
7115
7149
  // src/indexer.ts
7116
7150
  import { readdir, readFile } from "fs/promises";
7117
7151
 
@@ -7211,7 +7245,7 @@ async function buildIndex(folder, sourcesDir, onOutput, authStorage, modelId) {
7211
7245
  })
7212
7246
  });
7213
7247
  await loader.reload();
7214
- const model = modelId ? getModels("anthropic").find((m) => m.id === modelId) : void 0;
7248
+ const model = modelId ? await resolveModel(modelId, authStorage) : void 0;
7215
7249
  const { session } = await createAgentSession({
7216
7250
  cwd: folder,
7217
7251
  resourceLoader: loader,
@@ -7254,6 +7288,8 @@ Add a total word count estimate at the bottom.`;
7254
7288
 
7255
7289
  export {
7256
7290
  completeSimple,
7291
+ resolveModel,
7292
+ resolveApiKey,
7257
7293
  continueKBSession,
7258
7294
  createKBSession,
7259
7295
  getNodeModulesPath,
package/bin/cli.js CHANGED
@@ -4,13 +4,13 @@ import {
4
4
  completeSimple,
5
5
  continueKBSession,
6
6
  createKBSession,
7
- getNodeModulesPath
8
- } from "./chunk-DHOXVEIR.js";
7
+ getNodeModulesPath,
8
+ resolveApiKey,
9
+ resolveModel
10
+ } from "./chunk-G4UEKXXU.js";
9
11
  import "./chunk-3YMNGUZZ.js";
10
12
  import "./chunk-LDHOKBJA.js";
11
- import {
12
- getModels
13
- } from "./chunk-5PYKQQLA.js";
13
+ import "./chunk-5PYKQQLA.js";
14
14
  import "./chunk-EAQYK3U2.js";
15
15
 
16
16
  // src/cli.ts
@@ -335,20 +335,12 @@ function extractText(content) {
335
335
  }
336
336
 
337
337
  // src/wiki-updater.ts
338
- import { AuthStorage } from "@mariozechner/pi-coding-agent";
339
338
  import { existsSync as existsSync2 } from "fs";
340
339
  import { readFile as readFile2, writeFile as writeFile3, mkdir as mkdir3 } from "fs/promises";
341
340
  import { join as join4 } from "path";
342
- import { homedir } from "os";
343
- async function resolveApiKey(authStorage) {
344
- if (authStorage) {
345
- return authStorage.getApiKey("anthropic");
346
- }
347
- const piAuthPath = join4(homedir(), ".pi", "agent", "auth.json");
348
- if (existsSync2(piAuthPath)) {
349
- const storage = AuthStorage.create(piAuthPath);
350
- return storage.getApiKey("anthropic");
351
- }
341
+ async function resolveApiKey2(authStorage) {
342
+ const result = await resolveApiKey(authStorage);
343
+ if (result) return result.key;
352
344
  return process.env.ANTHROPIC_API_KEY;
353
345
  }
354
346
  function buildPrompt(question, answer, sources, date, currentWiki) {
@@ -413,9 +405,9 @@ async function updateWiki(kbRoot, trace, authStorage, indexModelId = "claude-hai
413
405
  const sources = trace.filesRead.map((f) => f.split(/[\\/]/).pop() ?? f).filter((f) => f.endsWith(".md") && f !== "index.md" && f !== "wiki.md").join(", ") || "unknown";
414
406
  const date = new Date(trace.timestamp).toISOString().slice(0, 10);
415
407
  const prompt = buildPrompt(trace.question, trace.answer, sources, date, currentWiki);
416
- const apiKey = await resolveApiKey(authStorage);
408
+ const apiKey = await resolveApiKey2(authStorage);
417
409
  if (!apiKey) return;
418
- const model = getModels("anthropic").find((m) => m.id === indexModelId);
410
+ const model = await resolveModel(indexModelId, authStorage);
419
411
  if (!model) return;
420
412
  const result = await completeSimple(
421
413
  model,
@@ -923,7 +915,7 @@ async function createChat(folder, options) {
923
915
  createBashTool(folder),
924
916
  createWriteTool(folder)
925
917
  ];
926
- const model = options.modelId ? getModels("anthropic").find((m) => m.id === options.modelId) : void 0;
918
+ const model = options.modelId ? await resolveModel(options.modelId, options.authStorage) : void 0;
927
919
  const { session } = await createAgentSession({
928
920
  cwd: folder,
929
921
  resourceLoader: loader,
@@ -952,17 +944,15 @@ async function query(folder, question, options) {
952
944
  session.dispose();
953
945
  if (options.save) {
954
946
  const sourcesDir = join6(folder, ".llm-kb", "wiki", "sources");
955
- const { buildIndex: buildIndex2 } = await import("./indexer-KSYRIVVN.js");
947
+ const { buildIndex: buildIndex2 } = await import("./indexer-Q44ALZ7N.js");
956
948
  await buildIndex2(folder, sourcesDir, void 0, options.authStorage);
957
949
  }
958
950
  }
959
951
 
960
952
  // src/eval.ts
961
- import { AuthStorage as AuthStorage3 } from "@mariozechner/pi-coding-agent";
962
953
  import { readFile as readFile5, readdir as readdir5, writeFile as writeFile5, mkdir as mkdir6 } from "fs/promises";
963
954
  import { existsSync as existsSync5 } from "fs";
964
955
  import { join as join7, basename as basename5 } from "path";
965
- import { homedir as homedir2 } from "os";
966
956
  async function parseSessionsForEval(sessionsDir, sourcesDir, limit) {
967
957
  if (!existsSync5(sessionsDir)) return [];
968
958
  const sessionFiles = (await readdir5(sessionsDir)).filter((f) => f.endsWith(".jsonl")).sort().reverse();
@@ -1102,18 +1092,14 @@ function calculateMetrics(qas) {
1102
1092
  wastedReads
1103
1093
  };
1104
1094
  }
1105
- async function resolveApiKey2(authStorage) {
1106
- if (authStorage) return authStorage.getApiKey("anthropic");
1107
- const piAuthPath = join7(homedir2(), ".pi", "agent", "auth.json");
1108
- if (existsSync5(piAuthPath)) {
1109
- const storage = AuthStorage3.create(piAuthPath);
1110
- return storage.getApiKey("anthropic");
1111
- }
1095
+ async function resolveApiKey3(authStorage) {
1096
+ const result = await resolveApiKey(authStorage);
1097
+ if (result) return result.key;
1112
1098
  return process.env.ANTHROPIC_API_KEY;
1113
1099
  }
1114
1100
  async function judgeQA(qa, apiKey, modelId) {
1115
1101
  const issues = [];
1116
- const model = getModels("anthropic").find((m) => m.id === modelId);
1102
+ const model = await resolveModel(modelId);
1117
1103
  if (!model) return issues;
1118
1104
  const filesSummary = qa.filesRead.map((f) => `File: ${basename5(f.path)}
1119
1105
  Content (first 2000 chars):
@@ -1303,7 +1289,7 @@ async function runEval(kbRoot, options) {
1303
1289
  }
1304
1290
  log("Calculating metrics...");
1305
1291
  const metrics = calculateMetrics(qas);
1306
- const apiKey = await resolveApiKey2(options.authStorage);
1292
+ const apiKey = await resolveApiKey3(options.authStorage);
1307
1293
  const allIssues = [];
1308
1294
  if (apiKey) {
1309
1295
  const modelId = "claude-haiku-4-5";
@@ -5476,17 +5462,17 @@ function resolveKnowledgeBase(startDir) {
5476
5462
  // src/auth.ts
5477
5463
  import { existsSync as existsSync7 } from "fs";
5478
5464
  import { join as join11 } from "path";
5479
- import { homedir as homedir4 } from "os";
5480
- import { AuthStorage as AuthStorage4 } from "@mariozechner/pi-coding-agent";
5465
+ import { homedir as homedir2 } from "os";
5466
+ import { AuthStorage as AuthStorage2 } from "@mariozechner/pi-coding-agent";
5481
5467
  import chalk5 from "chalk";
5482
5468
  function checkAuth() {
5483
- const piAuthPath = join11(homedir4(), ".pi", "agent", "auth.json");
5469
+ const piAuthPath = join11(homedir2(), ".pi", "agent", "auth.json");
5484
5470
  if (existsSync7(piAuthPath)) {
5485
- const authStorage = AuthStorage4.create();
5471
+ const authStorage = AuthStorage2.create();
5486
5472
  return { ok: true, method: "pi-sdk", authStorage };
5487
5473
  }
5488
5474
  if (process.env.ANTHROPIC_API_KEY) {
5489
- const authStorage = AuthStorage4.inMemory({
5475
+ const authStorage = AuthStorage2.inMemory({
5490
5476
  anthropic: { type: "api_key", key: process.env.ANTHROPIC_API_KEY }
5491
5477
  });
5492
5478
  return { ok: true, method: "api-key", authStorage };
@@ -5544,14 +5530,20 @@ async function ensureConfig(kbRoot) {
5544
5530
 
5545
5531
  // src/cli.ts
5546
5532
  import { existsSync as existsSync9 } from "fs";
5533
+ import { readFileSync } from "fs";
5547
5534
  import { mkdir as mkdir8, readdir as readdir6, stat as stat2 } from "fs/promises";
5548
- import { resolve as resolve3, join as join13 } from "path";
5535
+ import { resolve as resolve3, join as join13, dirname as dirname3 } from "path";
5536
+ import { fileURLToPath } from "url";
5549
5537
  import chalk6 from "chalk";
5538
+ var __filename = fileURLToPath(import.meta.url);
5539
+ var __dirname = dirname3(__filename);
5540
+ var pkg = JSON.parse(readFileSync(join13(__dirname, "..", "package.json"), "utf-8"));
5541
+ var VERSION = pkg.version;
5550
5542
  var program = new Command();
5551
- program.name("llm-kb").description("Drop files into a folder. Get a knowledge base you can query.").version("0.4.0");
5543
+ program.name("llm-kb").description("Drop files into a folder. Get a knowledge base you can query.").version(VERSION);
5552
5544
  program.command("run").description("Scan, parse, index, and watch a folder").argument("<folder>", "Path to your documents folder").action(async (folder) => {
5553
5545
  console.log(`
5554
- ${chalk6.bold("llm-kb")} v0.4.0
5546
+ ${chalk6.bold("llm-kb")} v${VERSION}
5555
5547
  `);
5556
5548
  const auth = checkAuth();
5557
5549
  if (!auth.ok) exitWithAuthError();
@@ -1,6 +1,6 @@
1
1
  import {
2
2
  buildIndex
3
- } from "./chunk-DHOXVEIR.js";
3
+ } from "./chunk-G4UEKXXU.js";
4
4
  import "./chunk-3YMNGUZZ.js";
5
5
  import "./chunk-LDHOKBJA.js";
6
6
  import "./chunk-5PYKQQLA.js";
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "llm-kb",
3
- "version": "0.4.2",
3
+ "version": "0.5.0",
4
4
  "description": "LLM-powered knowledge base. Drop documents, build a wiki, ask questions. Inspired by Karpathy.",
5
5
  "bin": {
6
6
  "llm-kb": "./bin/cli.js"