sift-light 1.0.3-5 → 1.0.3-6
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/CHANGELOG.md +6 -0
- package/package.json +7 -4
- package/plugins/sift-light/.claude-plugin/plugin.json +1 -1
- package/plugins/sift-light/.codex-plugin/plugin.json +1 -1
- package/plugins/sift-light/.mcp.json +1 -1
- package/plugins/sift-light/concept-worker.mjs +83 -33
- package/plugins/sift-light/kimi.plugin.json +2 -2
- package/plugins/sift-light/omp-extension.mjs +3092 -2117
- package/plugins/sift-light/package.json +1 -1
- package/src/analysis-store.ts +23 -2
- package/src/analysis-types.ts +3 -0
- package/src/byspace-data-source.ts +104 -0
- package/src/concept-model.ts +33 -0
- package/src/concept-search.ts +116 -227
- package/src/concept-worker-client.ts +306 -0
- package/src/concept-worker-protocol.ts +86 -0
- package/src/concept-worker.mjs +83 -33
- package/src/concept-worker.ts +86 -32
- package/src/config-reader.ts +11 -2
- package/src/data-source-config.ts +98 -0
- package/src/data-source-http.ts +120 -0
- package/src/data-source-protocol.ts +113 -0
- package/src/data-sources.ts +113 -0
- package/src/errors.ts +6 -0
- package/src/evidence-service.ts +27 -4
- package/src/index.ts +1 -0
- package/src/language-capabilities.ts +16 -0
- package/src/mcp-semantic-judge.ts +8 -1
- package/src/mcp-server.mjs +2906 -1929
- package/src/mcp-server.ts +10 -5
- package/src/mcp.ts +3 -0
- package/src/omp-index.ts +1 -0
- package/src/package-smoke.mjs +81 -0
- package/src/relevance-ranking.ts +184 -0
- package/src/request-contract-catalog.ts +14 -1
- package/src/request-contract-error.ts +2 -0
- package/src/request-contract.ts +134 -9
- package/src/rg.ts +30 -7
- package/src/ripgrep-diagnostics.ts +21 -3
- package/src/scan-revisions.ts +1 -1
- package/src/service.ts +41 -3
- package/src/tool-schema.ts +19 -1
- package/src/types.ts +6 -0
- package/src/workspace-files.ts +3 -0
package/CHANGELOG.md
CHANGED
|
@@ -1,5 +1,11 @@
|
|
|
1
1
|
# Changelog
|
|
2
2
|
|
|
3
|
+
## 1.0.3-6 — 2026-10-09
|
|
4
|
+
|
|
5
|
+
- Add bounded, read-only configured data-source adapters with explicit HTTPS/loopback validation, credential references and revision-aware source reads.
|
|
6
|
+
- Improve hybrid relevance ranking with request-scoped BM25 and semantic rank fusion, identifier-declaration candidates and distinct passage handling.
|
|
7
|
+
- Harden MCP/request-contract integration and add a packaged MCP smoke test so the published artifact is exercised through the real stdio transport.
|
|
8
|
+
|
|
3
9
|
## 1.0.3-5 — 2026-10-07
|
|
4
10
|
|
|
5
11
|
- Update the MCP SDK to 1.31.0 and Transformers.js to 4.3.1 to remove the dependency vulnerabilities reported in [#111](https://github.com/lightsifter/sift-light/issues/111), including the old ONNX proxy/logging dependency chain. Refresh compatible SDK transitive dependencies in the lockfile.
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sift-light",
|
|
3
|
-
"version": "1.0.3-
|
|
3
|
+
"version": "1.0.3-6",
|
|
4
4
|
"description": "Context-efficient local search for files, documents, notes and logs across Pi, OMP and MCP clients",
|
|
5
5
|
"keywords": [
|
|
6
6
|
"ai-agent",
|
|
@@ -38,6 +38,7 @@
|
|
|
38
38
|
"src/syntax-worker.mjs",
|
|
39
39
|
"src/mcp-server.mjs",
|
|
40
40
|
"src/syntax-worker.toml",
|
|
41
|
+
"src/package-smoke.mjs",
|
|
41
42
|
"README.md",
|
|
42
43
|
"README.zh-CN.md",
|
|
43
44
|
"CONTRIBUTING.md",
|
|
@@ -62,8 +63,9 @@
|
|
|
62
63
|
"format:check": "oxfmt --check .",
|
|
63
64
|
"lint": "oxlint --type-aware --deny-warnings --report-unused-disable-directives src scripts",
|
|
64
65
|
"typecheck": "tsc --noEmit",
|
|
65
|
-
"test": "bun test ./doc/testing/test",
|
|
66
|
-
"test
|
|
66
|
+
"test:repo": "bun test ./doc/testing/test",
|
|
67
|
+
"test": "node src/package-smoke.mjs",
|
|
68
|
+
"test:node:repo": "bun run doc/testing/scripts/node-smoke.ts",
|
|
67
69
|
"benchmark": "bun run doc/testing/scripts/benchmark.ts",
|
|
68
70
|
"check": "bun run format:check && bun run lint && bun run typecheck && bun run build",
|
|
69
71
|
"pack:check": "bun pm pack --dry-run && bun run scripts/check-npm-publish.ts",
|
|
@@ -71,6 +73,7 @@
|
|
|
71
73
|
"build:concept-worker": "bun run scripts/build-concept-worker.ts",
|
|
72
74
|
"check:concept-worker": "bun run doc/testing/scripts/check-concept-worker.ts",
|
|
73
75
|
"test:concept": "bun run doc/testing/scripts/test-concept.ts",
|
|
76
|
+
"evaluate:relevance": "bun run doc/testing/scripts/relevance-eval.ts",
|
|
74
77
|
"evaluate:investigations": "bun run doc/testing/scripts/investigation-eval.ts",
|
|
75
78
|
"build:search-plugin": "bun run scripts/build-search-plugin.ts",
|
|
76
79
|
"check:search-plugin": "bun run doc/testing/scripts/check-search-plugin.ts",
|
|
@@ -79,7 +82,7 @@
|
|
|
79
82
|
"format:local:check": "bun run doc/testing/scripts/format-local.ts --check",
|
|
80
83
|
"lint:local": "oxlint --no-ignore --type-aware --tsconfig doc/testing/tsconfig.json --deny-warnings --report-unused-disable-directives src scripts doc/testing/test doc/testing/scripts",
|
|
81
84
|
"typecheck:local": "tsc --noEmit --project doc/testing/tsconfig.json",
|
|
82
|
-
"check:local": "bun run format:check && bun run format:local:check && bun run check:search-plugin && bun run check:concept-worker && bun run check:worker && bun run check:mcp && bun run lint:local && bun run typecheck:local && bun run test && bun run test:node && bun run benchmark"
|
|
85
|
+
"check:local": "bun run format:check && bun run format:local:check && bun run check:search-plugin && bun run check:concept-worker && bun run check:worker && bun run check:mcp && bun run lint:local && bun run typecheck:local && bun run test:repo && bun run test:node:repo && bun run benchmark"
|
|
83
86
|
},
|
|
84
87
|
"dependencies": {
|
|
85
88
|
"@ast-grep/lang-go": "0.0.6",
|
|
@@ -462,8 +462,12 @@ async function installConceptModel() {
|
|
|
462
462
|
|
|
463
463
|
// src/concept-worker.ts
|
|
464
464
|
var CACHE_IO_CONCURRENCY = 64;
|
|
465
|
+
var activeRequestId;
|
|
466
|
+
var extractor;
|
|
467
|
+
var modelVerified = false;
|
|
468
|
+
var modelLoads = 0;
|
|
465
469
|
function emitProgress(progress) {
|
|
466
|
-
process.stdout.write(`${JSON.stringify({ type: "progress", ...progress })}
|
|
470
|
+
process.stdout.write(`${JSON.stringify({ type: "progress", id: activeRequestId, ...progress })}
|
|
467
471
|
`);
|
|
468
472
|
}
|
|
469
473
|
async function readCachedEmbeddings(root, requested, onProgress) {
|
|
@@ -475,7 +479,7 @@ async function readCachedEmbeddings(root, requested, onProgress) {
|
|
|
475
479
|
}
|
|
476
480
|
return cached;
|
|
477
481
|
}
|
|
478
|
-
async function
|
|
482
|
+
async function readSingleRequest() {
|
|
479
483
|
const chunks = [];
|
|
480
484
|
let bytes = 0;
|
|
481
485
|
for await (const chunk of process.stdin) {
|
|
@@ -485,7 +489,9 @@ async function requestFromStdin() {
|
|
|
485
489
|
if (bytes > MAX_CONCEPT_WORKER_INPUT_BYTES)
|
|
486
490
|
throw new Error("Concept worker input exceeds its 64 MiB source protocol budget");
|
|
487
491
|
}
|
|
488
|
-
|
|
492
|
+
return JSON.parse(Buffer.concat(chunks).toString("utf8"));
|
|
493
|
+
}
|
|
494
|
+
function decodeRequest(request) {
|
|
489
495
|
if (!isRecordValue(request) || typeof request.query !== "string" || request.query.length === 0 || request.query.length > 256 || !request.query.isWellFormed() || /[\r\n\0]/u.test(request.query) || !Array.isArray(request.encodedPassages) || request.encodedPassages.some((item) => typeof item !== "string" || item.length === 0 || item.length % 4 !== 0 || item.length > Math.ceil((MAX_CONCEPT_CHARS + 256) * 4 / 3 * 4) + 4 || !/^[A-Za-z0-9+/]+={0,2}$/u.test(item)))
|
|
490
496
|
throw new Error("Invalid concept worker input");
|
|
491
497
|
const encodedPassages = request.encodedPassages.filter((item) => typeof item === "string");
|
|
@@ -497,12 +503,16 @@ async function requestFromStdin() {
|
|
|
497
503
|
throw new Error("Invalid decoded concept worker passage");
|
|
498
504
|
return { query: request.query, passages };
|
|
499
505
|
}
|
|
500
|
-
async function search() {
|
|
501
|
-
const request =
|
|
506
|
+
async function search(raw) {
|
|
507
|
+
const request = decodeRequest(raw);
|
|
502
508
|
const directory = conceptModelDirectory();
|
|
503
509
|
const cacheRoot = conceptCacheDirectory();
|
|
504
510
|
const stagingRoot = process.env.SIFT_LIGHT_CONCEPT_CACHE_STAGING_DIR ?? cacheRoot;
|
|
505
|
-
|
|
511
|
+
if (!modelVerified) {
|
|
512
|
+
await verifyConceptModel(directory);
|
|
513
|
+
modelVerified = true;
|
|
514
|
+
}
|
|
515
|
+
const modelReused = extractor !== undefined;
|
|
506
516
|
const requested = [
|
|
507
517
|
{ key: conceptEmbeddingKey("query", request.query), role: "query", text: request.query },
|
|
508
518
|
...request.passages.map((text) => ({
|
|
@@ -526,28 +536,27 @@ async function search() {
|
|
|
526
536
|
env.useFSCache = false;
|
|
527
537
|
env.useBrowserCache = false;
|
|
528
538
|
env.localModelPath = "/";
|
|
529
|
-
|
|
530
|
-
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
try {
|
|
537
|
-
created = await embedConceptInputs(extractor, missing, {
|
|
538
|
-
onCompletedEmbedding: async (embedding, completed, total) => {
|
|
539
|
-
try {
|
|
540
|
-
await writeConceptEmbedding(cacheRoot, embedding, stagingRoot);
|
|
541
|
-
} catch {
|
|
542
|
-
cacheWriteFailed = true;
|
|
543
|
-
}
|
|
544
|
-
emitProgress({ phase: "cache-write", completed, total, ...progressContext });
|
|
545
|
-
},
|
|
546
|
-
onBatch: (completed, total) => emitProgress({ phase: "embedding", completed, total, ...progressContext })
|
|
539
|
+
if (!extractor) {
|
|
540
|
+
emitProgress({ phase: "model-loading", ...progressContext });
|
|
541
|
+
extractor = await pipeline("feature-extraction", directory, {
|
|
542
|
+
local_files_only: true,
|
|
543
|
+
dtype: "q8",
|
|
544
|
+
device: "cpu",
|
|
545
|
+
session_options: { intraOpNumThreads: 4, interOpNumThreads: 1 }
|
|
547
546
|
});
|
|
548
|
-
|
|
549
|
-
await extractor.dispose();
|
|
547
|
+
modelLoads += 1;
|
|
550
548
|
}
|
|
549
|
+
created = await embedConceptInputs(extractor, missing, {
|
|
550
|
+
onCompletedEmbedding: async (embedding, completed, total) => {
|
|
551
|
+
try {
|
|
552
|
+
await writeConceptEmbedding(cacheRoot, embedding, stagingRoot);
|
|
553
|
+
} catch {
|
|
554
|
+
cacheWriteFailed = true;
|
|
555
|
+
}
|
|
556
|
+
emitProgress({ phase: "cache-write", completed, total, ...progressContext });
|
|
557
|
+
},
|
|
558
|
+
onBatch: (completed, total) => emitProgress({ phase: "embedding", completed, total, ...progressContext })
|
|
559
|
+
});
|
|
551
560
|
if (cacheWriteFailed)
|
|
552
561
|
warnings.push("Concept embedding cache write failed; ranking completed but some work may repeat");
|
|
553
562
|
}
|
|
@@ -575,6 +584,9 @@ async function search() {
|
|
|
575
584
|
}
|
|
576
585
|
process.stdout.write(JSON.stringify({
|
|
577
586
|
type: "result",
|
|
587
|
+
id: activeRequestId,
|
|
588
|
+
modelLoads,
|
|
589
|
+
modelReused,
|
|
578
590
|
scores,
|
|
579
591
|
cacheHits: cached.filter(Boolean).length,
|
|
580
592
|
cacheMisses: missing.length,
|
|
@@ -584,11 +596,49 @@ async function search() {
|
|
|
584
596
|
warnings: [...new Set(warnings)],
|
|
585
597
|
peakRssBytes: process.resourceUsage().maxRSS * 1024,
|
|
586
598
|
modelBytes: CONCEPT_ASSETS.reduce((sum, asset) => sum + asset.bytes, 0)
|
|
587
|
-
})
|
|
599
|
+
}) + `
|
|
600
|
+
`);
|
|
601
|
+
}
|
|
602
|
+
async function serve() {
|
|
603
|
+
let buffer = Buffer.alloc(0);
|
|
604
|
+
for await (const chunk of process.stdin) {
|
|
605
|
+
buffer = Buffer.concat([buffer, Buffer.from(chunk)]);
|
|
606
|
+
if (buffer.length > MAX_CONCEPT_WORKER_INPUT_BYTES)
|
|
607
|
+
throw new Error("Concept request frame exceeds 64 MiB");
|
|
608
|
+
let newline = buffer.indexOf(10);
|
|
609
|
+
while (newline >= 0) {
|
|
610
|
+
const line = buffer.subarray(0, newline);
|
|
611
|
+
buffer = buffer.subarray(newline + 1);
|
|
612
|
+
const raw = JSON.parse(line.toString("utf8"));
|
|
613
|
+
if (!isRecordValue(raw) || typeof raw.id !== "string" || !/^[a-f0-9-]{36}$/u.test(raw.id))
|
|
614
|
+
throw new Error("Invalid concept request identity");
|
|
615
|
+
activeRequestId = raw.id;
|
|
616
|
+
try {
|
|
617
|
+
await search(raw);
|
|
618
|
+
} catch (error) {
|
|
619
|
+
process.stdout.write(JSON.stringify({
|
|
620
|
+
type: "error",
|
|
621
|
+
id: activeRequestId,
|
|
622
|
+
message: error instanceof Error ? error.message.slice(0, 512) : "Concept inference failed"
|
|
623
|
+
}) + `
|
|
624
|
+
`);
|
|
625
|
+
return;
|
|
626
|
+
}
|
|
627
|
+
newline = buffer.indexOf(10);
|
|
628
|
+
}
|
|
629
|
+
}
|
|
630
|
+
if (buffer.length)
|
|
631
|
+
throw new Error("Incomplete concept request frame");
|
|
632
|
+
}
|
|
633
|
+
try {
|
|
634
|
+
if (process.argv.includes("--install-model"))
|
|
635
|
+
await installConceptModel();
|
|
636
|
+
else if (process.argv.includes("--infer"))
|
|
637
|
+
await search(await readSingleRequest());
|
|
638
|
+
else if (process.argv.includes("--serve"))
|
|
639
|
+
await serve();
|
|
640
|
+
else
|
|
641
|
+
throw new Error("Usage: sift-light-model --install-model");
|
|
642
|
+
} finally {
|
|
643
|
+
await extractor?.dispose();
|
|
588
644
|
}
|
|
589
|
-
if (process.argv.includes("--install-model"))
|
|
590
|
-
await installConceptModel();
|
|
591
|
-
else if (process.argv.includes("--infer"))
|
|
592
|
-
await search();
|
|
593
|
-
else
|
|
594
|
-
throw new Error("Usage: sift-light-model --install-model");
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "sift-light",
|
|
3
|
-
"version": "1.0.3-
|
|
3
|
+
"version": "1.0.3-6",
|
|
4
4
|
"description": "Require sift-light for conventional local searches while keeping development tools available.",
|
|
5
5
|
"author": {
|
|
6
6
|
"name": "baoer"
|
|
@@ -13,7 +13,7 @@
|
|
|
13
13
|
"args": [
|
|
14
14
|
"--yes",
|
|
15
15
|
"--package",
|
|
16
|
-
"sift-light-runtime@npm:sift-light@1.0.3-
|
|
16
|
+
"sift-light-runtime@npm:sift-light@1.0.3-6",
|
|
17
17
|
"sift-light-mcp",
|
|
18
18
|
"--stdio"
|
|
19
19
|
],
|