sensemaking 0.17.0 → 0.17.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.
- package/dist/cjs/cli/map.js +4 -4
- package/dist/cjs/cli/map.js.map +1 -1
- package/dist/cjs/cli/named.js +2 -2
- package/dist/cjs/cli/named.js.map +1 -1
- package/dist/cjs/cli/path.js +7 -6
- package/dist/cjs/cli/path.js.map +1 -1
- package/dist/cjs/cli/peek.js +4 -4
- package/dist/cjs/cli/peek.js.map +1 -1
- package/dist/cjs/cli/related.js +4 -4
- package/dist/cjs/cli/related.js.map +1 -1
- package/dist/cjs/cli/search.js +4 -4
- package/dist/cjs/cli/search.js.map +1 -1
- package/dist/cjs/cli/status.js +18 -18
- package/dist/cjs/cli/status.js.map +1 -1
- package/dist/cjs/embed/distribution.d.cts +4 -0
- package/dist/cjs/embed/distribution.d.ts +4 -0
- package/dist/cjs/embed/distribution.js +30 -0
- package/dist/cjs/embed/distribution.js.map +1 -0
- package/dist/cjs/embed/langfit.d.cts +0 -3
- package/dist/cjs/embed/langfit.d.ts +0 -3
- package/dist/cjs/embed/langfit.js +21 -24
- package/dist/cjs/embed/langfit.js.map +1 -1
- package/dist/cjs/embed/static.js +13 -3
- package/dist/cjs/embed/static.js.map +1 -1
- package/dist/esm/cli/map.js +1 -1
- package/dist/esm/cli/map.js.map +1 -1
- package/dist/esm/cli/named.js +1 -1
- package/dist/esm/cli/named.js.map +1 -1
- package/dist/esm/cli/path.js +2 -1
- package/dist/esm/cli/path.js.map +1 -1
- package/dist/esm/cli/peek.js +1 -1
- package/dist/esm/cli/peek.js.map +1 -1
- package/dist/esm/cli/related.js +1 -1
- package/dist/esm/cli/related.js.map +1 -1
- package/dist/esm/cli/search.js +1 -1
- package/dist/esm/cli/search.js.map +1 -1
- package/dist/esm/cli/status.js +2 -2
- package/dist/esm/cli/status.js.map +1 -1
- package/dist/esm/embed/distribution.d.ts +4 -0
- package/dist/esm/embed/distribution.js +11 -0
- package/dist/esm/embed/distribution.js.map +1 -0
- package/dist/esm/embed/langfit.d.ts +0 -3
- package/dist/esm/embed/langfit.js +10 -10
- package/dist/esm/embed/langfit.js.map +1 -1
- package/dist/esm/embed/static.js +6 -1
- package/dist/esm/embed/static.js.map +1 -1
- package/package.json +1 -1
|
@@ -2,23 +2,15 @@
|
|
|
2
2
|
Object.defineProperty(exports, "__esModule", {
|
|
3
3
|
value: true
|
|
4
4
|
});
|
|
5
|
-
|
|
6
|
-
|
|
7
|
-
|
|
8
|
-
get: Object.getOwnPropertyDescriptor(all, name).get
|
|
9
|
-
});
|
|
10
|
-
}
|
|
11
|
-
_export(exports, {
|
|
12
|
-
get checkLanguageFit () {
|
|
5
|
+
Object.defineProperty(exports, "checkLanguageFit", {
|
|
6
|
+
enumerable: true,
|
|
7
|
+
get: function() {
|
|
13
8
|
return checkLanguageFit;
|
|
14
|
-
},
|
|
15
|
-
get languageDistribution () {
|
|
16
|
-
return languageDistribution;
|
|
17
9
|
}
|
|
18
10
|
});
|
|
19
|
-
var
|
|
20
|
-
var _sharedts = require("../db/shared.js");
|
|
11
|
+
var _nodemodule = /*#__PURE__*/ _interop_require_default(require("node:module"));
|
|
21
12
|
var _errorsts = require("../errors.js");
|
|
13
|
+
var _distributionts = require("./distribution.js");
|
|
22
14
|
var _languagests = require("./languages.js");
|
|
23
15
|
function _array_like_to_array(arr, len) {
|
|
24
16
|
if (len == null || len > arr.length) len = arr.length;
|
|
@@ -65,6 +57,11 @@ function _define_property(obj, key, value) {
|
|
|
65
57
|
} else obj[key] = value;
|
|
66
58
|
return obj;
|
|
67
59
|
}
|
|
60
|
+
function _interop_require_default(obj) {
|
|
61
|
+
return obj && obj.__esModule ? obj : {
|
|
62
|
+
default: obj
|
|
63
|
+
};
|
|
64
|
+
}
|
|
68
65
|
function _iterable_to_array_limit(arr, i) {
|
|
69
66
|
var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"];
|
|
70
67
|
if (_i == null) return;
|
|
@@ -217,36 +214,36 @@ function _unsupported_iterable_to_array(o, minLen) {
|
|
|
217
214
|
if (n === "Map" || n === "Set") return Array.from(n);
|
|
218
215
|
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array(o, minLen);
|
|
219
216
|
}
|
|
220
|
-
var META_KEY = 'embed_languages';
|
|
221
217
|
// franc's own reliability floor is a handful of characters; this is a cheap upper bound, not a
|
|
222
218
|
// per-chunk minimum -- a short chunk is simply more likely to come back 'und' (unclassified).
|
|
223
219
|
var SAMPLE_CHARS = 300;
|
|
224
220
|
// A majority computed over a handful of chunks is noise, not a corpus signal; the decision rule
|
|
225
221
|
// never fires below this many classified chunks, declared languages or not.
|
|
226
222
|
var MIN_CLASSIFIED = 10;
|
|
227
|
-
|
|
228
|
-
|
|
229
|
-
|
|
230
|
-
|
|
231
|
-
function classify(text) {
|
|
232
|
-
var code =
|
|
223
|
+
// franc-min is a 148K static import; a top-level import put it on every command's module graph
|
|
224
|
+
// regardless of whether the semantic path ran, shipped as the 0.17.0 regression. Deferred to a
|
|
225
|
+
// synchronous require inside checkLanguageFit so only the embed path pays for it.
|
|
226
|
+
var _require = typeof require === 'undefined' ? _nodemodule.default.createRequire(require("url").pathToFileURL(__filename).toString()) : require;
|
|
227
|
+
function classify(franc, text) {
|
|
228
|
+
var code = franc(text.slice(0, SAMPLE_CHARS));
|
|
233
229
|
return code === 'und' ? undefined : code;
|
|
234
230
|
}
|
|
235
231
|
function checkLanguageFit(db, provider, texts) {
|
|
236
232
|
return _async_to_generator(function() {
|
|
237
|
-
var _languageDistribution, persisted, merged, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, text, _merged_code, code, total, declared, _Object_entries_sort_, majorityLang, majorityCount, pct;
|
|
233
|
+
var _languageDistribution, franc, persisted, merged, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, text, _merged_code, code, total, declared, _Object_entries_sort_, majorityLang, majorityCount, pct;
|
|
238
234
|
return _ts_generator(this, function(_state) {
|
|
239
235
|
if (texts.length === 0) return [
|
|
240
236
|
2
|
|
241
237
|
];
|
|
242
|
-
|
|
238
|
+
franc = _require('franc-min').franc;
|
|
239
|
+
persisted = (_languageDistribution = (0, _distributionts.languageDistribution)(db)) !== null && _languageDistribution !== void 0 ? _languageDistribution : {};
|
|
243
240
|
merged = _object_spread({}, persisted);
|
|
244
241
|
_iteratorNormalCompletion = true, _didIteratorError = false, _iteratorError = undefined;
|
|
245
242
|
try {
|
|
246
243
|
for(_iterator = texts[Symbol.iterator](); !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true){
|
|
247
244
|
text = _step.value;
|
|
248
245
|
;
|
|
249
|
-
code = classify(text);
|
|
246
|
+
code = classify(franc, text);
|
|
250
247
|
if (code) merged[code] = ((_merged_code = merged[code]) !== null && _merged_code !== void 0 ? _merged_code : 0) + 1;
|
|
251
248
|
}
|
|
252
249
|
} catch (err) {
|
|
@@ -276,7 +273,7 @@ function checkLanguageFit(db, provider, texts) {
|
|
|
276
273
|
throw new _errorsts.SenseError('EMBED_MODEL_MISMATCH', "embed model ".concat(provider.id, " declares languages [").concat(provider.languages.join(', '), "], but ").concat(pct, "% of this tree's classified text is \"").concat(majorityLang, "\" (ISO 639-3), which is not among them; choose a model for this tree's languages: `sense init --model ...`, see the sense-setup skill or INTEGRATIONS.md"));
|
|
277
274
|
}
|
|
278
275
|
}
|
|
279
|
-
(0,
|
|
276
|
+
(0, _distributionts.saveLanguageDistribution)(db, merged);
|
|
280
277
|
return [
|
|
281
278
|
2
|
|
282
279
|
];
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/embed/langfit.ts"],"sourcesContent":["import
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/embed/langfit.ts"],"sourcesContent":["import Module from 'node:module';\nimport type { DatabaseSync } from 'node:sqlite';\nimport { SenseError } from '../errors.ts';\nimport { languageDistribution, saveLanguageDistribution } from './distribution.ts';\nimport { toIso3 } from './languages.ts';\nimport type { EmbedProvider } from './types.ts';\n\n// franc's own reliability floor is a handful of characters; this is a cheap upper bound, not a\n// per-chunk minimum -- a short chunk is simply more likely to come back 'und' (unclassified).\nconst SAMPLE_CHARS = 300;\n// A majority computed over a handful of chunks is noise, not a corpus signal; the decision rule\n// never fires below this many classified chunks, declared languages or not.\nconst MIN_CLASSIFIED = 10;\n\n// franc-min is a 148K static import; a top-level import put it on every command's module graph\n// regardless of whether the semantic path ran, shipped as the 0.17.0 regression. Deferred to a\n// synchronous require inside checkLanguageFit so only the embed path pays for it.\nconst _require = typeof require === 'undefined' ? Module.createRequire(import.meta.url) : require;\n\nfunction classify(franc: typeof import('franc-min')['franc'], text: string): string | undefined {\n const code = franc(text.slice(0, SAMPLE_CHARS));\n return code === 'und' ? undefined : code;\n}\n\n// Merges chunk texts into the persisted distribution; throws (without persisting) if the model\n// declares languages and a clear majority classified so far is not among them.\nexport async function checkLanguageFit(db: DatabaseSync, provider: EmbedProvider, texts: string[]): Promise<void> {\n if (texts.length === 0) return;\n const { franc } = _require('franc-min') as typeof import('franc-min');\n const persisted = languageDistribution(db) ?? {};\n const merged = { ...persisted };\n for (const text of texts) {\n const code = classify(franc, text);\n if (code) merged[code] = (merged[code] ?? 0) + 1;\n }\n\n const total = Object.values(merged).reduce((a, b) => a + b, 0);\n if (provider.languages && provider.languages.length > 0 && total >= MIN_CLASSIFIED) {\n const declared = new Set(provider.languages.map(toIso3));\n const [majorityLang, majorityCount] = Object.entries(merged).sort((a, b) => b[1] - a[1])[0];\n if (majorityCount / total >= 0.5 && !declared.has(majorityLang)) {\n const pct = Math.round((majorityCount / total) * 100);\n throw new SenseError(\n 'EMBED_MODEL_MISMATCH',\n `embed model ${provider.id} declares languages [${provider.languages.join(', ')}], but ${pct}% of this tree's classified text is \"${majorityLang}\" (ISO 639-3), which is not among them; choose a model for this tree's languages: \\`sense init --model ...\\`, see the sense-setup skill or INTEGRATIONS.md`\n );\n }\n }\n saveLanguageDistribution(db, merged);\n}\n"],"names":["checkLanguageFit","SAMPLE_CHARS","MIN_CLASSIFIED","_require","require","Module","createRequire","classify","franc","text","code","slice","undefined","db","provider","texts","languageDistribution","persisted","merged","total","declared","Object","majorityLang","majorityCount","pct","length","values","reduce","a","b","languages","Set","map","toIso3","entries","sort","has","Math","round","SenseError","id","join","saveLanguageDistribution"],"mappings":";;;;+BA0BsBA;;;eAAAA;;;iEA1BH;wBAEQ;8BACoC;2BACxC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAGvB,+FAA+F;AAC/F,8FAA8F;AAC9F,IAAMC,eAAe;AACrB,gGAAgG;AAChG,4EAA4E;AAC5E,IAAMC,iBAAiB;AAEvB,+FAA+F;AAC/F,+FAA+F;AAC/F,kFAAkF;AAClF,IAAMC,WAAW,OAAOC,YAAY,cAAcC,mBAAM,CAACC,aAAa,CAAC,uDAAmBF;AAE1F,SAASG,SAASC,KAA0C,EAAEC,IAAY;IACxE,IAAMC,OAAOF,MAAMC,KAAKE,KAAK,CAAC,GAAGV;IACjC,OAAOS,SAAS,QAAQE,YAAYF;AACtC;AAIO,SAAeV,iBAAiBa,EAAgB,EAAEC,QAAuB,EAAEC,KAAe;;YAG7EC,uBADVR,OACFS,WACAC,QACD,2BAAA,mBAAA,gBAAA,WAAA,OAAMT,MAEiBS,cADpBR,MAIFS,OAEEC,UACgCC,uBAA/BC,cAAcC,eAEbC;;YAdV,IAAIT,MAAMU,MAAM,KAAK,GAAG;;;YAChBjB,QAAUL,SAAS,aAAnBK;YACFS,aAAYD,wBAAAA,IAAAA,oCAAoB,EAACH,iBAArBG,mCAAAA,wBAA4B,CAAC;YACzCE,SAAS,mBAAKD;YACf,kCAAA,2BAAA;;gBAAL,IAAK,YAAcF,4BAAd,6BAAA,QAAA,yBAAA,iCAAqB;oBAAfN,OAAN;;oBACGC,OAAOH,SAASC,OAAOC;oBAC7B,IAAIC,MAAMQ,MAAM,CAACR,KAAK,GAAG,EAACQ,eAAAA,MAAM,CAACR,KAAK,cAAZQ,0BAAAA,eAAgB,KAAK;gBACjD;;gBAHK;gBAAA;;;yBAAA,6BAAA;wBAAA;;;wBAAA;8BAAA;;;;YAKCC,QAAQE,OAAOK,MAAM,CAACR,QAAQS,MAAM,CAAC,SAACC,GAAGC;uBAAMD,IAAIC;eAAG;YAC5D,IAAIf,SAASgB,SAAS,IAAIhB,SAASgB,SAAS,CAACL,MAAM,GAAG,KAAKN,SAASjB,gBAAgB;gBAC5EkB,WAAW,IAAIW,IAAIjB,SAASgB,SAAS,CAACE,GAAG,CAACC,mBAAM;gBAChBZ,yCAAAA,OAAOa,OAAO,CAAChB,QAAQiB,IAAI,CAAC,SAACP,GAAGC;2BAAMA,CAAC,CAAC,EAAE,GAAGD,CAAC,CAAC,EAAE;kBAAC,CAAC,EAAE,MAApFN,eAA+BD,0BAAjBE,gBAAiBF;gBACtC,IAAIE,gBAAgBJ,SAAS,OAAO,CAACC,SAASgB,GAAG,CAACd,eAAe;oBACzDE,MAAMa,KAAKC,KAAK,CAAC,AAACf,gBAAgBJ,QAAS;oBACjD,MAAM,IAAIoB,oBAAU,CAClB,wBACA,AAAC,eAAiDzB,OAAnCA,SAAS0B,EAAE,EAAC,yBAA8DhB,OAAvCV,SAASgB,SAAS,CAACW,IAAI,CAAC,OAAM,WAAoDnB,OAA3CE,KAAI,0CAAoD,OAAbF,cAAa;gBAErJ;YACF;YACAoB,IAAAA,wCAAwB,EAAC7B,IAAIK;;;;;IAC/B"}
|
package/dist/cjs/embed/static.js
CHANGED
|
@@ -9,8 +9,8 @@ Object.defineProperty(exports, "staticProvider", {
|
|
|
9
9
|
}
|
|
10
10
|
});
|
|
11
11
|
var _nodefs = require("node:fs");
|
|
12
|
+
var _nodemodule = /*#__PURE__*/ _interop_require_default(require("node:module"));
|
|
12
13
|
var _nodepath = require("node:path");
|
|
13
|
-
var _tokenizers = require("@huggingface/tokenizers");
|
|
14
14
|
var _errorsts = require("../errors.js");
|
|
15
15
|
var _storets = require("./store.js");
|
|
16
16
|
function _array_like_to_array(arr, len) {
|
|
@@ -47,6 +47,11 @@ function _async_to_generator(fn) {
|
|
|
47
47
|
});
|
|
48
48
|
};
|
|
49
49
|
}
|
|
50
|
+
function _interop_require_default(obj) {
|
|
51
|
+
return obj && obj.__esModule ? obj : {
|
|
52
|
+
default: obj
|
|
53
|
+
};
|
|
54
|
+
}
|
|
50
55
|
function _iterable_to_array_limit(arr, i) {
|
|
51
56
|
var _i = arr == null ? null : typeof Symbol !== "undefined" && arr[Symbol.iterator] || arr["@@iterator"];
|
|
52
57
|
if (_i == null) return;
|
|
@@ -185,9 +190,13 @@ function _unsupported_iterable_to_array(o, minLen) {
|
|
|
185
190
|
if (n === "Arguments" || /^(?:Ui|I)nt(?:8|16|32)(?:Clamped)?Array$/.test(n)) return _array_like_to_array(o, minLen);
|
|
186
191
|
}
|
|
187
192
|
var BATCH_CAP = 64;
|
|
193
|
+
// @huggingface/tokenizers is a 540K static import; a top-level import put it on every command's
|
|
194
|
+
// module graph regardless of whether the semantic path ran, shipped as the 0.17.0 regression.
|
|
195
|
+
// Deferred to a synchronous require inside staticProvider so only the embed path pays for it.
|
|
196
|
+
var _require = typeof require === 'undefined' ? _nodemodule.default.createRequire(require("url").pathToFileURL(__filename).toString()) : require;
|
|
188
197
|
function staticProvider(model) {
|
|
189
198
|
return _async_to_generator(function() {
|
|
190
|
-
var _ref, _tokenizerJson_model, _tokenizerJson_model_vocab, _tokenizerJson_model1, dir, languages, cached, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, file, raw, headerLen, header, entry, spec, dims, dataStart, matrix, tokenizerJson, tok, unkId;
|
|
199
|
+
var _ref, _tokenizerJson_model, _tokenizerJson_model_vocab, _tokenizerJson_model1, dir, languages, cached, _iteratorNormalCompletion, _didIteratorError, _iteratorError, _iterator, _step, file, raw, headerLen, header, entry, spec, dims, dataStart, matrix, tokenizerJson, Tokenizer, tok, unkId;
|
|
191
200
|
function one(text) {
|
|
192
201
|
// The tokenizer yields undefined (not the unk id) for tokens outside the vocab; an
|
|
193
202
|
// undefined id would index the matrix at NaN and poison the whole mean-pool -- and the
|
|
@@ -291,7 +300,8 @@ function staticProvider(model) {
|
|
|
291
300
|
dataStart = raw.byteOffset + 8 + headerLen + spec.data_offsets[0];
|
|
292
301
|
matrix = dataStart % 4 === 0 ? new Float32Array(raw.buffer, dataStart, spec.shape[0] * dims) : new Float32Array(raw.buffer.slice(dataStart, dataStart + spec.shape[0] * dims * 4));
|
|
293
302
|
tokenizerJson = JSON.parse((0, _nodefs.readFileSync)((0, _nodepath.join)(dir, 'tokenizer.json'), 'utf8'));
|
|
294
|
-
|
|
303
|
+
Tokenizer = _require('@huggingface/tokenizers').Tokenizer;
|
|
304
|
+
tok = new Tokenizer(tokenizerJson, {});
|
|
295
305
|
unkId = (_ref = (_tokenizerJson_model1 = tokenizerJson.model) === null || _tokenizerJson_model1 === void 0 ? void 0 : (_tokenizerJson_model_vocab = _tokenizerJson_model1.vocab) === null || _tokenizerJson_model_vocab === void 0 ? void 0 : _tokenizerJson_model_vocab[(_tokenizerJson_model = tokenizerJson.model) === null || _tokenizerJson_model === void 0 ? void 0 : _tokenizerJson_model.unk_token]) !== null && _ref !== void 0 ? _ref : -1;
|
|
296
306
|
// Symmetric model: document and query embedding are the same call.
|
|
297
307
|
return [
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/embed/static.ts"],"sourcesContent":["import { existsSync, readFileSync } from 'node:fs';\nimport
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/embed/static.ts"],"sourcesContent":["import { existsSync, readFileSync } from 'node:fs';\nimport Module from 'node:module';\nimport { join } from 'node:path';\nimport { SenseError } from '../errors.ts';\nimport { downloadModel, isDownloadable, MODEL_FILENAMES, MODEL_FILES, modelDir, readLanguages } from './store.ts';\nimport type { EmbedProvider } from './types.ts';\n\nconst BATCH_CAP = 64;\n\n// @huggingface/tokenizers is a 540K static import; a top-level import put it on every command's\n// module graph regardless of whether the semantic path ran, shipped as the 0.17.0 regression.\n// Deferred to a synchronous require inside staticProvider so only the embed path pays for it.\nconst _require = typeof require === 'undefined' ? Module.createRequire(import.meta.url) : require;\n\n// Model2Vec safetensors + pure-JS tokenizer. Encode convention from model2vec/model.py: no\n// special tokens, drop unk ids, mean-pool, L2-normalize.\nexport async function staticProvider(model: string): Promise<EmbedProvider> {\n let dir: string;\n let languages: string[] | undefined;\n if (isDownloadable(model)) {\n // Naming a HF id is consent: fetch whatever is missing now, announcing it on stderr.\n dir = await downloadModel(model, (file, into) => console.error(`sense: fetching ${model}/${file} into ${into}`));\n // Cached beside the repo; a local model directory has no card to read, so it has none.\n const cached = readLanguages(model);\n languages = cached && cached.length > 0 ? cached : undefined;\n } else {\n dir = modelDir(model);\n for (const file of MODEL_FILES) {\n if (!existsSync(join(dir, file))) {\n throw new SenseError('EMBED_MODEL_MISSING', `embed model ${model} is not available (looked in ${dir}); expected ${MODEL_FILENAMES} in that directory`);\n }\n }\n }\n\n const raw = readFileSync(join(dir, 'model.safetensors'));\n const headerLen = Number(raw.readBigUInt64LE(0));\n const header = JSON.parse(raw.subarray(8, 8 + headerLen).toString('utf8')) as Record<string, { dtype: string; shape: number[]; data_offsets: number[] }>;\n const entry = Object.entries(header).find(([k]) => k !== '__metadata__');\n if (!entry || entry[1].dtype !== 'F32') throw new SenseError('EMBED_MODEL', `${model}: expected an F32 safetensors matrix`);\n const spec = entry[1];\n const dims = spec.shape[1];\n const dataStart = raw.byteOffset + 8 + headerLen + spec.data_offsets[0];\n const matrix = dataStart % 4 === 0 ? new Float32Array(raw.buffer, dataStart, spec.shape[0] * dims) : new Float32Array(raw.buffer.slice(dataStart, dataStart + spec.shape[0] * dims * 4));\n\n const tokenizerJson = JSON.parse(readFileSync(join(dir, 'tokenizer.json'), 'utf8'));\n const { Tokenizer } = _require('@huggingface/tokenizers') as typeof import('@huggingface/tokenizers');\n const tok = new Tokenizer(tokenizerJson, {});\n const unkId = tokenizerJson.model?.vocab?.[tokenizerJson.model?.unk_token] ?? -1;\n\n function one(text: string): Float32Array {\n // The tokenizer yields undefined (not the unk id) for tokens outside the vocab; an\n // undefined id would index the matrix at NaN and poison the whole mean-pool -- and the\n // int8 conversion then stores the NaN vector as all zeros, silently. Keep integers only.\n const ids = (tok.encode(text, { add_special_tokens: false }).ids as number[]).filter((id) => Number.isInteger(id) && id !== unkId);\n const v = new Float32Array(dims);\n if (ids.length === 0) return v;\n for (const id of ids) {\n const off = id * dims;\n for (let d = 0; d < dims; d++) v[d] += matrix[off + d];\n }\n let norm = 0;\n for (let d = 0; d < dims; d++) {\n v[d] /= ids.length;\n norm += v[d] * v[d];\n }\n norm = Math.sqrt(norm) + 1e-32;\n for (let d = 0; d < dims; d++) v[d] /= norm;\n return v;\n }\n\n // Symmetric model: document and query embedding are the same call.\n return { id: `static:${model}`, dims, batchCap: BATCH_CAP, languages, embedDocuments: async (texts) => texts.map(one), embedQuery: async (text) => one(text) };\n}\n"],"names":["staticProvider","BATCH_CAP","_require","require","Module","createRequire","model","tokenizerJson","dir","languages","cached","file","raw","headerLen","header","entry","spec","dims","dataStart","matrix","Tokenizer","tok","unkId","one","text","ids","encode","add_special_tokens","filter","id","Number","isInteger","v","Float32Array","length","off","d","norm","Math","sqrt","isDownloadable","downloadModel","into","console","error","readLanguages","undefined","modelDir","MODEL_FILES","existsSync","join","SenseError","MODEL_FILENAMES","readFileSync","readBigUInt64LE","JSON","parse","subarray","toString","Object","entries","find","k","dtype","shape","byteOffset","data_offsets","buffer","slice","vocab","unk_token","batchCap","embedDocuments","texts","map","embedQuery"],"mappings":"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"}
|
package/dist/esm/cli/map.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { mapTree } from '../commands/
|
|
1
|
+
import { mapTree } from '../commands/map.js';
|
|
2
2
|
import { renderMap } from '../output/output.js';
|
|
3
3
|
import { USAGE } from './index.js';
|
|
4
4
|
import { CONFIG, FORMAT, formatOf, parse, SCOPE, scopeOf, withDb } from './shared.js';
|
package/dist/esm/cli/map.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/map.ts"],"sourcesContent":["import { mapTree } from '../commands/
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/map.ts"],"sourcesContent":["import { mapTree } from '../commands/map.ts';\nimport { renderMap } from '../output/output.ts';\nimport { USAGE } from './index.ts';\nimport { CONFIG, FORMAT, formatOf, parse, SCOPE, scopeOf, withDb } from './shared.ts';\nimport type { Command } from './types.ts';\n\nconst map: Command = (ctx) => {\n const { values } = parse(ctx.argv, `usage: ${ctx.name} ${USAGE.map}`, { ...SCOPE, ...FORMAT, ...CONFIG });\n const format = formatOf(values);\n return withDb(ctx, values.config as string | undefined, (db, cfg) => {\n const result = mapTree(db, cfg, scopeOf(values));\n console.log(format === 'json' ? JSON.stringify(result, null, 2) : renderMap(result));\n });\n};\nexport default map;\n"],"names":["mapTree","renderMap","USAGE","CONFIG","FORMAT","formatOf","parse","SCOPE","scopeOf","withDb","map","ctx","values","argv","name","format","config","db","cfg","result","console","log","JSON","stringify"],"mappings":"AAAA,SAASA,OAAO,QAAQ,qBAAqB;AAC7C,SAASC,SAAS,QAAQ,sBAAsB;AAChD,SAASC,KAAK,QAAQ,aAAa;AACnC,SAASC,MAAM,EAAEC,MAAM,EAAEC,QAAQ,EAAEC,KAAK,EAAEC,KAAK,EAAEC,OAAO,EAAEC,MAAM,QAAQ,cAAc;AAGtF,MAAMC,MAAe,CAACC;IACpB,MAAM,EAAEC,MAAM,EAAE,GAAGN,MAAMK,IAAIE,IAAI,EAAE,CAAC,OAAO,EAAEF,IAAIG,IAAI,CAAC,CAAC,EAAEZ,MAAMQ,GAAG,EAAE,EAAE;QAAE,GAAGH,KAAK;QAAE,GAAGH,MAAM;QAAE,GAAGD,MAAM;IAAC;IACvG,MAAMY,SAASV,SAASO;IACxB,OAAOH,OAAOE,KAAKC,OAAOI,MAAM,EAAwB,CAACC,IAAIC;QAC3D,MAAMC,SAASnB,QAAQiB,IAAIC,KAAKV,QAAQI;QACxCQ,QAAQC,GAAG,CAACN,WAAW,SAASO,KAAKC,SAAS,CAACJ,QAAQ,MAAM,KAAKlB,UAAUkB;IAC9E;AACF;AACA,eAAeT,IAAI"}
|
package/dist/esm/cli/named.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { search } from '../commands/
|
|
1
|
+
import { search } from '../commands/search.js';
|
|
2
2
|
import { printRows } from '../output/output.js';
|
|
3
3
|
import { CONFIG, FORMAT, parse, parseK, rowFormatOf, runSql, SEARCH_FLAGS, withDb } from './shared.js';
|
|
4
4
|
// Fallback when the first positional is not a command: a saved query, { sql } or { search }.
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/named.ts"],"sourcesContent":["import { search } from '../commands/
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/named.ts"],"sourcesContent":["import { search } from '../commands/search.ts';\nimport { printRows } from '../output/output.ts';\nimport { CONFIG, FORMAT, parse, parseK, rowFormatOf, runSql, SEARCH_FLAGS, withDb } from './shared.ts';\nimport type { Ctx } from './types.ts';\n\n// Fallback when the first positional is not a command: a saved query, { sql } or { search }.\n// SEARCH_FLAGS override a saved search's fields the same way they override a preset's.\nexport default async function named(ctx: Ctx, queryName: string): Promise<void> {\n const usage = `usage: ${ctx.name} ${queryName} [params...] [--format table|json|csv] [--config path] [--where \"<sql>\"] [--k n] [--preset name] [--include glob ...] [--exclude glob ...] [--no-exclude]`;\n const { values, positionals: params } = parse(ctx.argv, usage, { ...SEARCH_FLAGS, ...FORMAT, ...CONFIG });\n const format = rowFormatOf(values);\n const configPath = values.config as string | undefined;\n\n const cfg = ctx.resolveConfig(configPath);\n const entry = cfg.queries[queryName];\n if (entry === undefined) {\n console.error(`unknown command or saved entry: \"${queryName}\"`);\n console.error(`saved queries: ${Object.keys(cfg.queries).sort().join(', ')}`);\n process.exit(2);\n }\n\n if ('sql' in entry) {\n // A saved statement written against `scope` is preset-agnostic, so the same entry can be\n // re-pointed at another layer from the command line instead of being copied per preset.\n runSql(cfg, entry.sql, params, format, `query \"${queryName}\"`, values.preset as string | undefined);\n return;\n }\n\n // A saved search's text is fixed in config; there is nowhere for a positional to bind.\n if (params.length > 0) {\n ctx.usageError(`\"${queryName}\" is a saved search and takes no positional parameters; edit its \"search\" in sense.config.json, or use \"${ctx.name} search\" directly`);\n }\n const k = parseK(values.k as string | undefined, ctx.usageError) ?? entry.k;\n const where = (values.where as string | undefined) ?? entry.where;\n const preset = (values.preset as string | undefined) ?? entry.preset;\n const include = (values.include as string[] | undefined) ?? entry.include;\n const exclude = (values.exclude as string[] | undefined) ?? entry.exclude;\n const noExclude = values['no-exclude'] === true;\n await withDb(ctx, configPath, async (db, resolvedCfg) => printRows(await search(db, resolvedCfg, entry.search, { k, where, preset, include, exclude, noExclude }), format));\n}\n"],"names":["search","printRows","CONFIG","FORMAT","parse","parseK","rowFormatOf","runSql","SEARCH_FLAGS","withDb","named","ctx","queryName","values","usage","name","positionals","params","argv","format","configPath","config","cfg","resolveConfig","entry","queries","undefined","console","error","Object","keys","sort","join","process","exit","sql","preset","length","usageError","k","where","include","exclude","noExclude","db","resolvedCfg"],"mappings":"AAAA,SAASA,MAAM,QAAQ,wBAAwB;AAC/C,SAASC,SAAS,QAAQ,sBAAsB;AAChD,SAASC,MAAM,EAAEC,MAAM,EAAEC,KAAK,EAAEC,MAAM,EAAEC,WAAW,EAAEC,MAAM,EAAEC,YAAY,EAAEC,MAAM,QAAQ,cAAc;AAGvG,6FAA6F;AAC7F,uFAAuF;AACvF,eAAe,eAAeC,MAAMC,GAAQ,EAAEC,SAAiB;QAyBnDP,SACKQ,eACCA,gBACCA,iBACAA;IA5BjB,MAAMC,QAAQ,CAAC,OAAO,EAAEH,IAAII,IAAI,CAAC,CAAC,EAAEH,UAAU,yJAAyJ,CAAC;IACxM,MAAM,EAAEC,MAAM,EAAEG,aAAaC,MAAM,EAAE,GAAGb,MAAMO,IAAIO,IAAI,EAAEJ,OAAO;QAAE,GAAGN,YAAY;QAAE,GAAGL,MAAM;QAAE,GAAGD,MAAM;IAAC;IACvG,MAAMiB,SAASb,YAAYO;IAC3B,MAAMO,aAAaP,OAAOQ,MAAM;IAEhC,MAAMC,MAAMX,IAAIY,aAAa,CAACH;IAC9B,MAAMI,QAAQF,IAAIG,OAAO,CAACb,UAAU;IACpC,IAAIY,UAAUE,WAAW;QACvBC,QAAQC,KAAK,CAAC,CAAC,iCAAiC,EAAEhB,UAAU,CAAC,CAAC;QAC9De,QAAQC,KAAK,CAAC,CAAC,eAAe,EAAEC,OAAOC,IAAI,CAACR,IAAIG,OAAO,EAAEM,IAAI,GAAGC,IAAI,CAAC,OAAO;QAC5EC,QAAQC,IAAI,CAAC;IACf;IAEA,IAAI,SAASV,OAAO;QAClB,yFAAyF;QACzF,wFAAwF;QACxFjB,OAAOe,KAAKE,MAAMW,GAAG,EAAElB,QAAQE,QAAQ,CAAC,OAAO,EAAEP,UAAU,CAAC,CAAC,EAAEC,OAAOuB,MAAM;QAC5E;IACF;IAEA,uFAAuF;IACvF,IAAInB,OAAOoB,MAAM,GAAG,GAAG;QACrB1B,IAAI2B,UAAU,CAAC,CAAC,CAAC,EAAE1B,UAAU,wGAAwG,EAAED,IAAII,IAAI,CAAC,iBAAiB,CAAC;IACpK;IACA,MAAMwB,KAAIlC,UAAAA,OAAOQ,OAAO0B,CAAC,EAAwB5B,IAAI2B,UAAU,eAArDjC,qBAAAA,UAA0DmB,MAAMe,CAAC;IAC3E,MAAMC,SAAS3B,gBAAAA,OAAO2B,KAAK,cAAZ3B,2BAAAA,gBAAuCW,MAAMgB,KAAK;IACjE,MAAMJ,UAAUvB,iBAAAA,OAAOuB,MAAM,cAAbvB,4BAAAA,iBAAwCW,MAAMY,MAAM;IACpE,MAAMK,WAAW5B,kBAAAA,OAAO4B,OAAO,cAAd5B,6BAAAA,kBAA2CW,MAAMiB,OAAO;IACzE,MAAMC,WAAW7B,kBAAAA,OAAO6B,OAAO,cAAd7B,6BAAAA,kBAA2CW,MAAMkB,OAAO;IACzE,MAAMC,YAAY9B,MAAM,CAAC,aAAa,KAAK;IAC3C,MAAMJ,OAAOE,KAAKS,YAAY,OAAOwB,IAAIC,cAAgB5C,UAAU,MAAMD,OAAO4C,IAAIC,aAAarB,MAAMxB,MAAM,EAAE;YAAEuC;YAAGC;YAAOJ;YAAQK;YAASC;YAASC;QAAU,IAAIxB;AACrK"}
|
package/dist/esm/cli/path.js
CHANGED
|
@@ -1,4 +1,5 @@
|
|
|
1
|
-
import { resolveNote
|
|
1
|
+
import { resolveNote } from '../commands/peek.js';
|
|
2
|
+
import { scopedPaths } from '../commands/scope.js';
|
|
2
3
|
import { findPath } from '../graph/traverse.js';
|
|
3
4
|
import { printRows } from '../output/output.js';
|
|
4
5
|
import { USAGE } from './index.js';
|
package/dist/esm/cli/path.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/path.ts"],"sourcesContent":["import { resolveNote
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/path.ts"],"sourcesContent":["import { resolveNote } from '../commands/peek.ts';\nimport { scopedPaths } from '../commands/scope.ts';\nimport { findPath } from '../graph/traverse.ts';\nimport type { Row } from '../output/output.ts';\nimport { printRows } from '../output/output.ts';\nimport { USAGE } from './index.ts';\nimport { CONFIG, FORMAT, formatOf, parse, SCOPE, scopeOf, withDb } from './shared.ts';\nimport type { Command } from './types.ts';\n\n// --max-depth must be a positive integer, mirroring shared.ts's parseK.\nfunction parseMaxDepth(depth: string | undefined, usageError: (message: string) => never): number | undefined {\n if (depth === undefined) return undefined;\n const parsed = Number(depth);\n if (!Number.isInteger(parsed) || parsed <= 0) usageError(`--max-depth expects a positive integer, got \"${depth}\"`);\n return parsed;\n}\n\nconst pathCmd: Command = (ctx) => {\n const usage = `usage: ${ctx.name} ${USAGE.path}`;\n const { values, positionals } = parse(ctx.argv, usage, { ...SCOPE, ...FORMAT, ...CONFIG, 'max-depth': { type: 'string' } });\n const [a, b] = positionals;\n if (!a || !b) ctx.usageError(usage);\n const maxDepth = parseMaxDepth(values['max-depth'] as string | undefined, ctx.usageError);\n const format = formatOf(values);\n return withDb(ctx, values.config as string | undefined, (db, cfg) => {\n const paths = (db.prepare('SELECT \"path\" FROM frontmatter').all() as Array<{ path: string }>).map((r) => r.path);\n const from = resolveNote(paths, a);\n const to = resolveNote(paths, b);\n const allowed = scopedPaths(db, cfg, scopeOf(values));\n const hops = findPath(db, from, to, { maxDepth, allowed });\n\n if (format === 'json') {\n console.log(JSON.stringify(hops));\n return;\n }\n if (hops === null) {\n console.log(maxDepth ? `no path within ${maxDepth} hops` : 'no path');\n return;\n }\n const rows: Row[] = hops.map((p, step) => ({ step, path: p }));\n printRows(rows, format);\n });\n};\nexport default pathCmd;\n"],"names":["resolveNote","scopedPaths","findPath","printRows","USAGE","CONFIG","FORMAT","formatOf","parse","SCOPE","scopeOf","withDb","parseMaxDepth","depth","usageError","undefined","parsed","Number","isInteger","pathCmd","ctx","usage","name","path","values","positionals","argv","type","a","b","maxDepth","format","config","db","cfg","paths","prepare","all","map","r","from","to","allowed","hops","console","log","JSON","stringify","rows","p","step"],"mappings":"AAAA,SAASA,WAAW,QAAQ,sBAAsB;AAClD,SAASC,WAAW,QAAQ,uBAAuB;AACnD,SAASC,QAAQ,QAAQ,uBAAuB;AAEhD,SAASC,SAAS,QAAQ,sBAAsB;AAChD,SAASC,KAAK,QAAQ,aAAa;AACnC,SAASC,MAAM,EAAEC,MAAM,EAAEC,QAAQ,EAAEC,KAAK,EAAEC,KAAK,EAAEC,OAAO,EAAEC,MAAM,QAAQ,cAAc;AAGtF,wEAAwE;AACxE,SAASC,cAAcC,KAAyB,EAAEC,UAAsC;IACtF,IAAID,UAAUE,WAAW,OAAOA;IAChC,MAAMC,SAASC,OAAOJ;IACtB,IAAI,CAACI,OAAOC,SAAS,CAACF,WAAWA,UAAU,GAAGF,WAAW,CAAC,6CAA6C,EAAED,MAAM,CAAC,CAAC;IACjH,OAAOG;AACT;AAEA,MAAMG,UAAmB,CAACC;IACxB,MAAMC,QAAQ,CAAC,OAAO,EAAED,IAAIE,IAAI,CAAC,CAAC,EAAElB,MAAMmB,IAAI,EAAE;IAChD,MAAM,EAAEC,MAAM,EAAEC,WAAW,EAAE,GAAGjB,MAAMY,IAAIM,IAAI,EAAEL,OAAO;QAAE,GAAGZ,KAAK;QAAE,GAAGH,MAAM;QAAE,GAAGD,MAAM;QAAE,aAAa;YAAEsB,MAAM;QAAS;IAAE;IACzH,MAAM,CAACC,GAAGC,EAAE,GAAGJ;IACf,IAAI,CAACG,KAAK,CAACC,GAAGT,IAAIN,UAAU,CAACO;IAC7B,MAAMS,WAAWlB,cAAcY,MAAM,CAAC,YAAY,EAAwBJ,IAAIN,UAAU;IACxF,MAAMiB,SAASxB,SAASiB;IACxB,OAAOb,OAAOS,KAAKI,OAAOQ,MAAM,EAAwB,CAACC,IAAIC;QAC3D,MAAMC,QAAQ,AAACF,GAAGG,OAAO,CAAC,kCAAkCC,GAAG,GAA+BC,GAAG,CAAC,CAACC,IAAMA,EAAEhB,IAAI;QAC/G,MAAMiB,OAAOxC,YAAYmC,OAAOP;QAChC,MAAMa,KAAKzC,YAAYmC,OAAON;QAC9B,MAAMa,UAAUzC,YAAYgC,IAAIC,KAAKxB,QAAQc;QAC7C,MAAMmB,OAAOzC,SAAS+B,IAAIO,MAAMC,IAAI;YAAEX;YAAUY;QAAQ;QAExD,IAAIX,WAAW,QAAQ;YACrBa,QAAQC,GAAG,CAACC,KAAKC,SAAS,CAACJ;YAC3B;QACF;QACA,IAAIA,SAAS,MAAM;YACjBC,QAAQC,GAAG,CAACf,WAAW,CAAC,eAAe,EAAEA,SAAS,KAAK,CAAC,GAAG;YAC3D;QACF;QACA,MAAMkB,OAAcL,KAAKL,GAAG,CAAC,CAACW,GAAGC,OAAU,CAAA;gBAAEA;gBAAM3B,MAAM0B;YAAE,CAAA;QAC3D9C,UAAU6C,MAAMjB;IAClB;AACF;AACA,eAAeZ,QAAQ"}
|
package/dist/esm/cli/peek.js
CHANGED
package/dist/esm/cli/peek.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/peek.ts"],"sourcesContent":["import { peek } from '../commands/
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/peek.ts"],"sourcesContent":["import { peek } from '../commands/peek.ts';\nimport { renderPeek } from '../output/output.ts';\nimport { USAGE } from './index.ts';\nimport { CONFIG, FORMAT, formatOf, parse, SCOPE, scopeOf, withDb } from './shared.ts';\nimport type { Command } from './types.ts';\n\nconst peekCmd: Command = (ctx) => {\n const usage = `usage: ${ctx.name} ${USAGE.peek}`;\n const { values, positionals } = parse(ctx.argv, usage, { ...SCOPE, ...FORMAT, ...CONFIG });\n const [pathArg] = positionals;\n if (!pathArg) ctx.usageError(usage);\n const format = formatOf(values);\n return withDb(ctx, values.config as string | undefined, (db, cfg) => {\n const overrides = scopeOf(values);\n const result = peek(db, cfg, pathArg, overrides);\n console.log(format === 'json' ? JSON.stringify(result, null, 2) : renderPeek(result));\n });\n};\nexport default peekCmd;\n"],"names":["peek","renderPeek","USAGE","CONFIG","FORMAT","formatOf","parse","SCOPE","scopeOf","withDb","peekCmd","ctx","usage","name","values","positionals","argv","pathArg","usageError","format","config","db","cfg","overrides","result","console","log","JSON","stringify"],"mappings":"AAAA,SAASA,IAAI,QAAQ,sBAAsB;AAC3C,SAASC,UAAU,QAAQ,sBAAsB;AACjD,SAASC,KAAK,QAAQ,aAAa;AACnC,SAASC,MAAM,EAAEC,MAAM,EAAEC,QAAQ,EAAEC,KAAK,EAAEC,KAAK,EAAEC,OAAO,EAAEC,MAAM,QAAQ,cAAc;AAGtF,MAAMC,UAAmB,CAACC;IACxB,MAAMC,QAAQ,CAAC,OAAO,EAAED,IAAIE,IAAI,CAAC,CAAC,EAAEX,MAAMF,IAAI,EAAE;IAChD,MAAM,EAAEc,MAAM,EAAEC,WAAW,EAAE,GAAGT,MAAMK,IAAIK,IAAI,EAAEJ,OAAO;QAAE,GAAGL,KAAK;QAAE,GAAGH,MAAM;QAAE,GAAGD,MAAM;IAAC;IACxF,MAAM,CAACc,QAAQ,GAAGF;IAClB,IAAI,CAACE,SAASN,IAAIO,UAAU,CAACN;IAC7B,MAAMO,SAASd,SAASS;IACxB,OAAOL,OAAOE,KAAKG,OAAOM,MAAM,EAAwB,CAACC,IAAIC;QAC3D,MAAMC,YAAYf,QAAQM;QAC1B,MAAMU,SAASxB,KAAKqB,IAAIC,KAAKL,SAASM;QACtCE,QAAQC,GAAG,CAACP,WAAW,SAASQ,KAAKC,SAAS,CAACJ,QAAQ,MAAM,KAAKvB,WAAWuB;IAC/E;AACF;AACA,eAAed,QAAQ"}
|
package/dist/esm/cli/related.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { relatedNotes } from '../commands/
|
|
1
|
+
import { relatedNotes } from '../commands/related.js';
|
|
2
2
|
import { printRows } from '../output/output.js';
|
|
3
3
|
import { USAGE } from './index.js';
|
|
4
4
|
import { CONFIG, FORMAT, parse, parseK, rowFormatOf, SCOPE, scopeOf, withDb } from './shared.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/related.ts"],"sourcesContent":["import { relatedNotes } from '../commands/
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/related.ts"],"sourcesContent":["import { relatedNotes } from '../commands/related.ts';\nimport type { Row } from '../output/output.ts';\nimport { printRows } from '../output/output.ts';\nimport { USAGE } from './index.ts';\nimport { CONFIG, FORMAT, parse, parseK, rowFormatOf, SCOPE, scopeOf, withDb } from './shared.ts';\nimport type { Command } from './types.ts';\n\nconst RELATED_DEFAULT_K = 5;\n\nconst relatedCmd: Command = (ctx) => {\n const usage = `usage: ${ctx.name} ${USAGE.related}`;\n const { values, positionals } = parse(ctx.argv, usage, { ...SCOPE, ...FORMAT, ...CONFIG, k: { type: 'string' } });\n const [pathArg] = positionals;\n if (!pathArg) ctx.usageError(usage);\n const k = parseK(values.k as string | undefined, ctx.usageError) ?? RELATED_DEFAULT_K;\n const format = rowFormatOf(values);\n return withDb(ctx, values.config as string | undefined, async (db, cfg) => {\n const overrides = scopeOf(values);\n printRows((await relatedNotes(db, cfg, pathArg, overrides, k)) as Row[], format);\n });\n};\nexport default relatedCmd;\n"],"names":["relatedNotes","printRows","USAGE","CONFIG","FORMAT","parse","parseK","rowFormatOf","SCOPE","scopeOf","withDb","RELATED_DEFAULT_K","relatedCmd","ctx","usage","name","related","values","positionals","argv","k","type","pathArg","usageError","format","config","db","cfg","overrides"],"mappings":"AAAA,SAASA,YAAY,QAAQ,yBAAyB;AAEtD,SAASC,SAAS,QAAQ,sBAAsB;AAChD,SAASC,KAAK,QAAQ,aAAa;AACnC,SAASC,MAAM,EAAEC,MAAM,EAAEC,KAAK,EAAEC,MAAM,EAAEC,WAAW,EAAEC,KAAK,EAAEC,OAAO,EAAEC,MAAM,QAAQ,cAAc;AAGjG,MAAMC,oBAAoB;AAE1B,MAAMC,aAAsB,CAACC;QAKjBP;IAJV,MAAMQ,QAAQ,CAAC,OAAO,EAAED,IAAIE,IAAI,CAAC,CAAC,EAAEb,MAAMc,OAAO,EAAE;IACnD,MAAM,EAAEC,MAAM,EAAEC,WAAW,EAAE,GAAGb,MAAMQ,IAAIM,IAAI,EAAEL,OAAO;QAAE,GAAGN,KAAK;QAAE,GAAGJ,MAAM;QAAE,GAAGD,MAAM;QAAEiB,GAAG;YAAEC,MAAM;QAAS;IAAE;IAC/G,MAAM,CAACC,QAAQ,GAAGJ;IAClB,IAAI,CAACI,SAAST,IAAIU,UAAU,CAACT;IAC7B,MAAMM,KAAId,UAAAA,OAAOW,OAAOG,CAAC,EAAwBP,IAAIU,UAAU,eAArDjB,qBAAAA,UAA0DK;IACpE,MAAMa,SAASjB,YAAYU;IAC3B,OAAOP,OAAOG,KAAKI,OAAOQ,MAAM,EAAwB,OAAOC,IAAIC;QACjE,MAAMC,YAAYnB,QAAQQ;QAC1BhB,UAAW,MAAMD,aAAa0B,IAAIC,KAAKL,SAASM,WAAWR,IAAcI;IAC3E;AACF;AACA,eAAeZ,WAAW"}
|
package/dist/esm/cli/search.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { search } from '../commands/
|
|
1
|
+
import { search } from '../commands/search.js';
|
|
2
2
|
import { printRows } from '../output/output.js';
|
|
3
3
|
import { USAGE } from './index.js';
|
|
4
4
|
import { CONFIG, FORMAT, parse, parseK, rowFormatOf, SEARCH_FLAGS, scopeOf, withDb } from './shared.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/search.ts"],"sourcesContent":["import { search } from '../commands/
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/search.ts"],"sourcesContent":["import { search } from '../commands/search.ts';\nimport { printRows } from '../output/output.ts';\nimport { USAGE } from './index.ts';\nimport { CONFIG, FORMAT, parse, parseK, rowFormatOf, SEARCH_FLAGS, scopeOf, withDb } from './shared.ts';\nimport type { Command } from './types.ts';\n\nconst searchCmd: Command = async (ctx) => {\n const usage = `usage: ${ctx.name} ${USAGE.search}`;\n const { values, positionals } = parse(ctx.argv, usage, { ...SEARCH_FLAGS, ...FORMAT, ...CONFIG });\n const [terms] = positionals;\n if (!terms) ctx.usageError(usage);\n const k = parseK(values.k as string | undefined, ctx.usageError);\n const format = rowFormatOf(values);\n await withDb(ctx, values.config as string | undefined, async (db, cfg) => printRows(await search(db, cfg, terms, { k, ...scopeOf(values) }), format));\n};\nexport default searchCmd;\n"],"names":["search","printRows","USAGE","CONFIG","FORMAT","parse","parseK","rowFormatOf","SEARCH_FLAGS","scopeOf","withDb","searchCmd","ctx","usage","name","values","positionals","argv","terms","usageError","k","format","config","db","cfg"],"mappings":"AAAA,SAASA,MAAM,QAAQ,wBAAwB;AAC/C,SAASC,SAAS,QAAQ,sBAAsB;AAChD,SAASC,KAAK,QAAQ,aAAa;AACnC,SAASC,MAAM,EAAEC,MAAM,EAAEC,KAAK,EAAEC,MAAM,EAAEC,WAAW,EAAEC,YAAY,EAAEC,OAAO,EAAEC,MAAM,QAAQ,cAAc;AAGxG,MAAMC,YAAqB,OAAOC;IAChC,MAAMC,QAAQ,CAAC,OAAO,EAAED,IAAIE,IAAI,CAAC,CAAC,EAAEZ,MAAMF,MAAM,EAAE;IAClD,MAAM,EAAEe,MAAM,EAAEC,WAAW,EAAE,GAAGX,MAAMO,IAAIK,IAAI,EAAEJ,OAAO;QAAE,GAAGL,YAAY;QAAE,GAAGJ,MAAM;QAAE,GAAGD,MAAM;IAAC;IAC/F,MAAM,CAACe,MAAM,GAAGF;IAChB,IAAI,CAACE,OAAON,IAAIO,UAAU,CAACN;IAC3B,MAAMO,IAAId,OAAOS,OAAOK,CAAC,EAAwBR,IAAIO,UAAU;IAC/D,MAAME,SAASd,YAAYQ;IAC3B,MAAML,OAAOE,KAAKG,OAAOO,MAAM,EAAwB,OAAOC,IAAIC,MAAQvB,UAAU,MAAMD,OAAOuB,IAAIC,KAAKN,OAAO;YAAEE;YAAG,GAAGX,QAAQM,OAAO;QAAC,IAAIM;AAC/I;AACA,eAAeV,UAAU"}
|
package/dist/esm/cli/status.js
CHANGED
|
@@ -1,9 +1,9 @@
|
|
|
1
1
|
import { dirname } from 'node:path';
|
|
2
|
-
import { presetCoverage } from '../commands/
|
|
2
|
+
import { presetCoverage } from '../commands/status.js';
|
|
3
3
|
import { embedConfig, featureStates, SUPPORTED_CONFIG_VERSION } from '../config/index.js';
|
|
4
4
|
import { docCount, getMeta, open, SCHEMA_VERSION } from '../db/index.js';
|
|
5
|
+
import { languageDistribution } from '../embed/distribution.js';
|
|
5
6
|
import { probeReachable } from '../embed/http.js';
|
|
6
|
-
import { languageDistribution } from '../embed/langfit.js';
|
|
7
7
|
import { isDownloadable, MODEL_FILENAMES, modelDir, modelPresent, readLanguages } from '../embed/store.js';
|
|
8
8
|
import { featuresLine, presetsLines } from '../output/output.js';
|
|
9
9
|
import { USAGE } from './index.js';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/status.ts"],"sourcesContent":["import { dirname } from 'node:path';\nimport { presetCoverage } from '../commands/index.ts';\nimport { embedConfig, featureStates, SUPPORTED_CONFIG_VERSION } from '../config/index.ts';\nimport { docCount, getMeta, open, SCHEMA_VERSION } from '../db/index.ts';\nimport { probeReachable } from '../embed/http.ts';\nimport { languageDistribution } from '../embed/langfit.ts';\nimport { isDownloadable, MODEL_FILENAMES, modelDir, modelPresent, readLanguages } from '../embed/store.ts';\nimport { featuresLine, presetsLines } from '../output/output.ts';\nimport { USAGE } from './index.ts';\nimport { CONFIG, FORMAT, formatOf, parse, printWarnings } from './shared.ts';\nimport type { Command } from './types.ts';\n\n// status names what you cannot read off the config file: locations sense chose, values it\n// derived, state it stored. Config content is not echoed -- the config line says which file to\n// read, and duplicating its globs here would create two places that disagree after an edit.\n// The exception is the embed block's url and key, whose effect is remote and otherwise invisible.\n\n// Vectors are computed on the first semantic query, not at reconcile, so a tree can have a\n// semantic-on preset with nothing embedded yet -- reported here because a fast reconcile on\n// such a tree otherwise reads as \"the feature isn't on\".\nfunction vectorState(db: ReturnType<typeof open>['db']): { embedded: number; pending: number } | null {\n try {\n const row = db.prepare('SELECT COUNT(vector) AS embedded, COUNT(*) - COUNT(vector) AS pending FROM embeddings').get() as { embedded: number; pending: number };\n return row;\n } catch {\n return null;\n }\n}\n\nfunction parseErrorCount(db: ReturnType<typeof open>['db']): number {\n const row = db.prepare(`SELECT COUNT(*) AS n FROM frontmatter WHERE \"_parse_error\" IS NOT NULL`).get() as { n: number };\n return row.n;\n}\n\n// A URL can carry credentials in its userinfo (https://user:pass@host/v1). status output gets\n// pasted into issues and transcripts, so it is always safe to paste.\nexport function redactUrl(url: string): string {\n try {\n const parsed = new URL(url);\n if (!parsed.username && !parsed.password) return url;\n parsed.username = '';\n parsed.password = '';\n return `${parsed.toString().replace(/\\/$/, '')} (credentials redacted)`;\n } catch {\n return url;\n }\n}\n\n// A stopped Ollama/LM Studio/Cohere endpoint prints identically to a running one otherwise; any\n// HTTP response counts as reachable (probeReachable), so this only distinguishes up from down.\nasync function embedReachable(e: { provider: string; url?: string }): Promise<boolean | null> {\n if (e.provider === 'static' || (e.provider === 'openai' && !e.url)) return null;\n const base = (e.url ?? 'https://api.cohere.com').replace(/\\/+$/, '');\n return probeReachable(e.provider === 'openai' ? `${base}/models` : base);\n}\n\nconst status: Command = async (ctx) => {\n const { values } = parse(ctx.argv, `usage: ${ctx.name} ${USAGE.status}`, { ...FORMAT, ...CONFIG });\n const format = formatOf(values);\n const cfg = ctx.resolveConfig(values.config as string | undefined);\n const { db, dbPath, warnings } = open(cfg);\n printWarnings(warnings);\n\n const features = featureStates(cfg);\n const e = embedConfig(cfg);\n const hasModel = e ? modelPresent(cfg) : false;\n const reachable = e ? await embedReachable(e) : null;\n const vectors = e ? vectorState(db) : null;\n const presets = presetCoverage(db, cfg);\n const staticLanguages = e && e.provider === 'static' ? readLanguages(e.model) : undefined;\n const declaredLanguages = staticLanguages && staticLanguages.length > 0 ? staticLanguages : null;\n const detectedLanguages = languageDistribution(db) ?? null;\n const heartbeat = getMeta(db, 'watch_heartbeat');\n // Derived at open() (F): 3x the largest reconcile this cache has ever held its write\n // transaction for, floored at 30s -- read back from the connection rather than\n // recomputed here, so this always reports what open() actually set.\n const busyTimeoutMs = (db.prepare('PRAGMA busy_timeout').get() as { timeout: number }).timeout;\n // The env var holds the token; only its name and whether it is set are ever reported.\n const keyEnv = e?.key ? { name: e.key, set: (process.env[e.key] ?? '') !== '' } : null;\n const result = {\n config: cfg.configPath,\n configVersion: SUPPORTED_CONFIG_VERSION,\n migratedFrom: cfg.migratedFrom ?? null,\n unknownConfigKeys: cfg.unknownKeys ?? null,\n tree: cfg.baseDir,\n cache: dirname(dbPath),\n db: dbPath,\n cacheSchema: SCHEMA_VERSION,\n docs: docCount(db),\n unparseableFrontmatter: parseErrorCount(db),\n features: features.on,\n featuresOff: features.off,\n embed: e ? { provider: e.provider, model: e.model, dir: e.provider === 'static' ? modelDir(e.model) : null, url: e.url ? redactUrl(e.url) : null, reachable, keyEnv, downloaded: hasModel, languages: declaredLanguages, detectedLanguages, ...(vectors ?? {}) } : null,\n presets,\n queries: Object.keys(cfg.queries ?? {}).length,\n watcherPid: getMeta(db, 'watch_pid'),\n watcherHeartbeatSecondsAgo: heartbeat ? Math.round((Date.now() - Date.parse(heartbeat)) / 1000) : null,\n busyTimeoutMs,\n };\n\n if (format === 'json') {\n console.log(JSON.stringify(result, null, 2));\n } else {\n const migrated = cfg.migratedFrom !== undefined ? `, migrated from v${cfg.migratedFrom} on this run` : '';\n console.log(`config: ${result.config} (v${SUPPORTED_CONFIG_VERSION}${migrated})`);\n // A load-time stderr warning has scrolled away by the time anyone looks here.\n if (cfg.unknownKeys) console.log(` unknown keys, ignored: ${cfg.unknownKeys.join(', ')}`);\n console.log(`tree: ${result.tree}`);\n console.log(`cache: ${result.cache} (schema ${SCHEMA_VERSION}; delete this directory to reset)`);\n console.log(`docs: ${result.docs}${result.unparseableFrontmatter > 0 ? ` (${result.unparseableFrontmatter} with unparseable frontmatter: WHERE _parse_error IS NOT NULL)` : ''}`);\n console.log('');\n console.log(featuresLine(features));\n // One authoritative block, off states included: an absent model reads as a degraded search,\n // not as an empty corpus.\n if (!e) console.log('embed: off (no preset asks for vectors)');\n else {\n console.log(`embed: ${e.provider} ${e.model}`);\n if (e.provider === 'static') console.log(` model: ${modelDir(e.model)} (${hasModel ? 'present' : `missing, ${isDownloadable(e.model) ? `fetches automatically at first search, or run \\`${ctx.name} download\\` to prefetch` : `no ${MODEL_FILENAMES} in that directory`}`})`);\n if (declaredLanguages) console.log(` languages: ${declaredLanguages.join(', ')} (declared by the model card)`);\n // Cohere defaults to api.cohere.com with no url in the config; show it anyway so the\n // reachability probe below has something to name.\n if (e.url || reachable !== null) {\n const shown = e.url ? redactUrl(e.url) : 'https://api.cohere.com (default)';\n console.log(` url: ${shown}${reachable === null ? '' : reachable ? ' (reachable)' : ' (unreachable)'}`);\n }\n if (keyEnv) console.log(` key: env ${keyEnv.name} (${keyEnv.set ? 'set' : 'NOT SET'})`);\n if (!hasModel) console.log(' vectors: off until the model is present; search runs on words and links');\n else if (vectors) console.log(` vectors: ${vectors.embedded} embedded, ${vectors.pending} pending (embedded on the first semantic search)`);\n if (detectedLanguages) {\n const total = Object.values(detectedLanguages).reduce((a, b) => a + b, 0);\n const breakdown = Object.entries(detectedLanguages)\n .sort((a, b) => b[1] - a[1])\n .map(([code, n]) => `${code} ${Math.round((n / total) * 100)}%`)\n .join(', ');\n console.log(` detected: ${breakdown} (${total} chunks classified)`);\n }\n }\n console.log('');\n for (const line of presetsLines(presets)) console.log(line);\n console.log('');\n console.log(`queries: ${result.queries} saved (${ctx.name} --list)`);\n const pid = result.watcherPid ? `pid ${result.watcherPid}, ` : '';\n console.log(result.watcherHeartbeatSecondsAgo === null ? 'watcher: none' : `watcher: ${pid}last heartbeat ${result.watcherHeartbeatSecondsAgo}s ago`);\n console.log(`sqlite: busy_timeout ${result.busyTimeoutMs}ms (derived: 3x the largest reconcile this cache has recorded, floored at 30000ms)`);\n }\n db.close();\n};\nexport default status;\n"],"names":["dirname","presetCoverage","embedConfig","featureStates","SUPPORTED_CONFIG_VERSION","docCount","getMeta","open","SCHEMA_VERSION","probeReachable","languageDistribution","isDownloadable","MODEL_FILENAMES","modelDir","modelPresent","readLanguages","featuresLine","presetsLines","USAGE","CONFIG","FORMAT","formatOf","parse","printWarnings","vectorState","db","row","prepare","get","parseErrorCount","n","redactUrl","url","parsed","URL","username","password","toString","replace","embedReachable","e","provider","base","status","ctx","process","cfg","values","argv","name","format","resolveConfig","config","dbPath","warnings","features","hasModel","reachable","vectors","presets","staticLanguages","model","undefined","declaredLanguages","length","detectedLanguages","heartbeat","busyTimeoutMs","timeout","keyEnv","key","set","env","result","configPath","configVersion","migratedFrom","unknownConfigKeys","unknownKeys","tree","baseDir","cache","cacheSchema","docs","unparseableFrontmatter","on","featuresOff","off","embed","dir","downloaded","languages","queries","Object","keys","watcherPid","watcherHeartbeatSecondsAgo","Math","round","Date","now","console","log","JSON","stringify","migrated","join","shown","embedded","pending","total","reduce","a","b","breakdown","entries","sort","map","code","line","pid","close"],"mappings":"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"}
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/cli/status.ts"],"sourcesContent":["import { dirname } from 'node:path';\nimport { presetCoverage } from '../commands/status.ts';\nimport { embedConfig, featureStates, SUPPORTED_CONFIG_VERSION } from '../config/index.ts';\nimport { docCount, getMeta, open, SCHEMA_VERSION } from '../db/index.ts';\nimport { languageDistribution } from '../embed/distribution.ts';\nimport { probeReachable } from '../embed/http.ts';\nimport { isDownloadable, MODEL_FILENAMES, modelDir, modelPresent, readLanguages } from '../embed/store.ts';\nimport { featuresLine, presetsLines } from '../output/output.ts';\nimport { USAGE } from './index.ts';\nimport { CONFIG, FORMAT, formatOf, parse, printWarnings } from './shared.ts';\nimport type { Command } from './types.ts';\n\n// status names what you cannot read off the config file: locations sense chose, values it\n// derived, state it stored. Config content is not echoed -- the config line says which file to\n// read, and duplicating its globs here would create two places that disagree after an edit.\n// The exception is the embed block's url and key, whose effect is remote and otherwise invisible.\n\n// Vectors are computed on the first semantic query, not at reconcile, so a tree can have a\n// semantic-on preset with nothing embedded yet -- reported here because a fast reconcile on\n// such a tree otherwise reads as \"the feature isn't on\".\nfunction vectorState(db: ReturnType<typeof open>['db']): { embedded: number; pending: number } | null {\n try {\n const row = db.prepare('SELECT COUNT(vector) AS embedded, COUNT(*) - COUNT(vector) AS pending FROM embeddings').get() as { embedded: number; pending: number };\n return row;\n } catch {\n return null;\n }\n}\n\nfunction parseErrorCount(db: ReturnType<typeof open>['db']): number {\n const row = db.prepare(`SELECT COUNT(*) AS n FROM frontmatter WHERE \"_parse_error\" IS NOT NULL`).get() as { n: number };\n return row.n;\n}\n\n// A URL can carry credentials in its userinfo (https://user:pass@host/v1). status output gets\n// pasted into issues and transcripts, so it is always safe to paste.\nexport function redactUrl(url: string): string {\n try {\n const parsed = new URL(url);\n if (!parsed.username && !parsed.password) return url;\n parsed.username = '';\n parsed.password = '';\n return `${parsed.toString().replace(/\\/$/, '')} (credentials redacted)`;\n } catch {\n return url;\n }\n}\n\n// A stopped Ollama/LM Studio/Cohere endpoint prints identically to a running one otherwise; any\n// HTTP response counts as reachable (probeReachable), so this only distinguishes up from down.\nasync function embedReachable(e: { provider: string; url?: string }): Promise<boolean | null> {\n if (e.provider === 'static' || (e.provider === 'openai' && !e.url)) return null;\n const base = (e.url ?? 'https://api.cohere.com').replace(/\\/+$/, '');\n return probeReachable(e.provider === 'openai' ? `${base}/models` : base);\n}\n\nconst status: Command = async (ctx) => {\n const { values } = parse(ctx.argv, `usage: ${ctx.name} ${USAGE.status}`, { ...FORMAT, ...CONFIG });\n const format = formatOf(values);\n const cfg = ctx.resolveConfig(values.config as string | undefined);\n const { db, dbPath, warnings } = open(cfg);\n printWarnings(warnings);\n\n const features = featureStates(cfg);\n const e = embedConfig(cfg);\n const hasModel = e ? modelPresent(cfg) : false;\n const reachable = e ? await embedReachable(e) : null;\n const vectors = e ? vectorState(db) : null;\n const presets = presetCoverage(db, cfg);\n const staticLanguages = e && e.provider === 'static' ? readLanguages(e.model) : undefined;\n const declaredLanguages = staticLanguages && staticLanguages.length > 0 ? staticLanguages : null;\n const detectedLanguages = languageDistribution(db) ?? null;\n const heartbeat = getMeta(db, 'watch_heartbeat');\n // Derived at open() (F): 3x the largest reconcile this cache has ever held its write\n // transaction for, floored at 30s -- read back from the connection rather than\n // recomputed here, so this always reports what open() actually set.\n const busyTimeoutMs = (db.prepare('PRAGMA busy_timeout').get() as { timeout: number }).timeout;\n // The env var holds the token; only its name and whether it is set are ever reported.\n const keyEnv = e?.key ? { name: e.key, set: (process.env[e.key] ?? '') !== '' } : null;\n const result = {\n config: cfg.configPath,\n configVersion: SUPPORTED_CONFIG_VERSION,\n migratedFrom: cfg.migratedFrom ?? null,\n unknownConfigKeys: cfg.unknownKeys ?? null,\n tree: cfg.baseDir,\n cache: dirname(dbPath),\n db: dbPath,\n cacheSchema: SCHEMA_VERSION,\n docs: docCount(db),\n unparseableFrontmatter: parseErrorCount(db),\n features: features.on,\n featuresOff: features.off,\n embed: e ? { provider: e.provider, model: e.model, dir: e.provider === 'static' ? modelDir(e.model) : null, url: e.url ? redactUrl(e.url) : null, reachable, keyEnv, downloaded: hasModel, languages: declaredLanguages, detectedLanguages, ...(vectors ?? {}) } : null,\n presets,\n queries: Object.keys(cfg.queries ?? {}).length,\n watcherPid: getMeta(db, 'watch_pid'),\n watcherHeartbeatSecondsAgo: heartbeat ? Math.round((Date.now() - Date.parse(heartbeat)) / 1000) : null,\n busyTimeoutMs,\n };\n\n if (format === 'json') {\n console.log(JSON.stringify(result, null, 2));\n } else {\n const migrated = cfg.migratedFrom !== undefined ? `, migrated from v${cfg.migratedFrom} on this run` : '';\n console.log(`config: ${result.config} (v${SUPPORTED_CONFIG_VERSION}${migrated})`);\n // A load-time stderr warning has scrolled away by the time anyone looks here.\n if (cfg.unknownKeys) console.log(` unknown keys, ignored: ${cfg.unknownKeys.join(', ')}`);\n console.log(`tree: ${result.tree}`);\n console.log(`cache: ${result.cache} (schema ${SCHEMA_VERSION}; delete this directory to reset)`);\n console.log(`docs: ${result.docs}${result.unparseableFrontmatter > 0 ? ` (${result.unparseableFrontmatter} with unparseable frontmatter: WHERE _parse_error IS NOT NULL)` : ''}`);\n console.log('');\n console.log(featuresLine(features));\n // One authoritative block, off states included: an absent model reads as a degraded search,\n // not as an empty corpus.\n if (!e) console.log('embed: off (no preset asks for vectors)');\n else {\n console.log(`embed: ${e.provider} ${e.model}`);\n if (e.provider === 'static') console.log(` model: ${modelDir(e.model)} (${hasModel ? 'present' : `missing, ${isDownloadable(e.model) ? `fetches automatically at first search, or run \\`${ctx.name} download\\` to prefetch` : `no ${MODEL_FILENAMES} in that directory`}`})`);\n if (declaredLanguages) console.log(` languages: ${declaredLanguages.join(', ')} (declared by the model card)`);\n // Cohere defaults to api.cohere.com with no url in the config; show it anyway so the\n // reachability probe below has something to name.\n if (e.url || reachable !== null) {\n const shown = e.url ? redactUrl(e.url) : 'https://api.cohere.com (default)';\n console.log(` url: ${shown}${reachable === null ? '' : reachable ? ' (reachable)' : ' (unreachable)'}`);\n }\n if (keyEnv) console.log(` key: env ${keyEnv.name} (${keyEnv.set ? 'set' : 'NOT SET'})`);\n if (!hasModel) console.log(' vectors: off until the model is present; search runs on words and links');\n else if (vectors) console.log(` vectors: ${vectors.embedded} embedded, ${vectors.pending} pending (embedded on the first semantic search)`);\n if (detectedLanguages) {\n const total = Object.values(detectedLanguages).reduce((a, b) => a + b, 0);\n const breakdown = Object.entries(detectedLanguages)\n .sort((a, b) => b[1] - a[1])\n .map(([code, n]) => `${code} ${Math.round((n / total) * 100)}%`)\n .join(', ');\n console.log(` detected: ${breakdown} (${total} chunks classified)`);\n }\n }\n console.log('');\n for (const line of presetsLines(presets)) console.log(line);\n console.log('');\n console.log(`queries: ${result.queries} saved (${ctx.name} --list)`);\n const pid = result.watcherPid ? `pid ${result.watcherPid}, ` : '';\n console.log(result.watcherHeartbeatSecondsAgo === null ? 'watcher: none' : `watcher: ${pid}last heartbeat ${result.watcherHeartbeatSecondsAgo}s ago`);\n console.log(`sqlite: busy_timeout ${result.busyTimeoutMs}ms (derived: 3x the largest reconcile this cache has recorded, floored at 30000ms)`);\n }\n db.close();\n};\nexport default status;\n"],"names":["dirname","presetCoverage","embedConfig","featureStates","SUPPORTED_CONFIG_VERSION","docCount","getMeta","open","SCHEMA_VERSION","languageDistribution","probeReachable","isDownloadable","MODEL_FILENAMES","modelDir","modelPresent","readLanguages","featuresLine","presetsLines","USAGE","CONFIG","FORMAT","formatOf","parse","printWarnings","vectorState","db","row","prepare","get","parseErrorCount","n","redactUrl","url","parsed","URL","username","password","toString","replace","embedReachable","e","provider","base","status","ctx","process","cfg","values","argv","name","format","resolveConfig","config","dbPath","warnings","features","hasModel","reachable","vectors","presets","staticLanguages","model","undefined","declaredLanguages","length","detectedLanguages","heartbeat","busyTimeoutMs","timeout","keyEnv","key","set","env","result","configPath","configVersion","migratedFrom","unknownConfigKeys","unknownKeys","tree","baseDir","cache","cacheSchema","docs","unparseableFrontmatter","on","featuresOff","off","embed","dir","downloaded","languages","queries","Object","keys","watcherPid","watcherHeartbeatSecondsAgo","Math","round","Date","now","console","log","JSON","stringify","migrated","join","shown","embedded","pending","total","reduce","a","b","breakdown","entries","sort","map","code","line","pid","close"],"mappings":"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"}
|
|
@@ -0,0 +1,4 @@
|
|
|
1
|
+
import type { DatabaseSync } from 'node:sqlite';
|
|
2
|
+
export type LangCounts = Record<string, number>;
|
|
3
|
+
export declare function languageDistribution(db: DatabaseSync): LangCounts | undefined;
|
|
4
|
+
export declare function saveLanguageDistribution(db: DatabaseSync, counts: LangCounts): void;
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import { getMeta, setMeta } from '../db/shared.js';
|
|
2
|
+
// Split out of langfit.ts so reading the persisted counts (status.ts's only need) never pulls in
|
|
3
|
+
// franc-min; only checkLanguageFit's classify path needs the classifier itself.
|
|
4
|
+
const META_KEY = 'embed_languages';
|
|
5
|
+
export function languageDistribution(db) {
|
|
6
|
+
const raw = getMeta(db, META_KEY);
|
|
7
|
+
return raw ? JSON.parse(raw) : undefined;
|
|
8
|
+
}
|
|
9
|
+
export function saveLanguageDistribution(db, counts) {
|
|
10
|
+
setMeta(db, META_KEY, JSON.stringify(counts));
|
|
11
|
+
}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["/Users/kevin/Dev/OpenSource/ai/sensemaking/src/embed/distribution.ts"],"sourcesContent":["import type { DatabaseSync } from 'node:sqlite';\nimport { getMeta, setMeta } from '../db/shared.ts';\n\n// Split out of langfit.ts so reading the persisted counts (status.ts's only need) never pulls in\n// franc-min; only checkLanguageFit's classify path needs the classifier itself.\nconst META_KEY = 'embed_languages';\n\nexport type LangCounts = Record<string, number>;\n\nexport function languageDistribution(db: DatabaseSync): LangCounts | undefined {\n const raw = getMeta(db, META_KEY);\n return raw ? JSON.parse(raw) : undefined;\n}\n\nexport function saveLanguageDistribution(db: DatabaseSync, counts: LangCounts): void {\n setMeta(db, META_KEY, JSON.stringify(counts));\n}\n"],"names":["getMeta","setMeta","META_KEY","languageDistribution","db","raw","JSON","parse","undefined","saveLanguageDistribution","counts","stringify"],"mappings":"AACA,SAASA,OAAO,EAAEC,OAAO,QAAQ,kBAAkB;AAEnD,iGAAiG;AACjG,gFAAgF;AAChF,MAAMC,WAAW;AAIjB,OAAO,SAASC,qBAAqBC,EAAgB;IACnD,MAAMC,MAAML,QAAQI,IAAIF;IACxB,OAAOG,MAAMC,KAAKC,KAAK,CAACF,OAAOG;AACjC;AAEA,OAAO,SAASC,yBAAyBL,EAAgB,EAAEM,MAAkB;IAC3ET,QAAQG,IAAIF,UAAUI,KAAKK,SAAS,CAACD;AACvC"}
|
|
@@ -1,6 +1,3 @@
|
|
|
1
1
|
import type { DatabaseSync } from 'node:sqlite';
|
|
2
2
|
import type { EmbedProvider } from './types.js';
|
|
3
|
-
type LangCounts = Record<string, number>;
|
|
4
|
-
export declare function languageDistribution(db: DatabaseSync): LangCounts | undefined;
|
|
5
3
|
export declare function checkLanguageFit(db: DatabaseSync, provider: EmbedProvider, texts: string[]): Promise<void>;
|
|
6
|
-
export {};
|
|
@@ -1,19 +1,18 @@
|
|
|
1
|
-
import
|
|
2
|
-
import { getMeta, setMeta } from '../db/shared.js';
|
|
1
|
+
import Module from 'node:module';
|
|
3
2
|
import { SenseError } from '../errors.js';
|
|
3
|
+
import { languageDistribution, saveLanguageDistribution } from './distribution.js';
|
|
4
4
|
import { toIso3 } from './languages.js';
|
|
5
|
-
const META_KEY = 'embed_languages';
|
|
6
5
|
// franc's own reliability floor is a handful of characters; this is a cheap upper bound, not a
|
|
7
6
|
// per-chunk minimum -- a short chunk is simply more likely to come back 'und' (unclassified).
|
|
8
7
|
const SAMPLE_CHARS = 300;
|
|
9
8
|
// A majority computed over a handful of chunks is noise, not a corpus signal; the decision rule
|
|
10
9
|
// never fires below this many classified chunks, declared languages or not.
|
|
11
10
|
const MIN_CLASSIFIED = 10;
|
|
12
|
-
|
|
13
|
-
|
|
14
|
-
|
|
15
|
-
|
|
16
|
-
function classify(text) {
|
|
11
|
+
// franc-min is a 148K static import; a top-level import put it on every command's module graph
|
|
12
|
+
// regardless of whether the semantic path ran, shipped as the 0.17.0 regression. Deferred to a
|
|
13
|
+
// synchronous require inside checkLanguageFit so only the embed path pays for it.
|
|
14
|
+
const _require = typeof require === 'undefined' ? Module.createRequire(import.meta.url) : require;
|
|
15
|
+
function classify(franc, text) {
|
|
17
16
|
const code = franc(text.slice(0, SAMPLE_CHARS));
|
|
18
17
|
return code === 'und' ? undefined : code;
|
|
19
18
|
}
|
|
@@ -22,13 +21,14 @@ function classify(text) {
|
|
|
22
21
|
export async function checkLanguageFit(db, provider, texts) {
|
|
23
22
|
var _languageDistribution;
|
|
24
23
|
if (texts.length === 0) return;
|
|
24
|
+
const { franc } = _require('franc-min');
|
|
25
25
|
const persisted = (_languageDistribution = languageDistribution(db)) !== null && _languageDistribution !== void 0 ? _languageDistribution : {};
|
|
26
26
|
const merged = {
|
|
27
27
|
...persisted
|
|
28
28
|
};
|
|
29
29
|
for (const text of texts){
|
|
30
30
|
var _merged_code;
|
|
31
|
-
const code = classify(text);
|
|
31
|
+
const code = classify(franc, text);
|
|
32
32
|
if (code) merged[code] = ((_merged_code = merged[code]) !== null && _merged_code !== void 0 ? _merged_code : 0) + 1;
|
|
33
33
|
}
|
|
34
34
|
const total = Object.values(merged).reduce((a, b)=>a + b, 0);
|
|
@@ -40,5 +40,5 @@ export async function checkLanguageFit(db, provider, texts) {
|
|
|
40
40
|
throw new SenseError('EMBED_MODEL_MISMATCH', `embed model ${provider.id} declares languages [${provider.languages.join(', ')}], but ${pct}% of this tree's classified text is "${majorityLang}" (ISO 639-3), which is not among them; choose a model for this tree's languages: \`sense init --model ...\`, see the sense-setup skill or INTEGRATIONS.md`);
|
|
41
41
|
}
|
|
42
42
|
}
|
|
43
|
-
|
|
43
|
+
saveLanguageDistribution(db, merged);
|
|
44
44
|
}
|