@autorag/librarian 2.13.9 → 2.13.11
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/cli/index.js +56 -32
- package/dist/core.d.ts +5 -0
- package/dist/core.js +46 -23
- package/dist/filesystem/path-exclusions.d.ts +12 -1
- package/dist/index.js +158 -31
- package/dist/mcp/index.js +205 -34
- package/dist/mcp/reloading-lite.d.ts +25 -0
- package/dist/mcp/server.d.ts +16 -0
- package/dist/mirror/sync.d.ts +1 -0
- package/dist/profiles.js +49 -32
- package/package.json +1 -1
package/dist/mcp/index.js
CHANGED
|
@@ -3669,20 +3669,30 @@ var init_bundle = __esm(() => {
|
|
|
3669
3669
|
});
|
|
3670
3670
|
|
|
3671
3671
|
// src/filesystem/path-exclusions.ts
|
|
3672
|
-
import { posix as posix2, win32 as win322 } from "node:path";
|
|
3672
|
+
import { matchesGlob, posix as posix2, win32 as win322 } from "node:path";
|
|
3673
|
+
function isGlobExclusion(entry) {
|
|
3674
|
+
return /[*?[]/u.test(entry);
|
|
3675
|
+
}
|
|
3676
|
+
function matchesGlobExclusion(path, glob) {
|
|
3677
|
+
const slashed = path.replaceAll("\\", "/");
|
|
3678
|
+
if (matchesGlob(slashed, glob))
|
|
3679
|
+
return true;
|
|
3680
|
+
return glob.startsWith("**/") && matchesGlob(slashed, glob.slice(3));
|
|
3681
|
+
}
|
|
3673
3682
|
function createPathExclusionMatcher(excludedPaths, platform = process.platform) {
|
|
3674
3683
|
const paths = platform === "win32" ? win322 : posix2;
|
|
3675
3684
|
const normalize = (path) => {
|
|
3676
3685
|
const absolute = paths.resolve(path);
|
|
3677
3686
|
return platform === "win32" ? absolute.toLowerCase() : absolute;
|
|
3678
3687
|
};
|
|
3679
|
-
const
|
|
3688
|
+
const globs = excludedPaths.filter(isGlobExclusion).map((glob) => platform === "win32" ? glob.toLowerCase() : glob);
|
|
3689
|
+
const excluded = excludedPaths.filter((path) => !isGlobExclusion(path)).map((path) => {
|
|
3680
3690
|
const absolute = normalize(path);
|
|
3681
3691
|
return { absolute, prefix: absolute.endsWith(paths.sep) ? absolute : `${absolute}${paths.sep}` };
|
|
3682
3692
|
});
|
|
3683
3693
|
return (path) => {
|
|
3684
3694
|
const absolute = normalize(path);
|
|
3685
|
-
return excluded.some((entry) => absolute === entry.absolute || absolute.startsWith(entry.prefix));
|
|
3695
|
+
return excluded.some((entry) => absolute === entry.absolute || absolute.startsWith(entry.prefix)) || globs.some((glob) => matchesGlobExclusion(absolute, glob));
|
|
3686
3696
|
};
|
|
3687
3697
|
}
|
|
3688
3698
|
var init_path_exclusions = () => {};
|
|
@@ -10334,7 +10344,7 @@ var init_cloud = __esm(() => {
|
|
|
10334
10344
|
// src/mirror/sync.ts
|
|
10335
10345
|
import { createHash as createHash11 } from "node:crypto";
|
|
10336
10346
|
import { opendir, readFile, stat as stat3 } from "node:fs/promises";
|
|
10337
|
-
import { basename as basename9, dirname as dirname12, extname as extname6, join as join27, resolve as resolve11
|
|
10347
|
+
import { basename as basename9, dirname as dirname12, extname as extname6, join as join27, resolve as resolve11 } from "node:path";
|
|
10338
10348
|
import { setTimeout as sleep3 } from "node:timers/promises";
|
|
10339
10349
|
function errorCode(error) {
|
|
10340
10350
|
if (!(error instanceof Error))
|
|
@@ -10881,13 +10891,14 @@ function normalizeExtension2(extension) {
|
|
|
10881
10891
|
return lower.startsWith(".") ? lower : `.${lower}`;
|
|
10882
10892
|
}
|
|
10883
10893
|
function isPathExcluded(sourcePath, excluded) {
|
|
10884
|
-
if (excluded === undefined)
|
|
10894
|
+
if (excluded === undefined || excluded.size === 0)
|
|
10885
10895
|
return false;
|
|
10886
|
-
|
|
10887
|
-
|
|
10888
|
-
|
|
10896
|
+
let matcher = matcherBySet.get(excluded);
|
|
10897
|
+
if (matcher === undefined) {
|
|
10898
|
+
matcher = createPathExclusionMatcher([...excluded]);
|
|
10899
|
+
matcherBySet.set(excluded, matcher);
|
|
10889
10900
|
}
|
|
10890
|
-
return
|
|
10901
|
+
return matcher(sourcePath);
|
|
10891
10902
|
}
|
|
10892
10903
|
function walkLimits(options) {
|
|
10893
10904
|
return {
|
|
@@ -11054,10 +11065,11 @@ async function collectFiles(state, directory, depth) {
|
|
|
11054
11065
|
warnDirectoryUnreadable(state, directory, code);
|
|
11055
11066
|
}
|
|
11056
11067
|
}
|
|
11057
|
-
var DEFAULT_MAX_SOURCE_BYTES, DEFAULT_MAX_DELETE_RATIO = 0.3, MASS_DELETE_FLOOR = 100, DEFAULT_MAX_SCANNED_ENTRIES = 2000000, DEFAULT_MAX_WALK_DEPTH = 64, DEFAULT_MIRROR_BATCH_SIZE = 25, PRODUCT_ARTIFACT_FILE_NAMES, SKIP_DIR_NAMES, PARSER_FAILURE_MESSAGE = "The registered parser failed on this file; it was skipped during indexing.", PARSER_CRASH_MESSAGE = "The registered parser crashed unexpectedly on this file; it was skipped during indexing.", DEFAULT_TRANSIENT_RETRIES = 3, DEFAULT_TRANSIENT_BACKOFF_MS = 50, TRANSIENT_ERROR_CODES, WORKSPACE_ERROR_CODES, MirrorWorkspaceError, STANDALONE_OCR_IMAGE_EXTENSIONS, SEARCH_ROOT_UNAVAILABLE_MESSAGES;
|
|
11068
|
+
var DEFAULT_MAX_SOURCE_BYTES, DEFAULT_MAX_DELETE_RATIO = 0.3, MASS_DELETE_FLOOR = 100, DEFAULT_MAX_SCANNED_ENTRIES = 2000000, DEFAULT_MAX_WALK_DEPTH = 64, DEFAULT_MIRROR_BATCH_SIZE = 25, PRODUCT_ARTIFACT_FILE_NAMES, SKIP_DIR_NAMES, PARSER_FAILURE_MESSAGE = "The registered parser failed on this file; it was skipped during indexing.", PARSER_CRASH_MESSAGE = "The registered parser crashed unexpectedly on this file; it was skipped during indexing.", DEFAULT_TRANSIENT_RETRIES = 3, DEFAULT_TRANSIENT_BACKOFF_MS = 50, TRANSIENT_ERROR_CODES, WORKSPACE_ERROR_CODES, MirrorWorkspaceError, STANDALONE_OCR_IMAGE_EXTENSIONS, matcherBySet, SEARCH_ROOT_UNAVAILABLE_MESSAGES;
|
|
11058
11069
|
var init_sync = __esm(() => {
|
|
11059
11070
|
init_cli2();
|
|
11060
11071
|
init_cloud_placeholder();
|
|
11072
|
+
init_path_exclusions();
|
|
11061
11073
|
init_source_paths();
|
|
11062
11074
|
init_binary();
|
|
11063
11075
|
init_stage();
|
|
@@ -11116,6 +11128,7 @@ var init_sync = __esm(() => {
|
|
|
11116
11128
|
}
|
|
11117
11129
|
};
|
|
11118
11130
|
STANDALONE_OCR_IMAGE_EXTENSIONS = new Set(KORDOC_IMAGE_EXTENSIONS);
|
|
11131
|
+
matcherBySet = new WeakMap;
|
|
11119
11132
|
SEARCH_ROOT_UNAVAILABLE_MESSAGES = {
|
|
11120
11133
|
gone: "A search root no longer exists; its previously indexed documents were left untouched.",
|
|
11121
11134
|
"not-a-directory": "A search root is no longer a directory; its previously indexed documents were left untouched.",
|
|
@@ -16190,7 +16203,7 @@ var init_automation_profiles = __esm(() => {
|
|
|
16190
16203
|
|
|
16191
16204
|
// src/automation/config.ts
|
|
16192
16205
|
import { existsSync as existsSync19, readFileSync as readFileSync14, realpathSync as realpathSync7 } from "node:fs";
|
|
16193
|
-
import { basename as basename10, dirname as dirname15, isAbsolute as isAbsolute8, join as join30, matchesGlob, relative as relative5, resolve as resolve12 } from "node:path";
|
|
16206
|
+
import { basename as basename10, dirname as dirname15, isAbsolute as isAbsolute8, join as join30, matchesGlob as matchesGlob2, relative as relative5, resolve as resolve12 } from "node:path";
|
|
16194
16207
|
function automationsConfigPath(env = process.env) {
|
|
16195
16208
|
return join30(resolveAutoRAGHome(env), "automations.json");
|
|
16196
16209
|
}
|
|
@@ -16366,9 +16379,9 @@ function deleteAutomation(configPath, id) {
|
|
|
16366
16379
|
function globMatches(relPosix, pattern) {
|
|
16367
16380
|
if (pattern === "**")
|
|
16368
16381
|
return true;
|
|
16369
|
-
if (
|
|
16382
|
+
if (matchesGlob2(relPosix, pattern))
|
|
16370
16383
|
return true;
|
|
16371
|
-
if (pattern.startsWith("**/") &&
|
|
16384
|
+
if (pattern.startsWith("**/") && matchesGlob2(relPosix, pattern.slice(3)))
|
|
16372
16385
|
return true;
|
|
16373
16386
|
return false;
|
|
16374
16387
|
}
|
|
@@ -17165,7 +17178,7 @@ var init_permission_judgment = __esm(() => {
|
|
|
17165
17178
|
|
|
17166
17179
|
// src/agent/permission-gate.ts
|
|
17167
17180
|
import { statSync as statSync7 } from "node:fs";
|
|
17168
|
-
import { isAbsolute as isAbsolute9, relative as relative6, sep as
|
|
17181
|
+
import { isAbsolute as isAbsolute9, relative as relative6, sep as sep6 } from "node:path";
|
|
17169
17182
|
import { matchesKey } from "@earendil-works/pi-tui";
|
|
17170
17183
|
function pathExists(path) {
|
|
17171
17184
|
try {
|
|
@@ -17228,7 +17241,7 @@ class PermissionController {
|
|
|
17228
17241
|
if (path === root)
|
|
17229
17242
|
return true;
|
|
17230
17243
|
const rel = relative6(root, path);
|
|
17231
|
-
if (rel !== "" && rel !== ".." && !rel.startsWith(`..${
|
|
17244
|
+
if (rel !== "" && rel !== ".." && !rel.startsWith(`..${sep6}`) && !isAbsolute9(rel))
|
|
17232
17245
|
return true;
|
|
17233
17246
|
}
|
|
17234
17247
|
return false;
|
|
@@ -18680,7 +18693,7 @@ var init_connector = () => {};
|
|
|
18680
18693
|
// src/datasource/sidecar/config.ts
|
|
18681
18694
|
import { readFileSync as readFileSync17 } from "node:fs";
|
|
18682
18695
|
import { homedir as homedir5 } from "node:os";
|
|
18683
|
-
import { dirname as dirname17, isAbsolute as isAbsolute10, join as join34, resolve as resolve14, sep as
|
|
18696
|
+
import { dirname as dirname17, isAbsolute as isAbsolute10, join as join34, resolve as resolve14, sep as sep7 } from "node:path";
|
|
18684
18697
|
import { parse as parseToml } from "smol-toml";
|
|
18685
18698
|
function resolveSidecarOptions(input) {
|
|
18686
18699
|
const { connector, workspaceRoot } = input;
|
|
@@ -18720,7 +18733,7 @@ function archivePathFromCrawlerConfig(input) {
|
|
|
18720
18733
|
function expandHome(path) {
|
|
18721
18734
|
if (path === "~")
|
|
18722
18735
|
return homedir5();
|
|
18723
|
-
const prefixed = path.startsWith("~/") ||
|
|
18736
|
+
const prefixed = path.startsWith("~/") || sep7 === "\\" && path.startsWith("~\\");
|
|
18724
18737
|
return prefixed ? join34(homedir5(), path.slice(2)) : path;
|
|
18725
18738
|
}
|
|
18726
18739
|
var init_config3 = __esm(() => {
|
|
@@ -25974,7 +25987,7 @@ import {
|
|
|
25974
25987
|
writeFileSync as writeFileSync13
|
|
25975
25988
|
} from "node:fs";
|
|
25976
25989
|
import { opendir as opendir2, stat as stat4 } from "node:fs/promises";
|
|
25977
|
-
import { basename as basename11, dirname as dirname23, extname as extname8, join as join40, relative as relative7, sep as
|
|
25990
|
+
import { basename as basename11, dirname as dirname23, extname as extname8, join as join40, relative as relative7, sep as sep8 } from "node:path";
|
|
25978
25991
|
function errnoCode2(error) {
|
|
25979
25992
|
const code = error instanceof Error ? error.code : undefined;
|
|
25980
25993
|
return typeof code === "string" ? code : "UNKNOWN";
|
|
@@ -26044,7 +26057,7 @@ async function listVaultNotes(vaultPath) {
|
|
|
26044
26057
|
return { notes, unreadableFolders, collisions };
|
|
26045
26058
|
}
|
|
26046
26059
|
function toRelative(vaultPath, path) {
|
|
26047
|
-
return relative7(vaultPath, path).split(
|
|
26060
|
+
return relative7(vaultPath, path).split(sep8).join("/").normalize("NFC");
|
|
26048
26061
|
}
|
|
26049
26062
|
function loadStagingState2(statePath) {
|
|
26050
26063
|
try {
|
|
@@ -26128,7 +26141,7 @@ function removeUnexpected(filesRoot, directory, wanted) {
|
|
|
26128
26141
|
return removed;
|
|
26129
26142
|
}
|
|
26130
26143
|
function toStagedRelative(filesRoot, path) {
|
|
26131
|
-
return relative7(filesRoot, path).split(
|
|
26144
|
+
return relative7(filesRoot, path).split(sep8).join("/").normalize("NFC");
|
|
26132
26145
|
}
|
|
26133
26146
|
var NOTE_EXTENSIONS, SKIPPED_DIRECTORIES, MAX_WALK_DEPTH = 64, VaultUnavailableError;
|
|
26134
26147
|
var init_staging = __esm(() => {
|
|
@@ -28049,7 +28062,7 @@ function resolveExcludePaths(value, origin) {
|
|
|
28049
28062
|
if (!Array.isArray(value) || value.some((path) => typeof path !== "string" || path.length === 0)) {
|
|
28050
28063
|
throw new ConfigError("Config field 'excludePaths' must be a non-empty string array");
|
|
28051
28064
|
}
|
|
28052
|
-
return
|
|
28065
|
+
return value.map((entry) => isGlobExclusion(entry) ? entry : resolvePersistedPath(entry, origin));
|
|
28053
28066
|
}
|
|
28054
28067
|
function resolvePersistedPath(path, origin) {
|
|
28055
28068
|
return isAbsolute11(path) ? path : resolve15(origin, path);
|
|
@@ -29354,6 +29367,7 @@ var init_config5 = __esm(() => {
|
|
|
29354
29367
|
init_factory();
|
|
29355
29368
|
init_embedding();
|
|
29356
29369
|
init_file_lock();
|
|
29370
|
+
init_path_exclusions();
|
|
29357
29371
|
init_language();
|
|
29358
29372
|
init_atomic_write();
|
|
29359
29373
|
init_rerank();
|
|
@@ -38607,7 +38621,7 @@ var init_web_search_tool = __esm(() => {
|
|
|
38607
38621
|
// src/agent/agent.ts
|
|
38608
38622
|
import { randomUUID as randomUUID7 } from "node:crypto";
|
|
38609
38623
|
import { existsSync as existsSync34, watch as fsWatch, mkdirSync as mkdirSync24, realpathSync as realpathSync8, statSync as statSync11, writeFileSync as writeFileSync17 } from "node:fs";
|
|
38610
|
-
import { basename as basename15, dirname as dirname27, join as join55, relative as relative8, resolve as resolve18, sep as
|
|
38624
|
+
import { basename as basename15, dirname as dirname27, join as join55, relative as relative8, resolve as resolve18, sep as sep9 } from "node:path";
|
|
38611
38625
|
import { clampThinkingLevel } from "@earendil-works/pi-ai/compat";
|
|
38612
38626
|
import { getAgentDir as getAgentDir6, keyText } from "@earendil-works/pi-coding-agent";
|
|
38613
38627
|
function describeDecisionModel(status) {
|
|
@@ -41280,7 +41294,7 @@ ${this.discoveryHint((tools) => `When exploring local files and folders, activel
|
|
|
41280
41294
|
return { ok: false, reason: "cloud-root-skipped", stdout: "", stderr: "", code: null };
|
|
41281
41295
|
}
|
|
41282
41296
|
const canonicalSourcePath = canonicalPath(sourcePath);
|
|
41283
|
-
const exclude = scope.nestedCloudRoots.map((root) => relative8(canonicalSourcePath, root.path).split(
|
|
41297
|
+
const exclude = scope.nestedCloudRoots.map((root) => relative8(canonicalSourcePath, root.path).split(sep9).join("/")).filter((pattern) => pattern !== "" && !pattern.startsWith(".."));
|
|
41284
41298
|
return client.prepare(sourcePath, { ...options, ...exclude.length === 0 ? {} : { exclude } });
|
|
41285
41299
|
}));
|
|
41286
41300
|
}
|
|
@@ -41794,6 +41808,8 @@ function toMinSyncReasonDiagnostic(reason) {
|
|
|
41794
41808
|
};
|
|
41795
41809
|
}
|
|
41796
41810
|
function pinExcludedPath(path) {
|
|
41811
|
+
if (isGlobExclusion(path))
|
|
41812
|
+
return path;
|
|
41797
41813
|
const resolvedPath = resolve18(path);
|
|
41798
41814
|
try {
|
|
41799
41815
|
return join55(realpathSync8(dirname27(resolvedPath)), basename15(resolvedPath));
|
|
@@ -41842,6 +41858,7 @@ var init_agent = __esm(() => {
|
|
|
41842
41858
|
init_embedding();
|
|
41843
41859
|
init_everything();
|
|
41844
41860
|
init_cloud_placeholder();
|
|
41861
|
+
init_path_exclusions();
|
|
41845
41862
|
init_fsearch();
|
|
41846
41863
|
init_diagnostics();
|
|
41847
41864
|
init_jikji();
|
|
@@ -42002,6 +42019,12 @@ class AutoRAGLite {
|
|
|
42002
42019
|
getMemorySchema() {
|
|
42003
42020
|
return structuredClone(this.memory.getSchema());
|
|
42004
42021
|
}
|
|
42022
|
+
convertFiles(request, signal) {
|
|
42023
|
+
return this.agent.convertFiles(request, signal);
|
|
42024
|
+
}
|
|
42025
|
+
listFileConversions(from, signal) {
|
|
42026
|
+
return this.agent.listFileConversions(from, signal);
|
|
42027
|
+
}
|
|
42005
42028
|
}
|
|
42006
42029
|
function createAutoRAGLite(options = {}) {
|
|
42007
42030
|
const input = { flags: options.flags ?? {} };
|
|
@@ -42693,6 +42716,48 @@ import { realpathSync as realpathSync10 } from "node:fs";
|
|
|
42693
42716
|
import { fileURLToPath as fileURLToPath6 } from "node:url";
|
|
42694
42717
|
import { StdioServerTransport } from "@modelcontextprotocol/server/stdio";
|
|
42695
42718
|
|
|
42719
|
+
// src/mcp/reloading-lite.ts
|
|
42720
|
+
init_config5();
|
|
42721
|
+
import { statSync as statSync12 } from "node:fs";
|
|
42722
|
+
function createReloadingLite(options) {
|
|
42723
|
+
let attempted = options.signature();
|
|
42724
|
+
let current = options.create();
|
|
42725
|
+
const sync = () => {
|
|
42726
|
+
const next = options.signature();
|
|
42727
|
+
if (next === attempted)
|
|
42728
|
+
return current;
|
|
42729
|
+
attempted = next;
|
|
42730
|
+
try {
|
|
42731
|
+
current = options.create();
|
|
42732
|
+
} catch (error) {
|
|
42733
|
+
options.onError?.(error instanceof Error ? error : new Error(String(error)));
|
|
42734
|
+
}
|
|
42735
|
+
return current;
|
|
42736
|
+
};
|
|
42737
|
+
return new Proxy({}, {
|
|
42738
|
+
get(_target, property) {
|
|
42739
|
+
const runtime = sync();
|
|
42740
|
+
const value = Reflect.get(runtime, property, runtime);
|
|
42741
|
+
return typeof value === "function" ? value.bind(runtime) : value;
|
|
42742
|
+
},
|
|
42743
|
+
has(_target, property) {
|
|
42744
|
+
return property in sync();
|
|
42745
|
+
}
|
|
42746
|
+
});
|
|
42747
|
+
}
|
|
42748
|
+
function configSignature(env = process.env) {
|
|
42749
|
+
const { configPath, legacyPath } = resolveConfigPath({ flags: {}, env });
|
|
42750
|
+
return [configPath, legacyPath].map((path) => path === undefined ? "-" : fingerprint(path)).join("|");
|
|
42751
|
+
}
|
|
42752
|
+
function fingerprint(path) {
|
|
42753
|
+
try {
|
|
42754
|
+
const stats = statSync12(path);
|
|
42755
|
+
return `${stats.ino}:${stats.size}:${stats.mtimeMs}`;
|
|
42756
|
+
} catch {
|
|
42757
|
+
return "absent";
|
|
42758
|
+
}
|
|
42759
|
+
}
|
|
42760
|
+
|
|
42696
42761
|
// src/mcp/server.ts
|
|
42697
42762
|
init_evidence();
|
|
42698
42763
|
init_report();
|
|
@@ -42706,7 +42771,7 @@ import { z as z4 } from "zod";
|
|
|
42706
42771
|
// src/filesystem/name-search.ts
|
|
42707
42772
|
import { realpathSync as realpathSync9 } from "node:fs";
|
|
42708
42773
|
import { lstat as lstat2, readdir as readdir5 } from "node:fs/promises";
|
|
42709
|
-
import { basename as basename16, dirname as dirname28, isAbsolute as isAbsolute14, join as join56, relative as relative9, resolve as resolve19, sep as
|
|
42774
|
+
import { basename as basename16, dirname as dirname28, isAbsolute as isAbsolute14, join as join56, relative as relative9, resolve as resolve19, sep as sep10 } from "node:path";
|
|
42710
42775
|
var SKIP_DIR_NAMES2 = {
|
|
42711
42776
|
".git": true,
|
|
42712
42777
|
".autorag": true,
|
|
@@ -42734,7 +42799,7 @@ function fsErrorCode(error) {
|
|
|
42734
42799
|
return typeof code === "string" ? code : undefined;
|
|
42735
42800
|
}
|
|
42736
42801
|
function isContained(childReal, parentReal) {
|
|
42737
|
-
const prefix = parentReal.endsWith(
|
|
42802
|
+
const prefix = parentReal.endsWith(sep10) ? parentReal : `${parentReal}${sep10}`;
|
|
42738
42803
|
return childReal === parentReal || childReal.startsWith(prefix);
|
|
42739
42804
|
}
|
|
42740
42805
|
function pinExcludedPath2(path) {
|
|
@@ -42747,14 +42812,14 @@ function pinExcludedPath2(path) {
|
|
|
42747
42812
|
}
|
|
42748
42813
|
function isExcluded2(absPath, excluded) {
|
|
42749
42814
|
for (const excludedPath of excluded) {
|
|
42750
|
-
const prefix = excludedPath.endsWith(
|
|
42815
|
+
const prefix = excludedPath.endsWith(sep10) ? excludedPath : `${excludedPath}${sep10}`;
|
|
42751
42816
|
if (absPath === excludedPath || absPath.startsWith(prefix))
|
|
42752
42817
|
return true;
|
|
42753
42818
|
}
|
|
42754
42819
|
return false;
|
|
42755
42820
|
}
|
|
42756
42821
|
function matchesEntry(context, absPath, name) {
|
|
42757
|
-
const haystackRaw = context.matchPath ? relative9(context.rootReal, absPath).split(
|
|
42822
|
+
const haystackRaw = context.matchPath ? relative9(context.rootReal, absPath).split(sep10).join("/") : name;
|
|
42758
42823
|
const haystack = context.matchCase ? haystackRaw : haystackRaw.toLowerCase();
|
|
42759
42824
|
const needle = context.matchCase ? context.query : context.query.toLowerCase();
|
|
42760
42825
|
return haystack.includes(needle);
|
|
@@ -42895,7 +42960,7 @@ async function filterFileNameSearchMatches(roots, candidates, excludePaths = [])
|
|
|
42895
42960
|
continue;
|
|
42896
42961
|
if (isExcluded2(real, excluded))
|
|
42897
42962
|
continue;
|
|
42898
|
-
const segments = real.split(
|
|
42963
|
+
const segments = real.split(sep10);
|
|
42899
42964
|
if (segments.some((segment) => SKIP_DIR_NAMES2[segment] === true))
|
|
42900
42965
|
continue;
|
|
42901
42966
|
matches.push({ path: real, type: stat.isDirectory() ? "folder" : "file" });
|
|
@@ -43019,6 +43084,16 @@ var evidenceInput = z4.strictObject({
|
|
|
43019
43084
|
sessionId: z4.string().trim().min(1),
|
|
43020
43085
|
resultNumber: z4.number().int().positive().optional()
|
|
43021
43086
|
});
|
|
43087
|
+
var convertInput = z4.strictObject({
|
|
43088
|
+
inputs: z4.array(z4.string().trim().min(1)).min(1).max(500),
|
|
43089
|
+
to: z4.string().trim().min(1),
|
|
43090
|
+
outputDir: z4.string().trim().min(1).optional(),
|
|
43091
|
+
recursive: z4.boolean().optional(),
|
|
43092
|
+
quality: z4.number().int().min(1).max(100).optional(),
|
|
43093
|
+
keepDates: z4.boolean().optional()
|
|
43094
|
+
});
|
|
43095
|
+
var convertFormatsInput = z4.strictObject({ from: z4.string().trim().min(1).optional() });
|
|
43096
|
+
var MAX_CONVERT_FILES = 200;
|
|
43022
43097
|
function exactGroupsFromScan(scan) {
|
|
43023
43098
|
const groups = new Map;
|
|
43024
43099
|
for (const file of scan.files) {
|
|
@@ -43040,6 +43115,57 @@ function jsonResult(value, isError = false) {
|
|
|
43040
43115
|
function toolError(code, message, extra = {}) {
|
|
43041
43116
|
return jsonResult({ ok: false, errorCode: code, message, ...extra }, true);
|
|
43042
43117
|
}
|
|
43118
|
+
var DIAGNOSTIC_EXAMPLES_PER_CODE = 3;
|
|
43119
|
+
function capDiagnostics(diagnostics) {
|
|
43120
|
+
const byCode = new Map;
|
|
43121
|
+
for (const entry of diagnostics) {
|
|
43122
|
+
const list = byCode.get(entry.code);
|
|
43123
|
+
if (list === undefined)
|
|
43124
|
+
byCode.set(entry.code, [entry]);
|
|
43125
|
+
else
|
|
43126
|
+
list.push(entry);
|
|
43127
|
+
}
|
|
43128
|
+
const out = [];
|
|
43129
|
+
for (const [code, entries] of byCode) {
|
|
43130
|
+
out.push(...entries.slice(0, DIAGNOSTIC_EXAMPLES_PER_CODE));
|
|
43131
|
+
const rest = entries.slice(DIAGNOSTIC_EXAMPLES_PER_CODE);
|
|
43132
|
+
if (rest.length === 0)
|
|
43133
|
+
continue;
|
|
43134
|
+
const reasons = new Map;
|
|
43135
|
+
for (const entry of rest) {
|
|
43136
|
+
const key = entry.reason ?? "unspecified";
|
|
43137
|
+
reasons.set(key, (reasons.get(key) ?? 0) + 1);
|
|
43138
|
+
}
|
|
43139
|
+
const split = [...reasons].map(([reason, count]) => `${reason}: ${count}`).join(", ");
|
|
43140
|
+
const severity = entries.some((entry) => entry.severity === "error") ? "error" : entries.some((entry) => entry.severity === "warning") ? "warning" : "info";
|
|
43141
|
+
out.push({
|
|
43142
|
+
code,
|
|
43143
|
+
severity,
|
|
43144
|
+
message: `${rest.length} more ${code} entries omitted (${split}); the first ${DIAGNOSTIC_EXAMPLES_PER_CODE} are shown above.`
|
|
43145
|
+
});
|
|
43146
|
+
}
|
|
43147
|
+
return out;
|
|
43148
|
+
}
|
|
43149
|
+
function convertResult(details) {
|
|
43150
|
+
const { result, links } = details;
|
|
43151
|
+
const files = result.files.slice(0, MAX_CONVERT_FILES).map((file) => ({
|
|
43152
|
+
source: file.source,
|
|
43153
|
+
state: file.state,
|
|
43154
|
+
outputs: file.outputs,
|
|
43155
|
+
...file.error !== undefined ? { error: file.error } : {},
|
|
43156
|
+
...file.notice !== undefined ? { notice: file.notice } : {}
|
|
43157
|
+
}));
|
|
43158
|
+
const body = {
|
|
43159
|
+
target: result.target,
|
|
43160
|
+
converted: result.converted,
|
|
43161
|
+
skipped: result.skipped,
|
|
43162
|
+
failed: result.failed,
|
|
43163
|
+
files,
|
|
43164
|
+
...result.files.length > files.length ? { omittedFiles: result.files.length - files.length } : {},
|
|
43165
|
+
links
|
|
43166
|
+
};
|
|
43167
|
+
return result.converted === 0 && result.failed > 0 ? toolError("convert-failed", "No file was converted.", body) : jsonResult({ ok: true, ...body });
|
|
43168
|
+
}
|
|
43043
43169
|
function isToolEnabled(name, options) {
|
|
43044
43170
|
return options.tools === undefined || options.tools.includes(name);
|
|
43045
43171
|
}
|
|
@@ -43165,7 +43291,10 @@ function createAutoRAGMcpServer(lite, options = {}) {
|
|
|
43165
43291
|
inputSchema: emptyInput,
|
|
43166
43292
|
outputSchema: objectOutput,
|
|
43167
43293
|
annotations: { readOnlyHint: true, openWorldHint: false }
|
|
43168
|
-
}, async () =>
|
|
43294
|
+
}, async () => {
|
|
43295
|
+
const status = await lite.getRefreshStatus();
|
|
43296
|
+
return jsonResult({ ...status, diagnostics: capDiagnostics(status.diagnostics) });
|
|
43297
|
+
});
|
|
43169
43298
|
}
|
|
43170
43299
|
if (isToolEnabled("autorag.search", options)) {
|
|
43171
43300
|
server.registerTool("autorag.search", {
|
|
@@ -43204,7 +43333,7 @@ function createAutoRAGMcpServer(lite, options = {}) {
|
|
|
43204
43333
|
content: result.content
|
|
43205
43334
|
})),
|
|
43206
43335
|
unsearched: retrieved.unsearched,
|
|
43207
|
-
diagnostics: [...status.diagnostics, ...retrieved.diagnostics]
|
|
43336
|
+
diagnostics: capDiagnostics([...status.diagnostics, ...retrieved.diagnostics])
|
|
43208
43337
|
});
|
|
43209
43338
|
} catch (error) {
|
|
43210
43339
|
return toolError(error instanceof RetrievalSelectionError ? "invalid-selection" : "search-failed", error instanceof Error ? error.message : String(error), { retryable: !(error instanceof RetrievalSelectionError) });
|
|
@@ -43259,7 +43388,7 @@ function createAutoRAGMcpServer(lite, options = {}) {
|
|
|
43259
43388
|
content: result.content
|
|
43260
43389
|
})),
|
|
43261
43390
|
unsearched: retrieved.unsearched,
|
|
43262
|
-
diagnostics: [...status.diagnostics, ...retrieved.diagnostics]
|
|
43391
|
+
diagnostics: capDiagnostics([...status.diagnostics, ...retrieved.diagnostics])
|
|
43263
43392
|
});
|
|
43264
43393
|
} catch (error) {
|
|
43265
43394
|
return toolError(error instanceof RetrievalSelectionError ? "invalid-selection" : "search-failed", error instanceof Error ? error.message : String(error), { datasourceId: entry.datasourceId, retryable: !(error instanceof RetrievalSelectionError) });
|
|
@@ -43334,6 +43463,46 @@ function createAutoRAGMcpServer(lite, options = {}) {
|
|
|
43334
43463
|
return datasource === undefined ? toolError("datasource-not-found", `No configured datasource named ${datasourceId}.`, { datasourceId }) : jsonResult({ ok: true, datasource });
|
|
43335
43464
|
});
|
|
43336
43465
|
}
|
|
43466
|
+
const convertEnabled = lite.config.filee?.enabled !== false;
|
|
43467
|
+
if (convertEnabled && !readOnly && isToolEnabled("autorag.convert", options)) {
|
|
43468
|
+
server.registerTool("autorag.convert", {
|
|
43469
|
+
title: "Convert Files",
|
|
43470
|
+
description: "Convert local files to another format offline with Filee: documents, spreadsheets, slides, HWP/HWPX, images, e-books, archives, audio, video, data. Writes new files next to each source (or into outputDir) and never replaces an existing file: a colliding name gets a number added. Each output is compared with its source by Dupey, so the result says whether the copy would count as a duplicate. Use autorag.convert.formats when unsure what a source can become.",
|
|
43471
|
+
inputSchema: convertInput,
|
|
43472
|
+
outputSchema: objectOutput,
|
|
43473
|
+
annotations: { readOnlyHint: false, idempotentHint: false, destructiveHint: false, openWorldHint: false }
|
|
43474
|
+
}, async ({ inputs, to, outputDir, recursive, quality, keepDates }, ctx) => {
|
|
43475
|
+
try {
|
|
43476
|
+
const details = await lite.convertFiles({
|
|
43477
|
+
inputs,
|
|
43478
|
+
to,
|
|
43479
|
+
...outputDir !== undefined ? { outputDir } : {},
|
|
43480
|
+
...recursive !== undefined ? { recursive } : {},
|
|
43481
|
+
...quality !== undefined ? { quality } : {},
|
|
43482
|
+
...keepDates !== undefined ? { keepDates } : {}
|
|
43483
|
+
}, ctx.mcpReq.signal);
|
|
43484
|
+
return convertResult(details);
|
|
43485
|
+
} catch (error) {
|
|
43486
|
+
return toolError("convert-failed", error instanceof Error ? error.message : String(error));
|
|
43487
|
+
}
|
|
43488
|
+
});
|
|
43489
|
+
}
|
|
43490
|
+
if (convertEnabled && isToolEnabled("autorag.convert.formats", options)) {
|
|
43491
|
+
server.registerTool("autorag.convert.formats", {
|
|
43492
|
+
title: "List Convertible Formats",
|
|
43493
|
+
description: "List the file formats Filee knows, or what one source format (heic, docx, hwp, mkv) can be converted to, including targets that need an optional engine. Read-only.",
|
|
43494
|
+
inputSchema: convertFormatsInput,
|
|
43495
|
+
outputSchema: objectOutput,
|
|
43496
|
+
annotations: { readOnlyHint: true, openWorldHint: false }
|
|
43497
|
+
}, async ({ from }, ctx) => {
|
|
43498
|
+
try {
|
|
43499
|
+
const formats = await lite.listFileConversions(from, ctx.mcpReq.signal);
|
|
43500
|
+
return jsonResult({ ok: true, ...from !== undefined ? { from } : {}, formats });
|
|
43501
|
+
} catch (error) {
|
|
43502
|
+
return toolError("convert-failed", error instanceof Error ? error.message : String(error));
|
|
43503
|
+
}
|
|
43504
|
+
});
|
|
43505
|
+
}
|
|
43337
43506
|
if (!readOnly && isToolEnabled("autorag.report", options)) {
|
|
43338
43507
|
server.registerTool("autorag.report", {
|
|
43339
43508
|
title: "Persist AutoRAG Curated Report",
|
|
@@ -43421,9 +43590,11 @@ function isInvokedDirectly() {
|
|
|
43421
43590
|
async function main() {
|
|
43422
43591
|
const readOnly = parseBoolean(process.env.AUTORAG_MCP_READ_ONLY);
|
|
43423
43592
|
const tools = parseTools(process.env.AUTORAG_MCP_TOOLS);
|
|
43424
|
-
const lite =
|
|
43425
|
-
env: process.env,
|
|
43426
|
-
|
|
43593
|
+
const lite = createReloadingLite({
|
|
43594
|
+
create: () => createAutoRAGLite({ env: process.env, readOnly }),
|
|
43595
|
+
signature: () => configSignature(process.env),
|
|
43596
|
+
onError: (error) => process.stderr.write(`autorag-mcp: keeping the previous config, the new one failed: ${error.message}
|
|
43597
|
+
`)
|
|
43427
43598
|
});
|
|
43428
43599
|
const server = createAutoRAGMcpServer(lite, { readOnly, tools });
|
|
43429
43600
|
await server.connect(new StdioServerTransport);
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
import type { AutoRAGLite } from "../core.js";
|
|
2
|
+
export interface ReloadingLiteOptions {
|
|
3
|
+
/** Build a runtime from the config as it is now. May throw (missing or unparsable config). */
|
|
4
|
+
readonly create: () => AutoRAGLite;
|
|
5
|
+
/** A cheap fingerprint of whatever `create` reads; a different value means the runtime is out of date. */
|
|
6
|
+
readonly signature: () => string;
|
|
7
|
+
/** A config that could not be loaded. Called once per distinct broken config, never on every call. */
|
|
8
|
+
readonly onError?: (error: Error) => void;
|
|
9
|
+
}
|
|
10
|
+
/**
|
|
11
|
+
* A runtime that follows its config file. An MCP server is started once and then lives for as long as its host
|
|
12
|
+
* keeps it (Hermes keeps one per gateway, across chat sessions), so a config written after it started, which is
|
|
13
|
+
* exactly what first-time setup does, would otherwise never be seen: every search kept answering `index-not-ready`.
|
|
14
|
+
*
|
|
15
|
+
* Each access compares the config's signature (two `stat` calls) and rebuilds the runtime when it changed. The first
|
|
16
|
+
* build happens eagerly, so a bad config still fails at start. A later config that cannot be loaded (half-written,
|
|
17
|
+
* mistyped) keeps the last working runtime and is reported once, then retried when the file changes again.
|
|
18
|
+
*/
|
|
19
|
+
export declare function createReloadingLite(options: ReloadingLiteOptions): AutoRAGLite;
|
|
20
|
+
/**
|
|
21
|
+
* Fingerprint of the config file `createAutoRAGLite` would read: its inode, size and modification time, or `absent`.
|
|
22
|
+
* An explicit `AUTORAG_CONFIG`, else `<AUTORAG_HOME>/config.json` (and the legacy `autorag.config.json` beside the
|
|
23
|
+
* working directory) are covered, in the same order the resolver uses.
|
|
24
|
+
*/
|
|
25
|
+
export declare function configSignature(env?: NodeJS.ProcessEnv): string;
|
package/dist/mcp/server.d.ts
CHANGED
|
@@ -6,4 +6,20 @@ export interface AutoRAGMcpServerOptions {
|
|
|
6
6
|
/** Test/embedded override; defaults to the current Node platform. */
|
|
7
7
|
readonly platform?: NodeJS.Platform;
|
|
8
8
|
}
|
|
9
|
+
interface DiagnosticLike {
|
|
10
|
+
readonly code: string;
|
|
11
|
+
readonly severity: string;
|
|
12
|
+
readonly message: string;
|
|
13
|
+
readonly source?: string;
|
|
14
|
+
readonly reason?: string;
|
|
15
|
+
}
|
|
16
|
+
/**
|
|
17
|
+
* Keep an MCP response small when one code repeats once per file. A corpus whose parser changed reports one
|
|
18
|
+
* `stale-index` entry per source (1,100 of them, about 750 KB, on a real 160k-file index), which the model then has to
|
|
19
|
+
* read through on every search and status call. Each code keeps its first few entries verbatim and one summary entry
|
|
20
|
+
* says how many more there were and how they split by `reason`, so "why is it stale" survives and a different code is
|
|
21
|
+
* never hidden behind a flood of this one. Short lists pass through unchanged.
|
|
22
|
+
*/
|
|
23
|
+
export declare function capDiagnostics<T extends DiagnosticLike>(diagnostics: readonly T[]): (T | DiagnosticLike)[];
|
|
9
24
|
export declare function createAutoRAGMcpServer(lite: AutoRAGLite, options?: AutoRAGMcpServerOptions): McpServer;
|
|
25
|
+
export {};
|
package/dist/mirror/sync.d.ts
CHANGED
|
@@ -187,4 +187,5 @@ export declare class MirrorWorkspaceError extends Error {
|
|
|
187
187
|
export declare function syncParsedMirrors(options: ParsedMirrorSyncOptions): Promise<ParsedMirrorSyncResult>;
|
|
188
188
|
/** Ask MinSync's read-only plan which current source revisions still need work. */
|
|
189
189
|
export declare function detectMirrorStaleness(options: ParsedMirrorSyncOptions): Promise<ParsedMirrorDiagnostic[]>;
|
|
190
|
+
/** A path is excluded when it equals an excluded path, sits under one, or matches an excluded glob. */
|
|
190
191
|
export declare function isPathExcluded(sourcePath: string, excluded: ReadonlySet<string> | undefined): boolean;
|