@autorag/librarian 2.13.2 → 2.13.4
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/NOTICE +3 -0
- package/README.md +0 -1
- package/dist/agent/context-token-guard.d.ts +11 -6
- package/dist/agent/token-count.d.ts +4 -0
- package/dist/cli/index.js +287 -632
- package/dist/cloud/context-overflow.d.ts +29 -0
- package/dist/core.js +203 -547
- package/dist/datasource/connector-skill.d.ts +1 -1
- package/dist/datasource/connector.d.ts +1 -1
- package/dist/datasource/index.d.ts +0 -1
- package/dist/index.js +205 -552
- package/dist/mcp/index.js +205 -549
- package/dist/profiles.js +288 -632
- package/package.json +2 -1
- package/skills/autorag-doctor/SKILL.md +1 -2
- package/skills/autorag-lite-setup/SKILL.md +1 -1
- package/skills/autorag-setup/SKILL.md +3 -4
- package/dist/datasource/skills/spotlight/connector.d.ts +0 -53
- package/dist/datasource/skills/spotlight/index.d.ts +0 -2
- package/dist/datasource/skills/spotlight/skill.d.ts +0 -33
package/dist/cli/index.js
CHANGED
|
@@ -2381,6 +2381,51 @@ var init_credential = __esm(() => {
|
|
|
2381
2381
|
init_models();
|
|
2382
2382
|
});
|
|
2383
2383
|
|
|
2384
|
+
// src/cloud/context-overflow.ts
|
|
2385
|
+
import {
|
|
2386
|
+
createAssistantMessageEventStream,
|
|
2387
|
+
isContextOverflow
|
|
2388
|
+
} from "@earendil-works/pi-ai";
|
|
2389
|
+
import { getApiProvider } from "@earendil-works/pi-ai/compat";
|
|
2390
|
+
function recordRequestEstimate(model, estimatedTokens) {
|
|
2391
|
+
lastEstimates.set(modelKey(model), estimatedTokens);
|
|
2392
|
+
}
|
|
2393
|
+
function noteContextOverflow(model) {
|
|
2394
|
+
const key = modelKey(model);
|
|
2395
|
+
const failed = lastEstimates.get(key);
|
|
2396
|
+
if (failed === undefined)
|
|
2397
|
+
return;
|
|
2398
|
+
ceilings.set(key, Math.min(Math.floor(failed / 2), ceilings.get(key) ?? Number.POSITIVE_INFINITY));
|
|
2399
|
+
}
|
|
2400
|
+
function contextOverflowCeiling(model) {
|
|
2401
|
+
return ceilings.get(modelKey(model));
|
|
2402
|
+
}
|
|
2403
|
+
function streamDazziSimple(model, context, options) {
|
|
2404
|
+
const api = getApiProvider(model.api);
|
|
2405
|
+
if (api === undefined)
|
|
2406
|
+
throw new Error(`No API provider registered for api: ${model.api}`);
|
|
2407
|
+
const inner = api.streamSimple(model, context, options);
|
|
2408
|
+
const stream = createAssistantMessageEventStream();
|
|
2409
|
+
(async () => {
|
|
2410
|
+
try {
|
|
2411
|
+
for await (const event of inner) {
|
|
2412
|
+
if (event.type === "error" && event.error.stopReason === "error" && isContextOverflow(event.error)) {
|
|
2413
|
+
noteContextOverflow(model);
|
|
2414
|
+
}
|
|
2415
|
+
stream.push(event);
|
|
2416
|
+
}
|
|
2417
|
+
} finally {
|
|
2418
|
+
stream.end();
|
|
2419
|
+
}
|
|
2420
|
+
})();
|
|
2421
|
+
return stream;
|
|
2422
|
+
}
|
|
2423
|
+
var lastEstimates, ceilings, modelKey = (model) => `${model.provider}/${model.id}`;
|
|
2424
|
+
var init_context_overflow = __esm(() => {
|
|
2425
|
+
lastEstimates = new Map;
|
|
2426
|
+
ceilings = new Map;
|
|
2427
|
+
});
|
|
2428
|
+
|
|
2384
2429
|
// src/cloud/authorize.ts
|
|
2385
2430
|
function buildAuthorizeUrl(params) {
|
|
2386
2431
|
const url = new URL(`${normalizeBaseUrl(params.baseUrl)}${AUTHORIZE_PATH}`);
|
|
@@ -2736,6 +2781,7 @@ function createDazziProviderConfig(env = process.env) {
|
|
|
2736
2781
|
name: PROVIDER_NAME,
|
|
2737
2782
|
baseUrl: endpoints.apiBaseUrl,
|
|
2738
2783
|
api: "openai-responses",
|
|
2784
|
+
streamSimple: streamDazziSimple,
|
|
2739
2785
|
oauth: {
|
|
2740
2786
|
name: PROVIDER_NAME,
|
|
2741
2787
|
login: (callbacks) => loginDazzi(callbacks, { baseUrl }),
|
|
@@ -2751,6 +2797,7 @@ async function registerDazziProvider(runtime, env = process.env) {
|
|
|
2751
2797
|
}
|
|
2752
2798
|
var init_provider = __esm(() => {
|
|
2753
2799
|
init_config2();
|
|
2800
|
+
init_context_overflow();
|
|
2754
2801
|
init_models();
|
|
2755
2802
|
init_oauth_login();
|
|
2756
2803
|
});
|
|
@@ -14530,413 +14577,6 @@ var init_slack = __esm(() => {
|
|
|
14530
14577
|
};
|
|
14531
14578
|
});
|
|
14532
14579
|
|
|
14533
|
-
// src/datasource/skills/spotlight/connector.ts
|
|
14534
|
-
import { spawn as spawn13 } from "node:child_process";
|
|
14535
|
-
import { createHash as createHash10 } from "node:crypto";
|
|
14536
|
-
import { readFile as fsReadFile, stat as stat2 } from "node:fs/promises";
|
|
14537
|
-
import { basename as basename6, extname as extname6 } from "node:path";
|
|
14538
|
-
|
|
14539
|
-
class SpotlightConnector {
|
|
14540
|
-
options;
|
|
14541
|
-
run;
|
|
14542
|
-
readFile;
|
|
14543
|
-
platform;
|
|
14544
|
-
constructor(options = {}) {
|
|
14545
|
-
this.options = options;
|
|
14546
|
-
this.run = options.run ?? spawnRunner;
|
|
14547
|
-
this.readFile = options.readFile ?? ((path) => fsReadFile(path, "utf8"));
|
|
14548
|
-
this.platform = options.platform ?? process.platform;
|
|
14549
|
-
}
|
|
14550
|
-
async probe() {
|
|
14551
|
-
const queries = (this.options.queries ?? []).map((query) => query.trim()).filter((query) => query.length > 0);
|
|
14552
|
-
const failure = await this.readinessFailure(queries);
|
|
14553
|
-
return failure ?? { ok: true, documents: [] };
|
|
14554
|
-
}
|
|
14555
|
-
async search(query, limit = DEFAULT_MAX_DOCUMENTS4, acceptDocument) {
|
|
14556
|
-
const trimmed = query.trim();
|
|
14557
|
-
if (trimmed.length === 0 || limit <= 0)
|
|
14558
|
-
return { ok: true, documents: [] };
|
|
14559
|
-
const queries = (this.options.queries ?? []).map((query) => query.trim()).filter((query) => query.length > 0);
|
|
14560
|
-
const failure = await this.readinessFailure(queries);
|
|
14561
|
-
if (failure !== undefined)
|
|
14562
|
-
return failure;
|
|
14563
|
-
const timeoutMs = this.options.timeoutMs ?? DEFAULT_TIMEOUT_MS8;
|
|
14564
|
-
const maxPerQuery = this.options.maxResultsPerQuery ?? DEFAULT_MAX_RESULTS_PER_QUERY;
|
|
14565
|
-
const maxDocuments = Math.min(this.options.maxDocuments ?? DEFAULT_MAX_DOCUMENTS4, limit);
|
|
14566
|
-
const seen = new Set;
|
|
14567
|
-
const paths = [];
|
|
14568
|
-
const textQuery = trimmed.split(/\s+/u).map((term) => `"${term.replace(/\\/gu, "\\\\").replace(/"/gu, "\\\"")}"`).join(" AND ");
|
|
14569
|
-
let mdfindMissing = false;
|
|
14570
|
-
let failedQueries = 0;
|
|
14571
|
-
const failures = [];
|
|
14572
|
-
for (const filter of queries) {
|
|
14573
|
-
const query = `(${filter}) AND (${textQuery})`;
|
|
14574
|
-
const args = this.options.onlyIn !== undefined ? ["-onlyin", this.options.onlyIn, query] : [query];
|
|
14575
|
-
const result = await this.run("mdfind", args, timeoutMs);
|
|
14576
|
-
if (!result.ok) {
|
|
14577
|
-
if (result.error === "ENOENT") {
|
|
14578
|
-
mdfindMissing = true;
|
|
14579
|
-
break;
|
|
14580
|
-
}
|
|
14581
|
-
failedQueries += 1;
|
|
14582
|
-
failures.push(result);
|
|
14583
|
-
continue;
|
|
14584
|
-
}
|
|
14585
|
-
let kept = 0;
|
|
14586
|
-
for (const line of result.stdout.split(`
|
|
14587
|
-
`)) {
|
|
14588
|
-
const path = line.trim();
|
|
14589
|
-
if (path.length === 0 || seen.has(path))
|
|
14590
|
-
continue;
|
|
14591
|
-
if (kept >= maxPerQuery)
|
|
14592
|
-
break;
|
|
14593
|
-
seen.add(path);
|
|
14594
|
-
paths.push(path);
|
|
14595
|
-
kept += 1;
|
|
14596
|
-
}
|
|
14597
|
-
}
|
|
14598
|
-
if (mdfindMissing) {
|
|
14599
|
-
return { ok: false, reason: "unavailable", message: "mdfind binary not found; Spotlight requires macOS" };
|
|
14600
|
-
}
|
|
14601
|
-
if (failedQueries === queries.length) {
|
|
14602
|
-
return {
|
|
14603
|
-
ok: false,
|
|
14604
|
-
reason: "unavailable",
|
|
14605
|
-
message: "every configured mdfind query failed",
|
|
14606
|
-
stderr: failures[0]?.stderr,
|
|
14607
|
-
stdout: failures[0]?.stdout,
|
|
14608
|
-
code: failures[0]?.code
|
|
14609
|
-
};
|
|
14610
|
-
}
|
|
14611
|
-
const documents = [];
|
|
14612
|
-
let permissionDenied = 0;
|
|
14613
|
-
let readFailures = 0;
|
|
14614
|
-
const maxBytes = this.options.maxBytesPerFile ?? DEFAULT_MAX_BYTES_PER_FILE2;
|
|
14615
|
-
const maxContentChars = this.options.maxContentChars ?? MAX_CONTENT_CHARS3;
|
|
14616
|
-
for (const path of paths) {
|
|
14617
|
-
if (documents.length >= maxDocuments)
|
|
14618
|
-
break;
|
|
14619
|
-
const docId = createHash10("sha256").update(path).digest("hex").slice(0, 16);
|
|
14620
|
-
if (acceptDocument !== undefined && !acceptDocument(docId))
|
|
14621
|
-
continue;
|
|
14622
|
-
try {
|
|
14623
|
-
const info = await stat2(path);
|
|
14624
|
-
if (!info.isFile() || info.size > maxBytes)
|
|
14625
|
-
continue;
|
|
14626
|
-
const text = await this.readFile(path);
|
|
14627
|
-
const content = text.trim().slice(0, maxContentChars);
|
|
14628
|
-
if (content.length === 0)
|
|
14629
|
-
continue;
|
|
14630
|
-
documents.push({
|
|
14631
|
-
docId,
|
|
14632
|
-
hierarchy: ["files"],
|
|
14633
|
-
title: basename6(path),
|
|
14634
|
-
content,
|
|
14635
|
-
publishedAt: info.mtimeMs,
|
|
14636
|
-
metadata: { path, extension: extname6(path).toLowerCase() }
|
|
14637
|
-
});
|
|
14638
|
-
} catch (error) {
|
|
14639
|
-
const code = error.code;
|
|
14640
|
-
if (code === "EPERM" || code === "EACCES")
|
|
14641
|
-
permissionDenied += 1;
|
|
14642
|
-
else
|
|
14643
|
-
readFailures += 1;
|
|
14644
|
-
}
|
|
14645
|
-
}
|
|
14646
|
-
if (documents.length === 0 && permissionDenied > 0) {
|
|
14647
|
-
return {
|
|
14648
|
-
ok: false,
|
|
14649
|
-
reason: "permission",
|
|
14650
|
-
message: `macOS denied access to all Spotlight hits; ${FDA_GUIDANCE}`
|
|
14651
|
-
};
|
|
14652
|
-
}
|
|
14653
|
-
if (documents.length === 0 && failedQueries > 0) {
|
|
14654
|
-
return {
|
|
14655
|
-
ok: false,
|
|
14656
|
-
reason: "unavailable",
|
|
14657
|
-
message: "some mdfind queries failed and no readable hits remained",
|
|
14658
|
-
stderr: failures[0]?.stderr,
|
|
14659
|
-
stdout: failures[0]?.stdout,
|
|
14660
|
-
code: failures[0]?.code
|
|
14661
|
-
};
|
|
14662
|
-
}
|
|
14663
|
-
const warnings = [];
|
|
14664
|
-
if (failedQueries > 0)
|
|
14665
|
-
warnings.push(`${failedQueries} mdfind quer(y/ies) failed`);
|
|
14666
|
-
if (permissionDenied > 0) {
|
|
14667
|
-
warnings.push(`${permissionDenied} Spotlight hit(s) were denied by macOS privacy protections; ${FDA_GUIDANCE}`);
|
|
14668
|
-
}
|
|
14669
|
-
if (readFailures > 0)
|
|
14670
|
-
warnings.push(`${readFailures} Spotlight hit(s) failed to read`);
|
|
14671
|
-
return { ok: true, documents, ...warnings.length > 0 ? { warnings } : {} };
|
|
14672
|
-
}
|
|
14673
|
-
async readinessFailure(queries) {
|
|
14674
|
-
if (this.platform !== "darwin") {
|
|
14675
|
-
return { ok: false, reason: "unavailable", message: "spotlight datasource is supported on macOS only" };
|
|
14676
|
-
}
|
|
14677
|
-
if (queries.length === 0) {
|
|
14678
|
-
return { ok: false, reason: "not-configured", message: "no spotlight queries configured" };
|
|
14679
|
-
}
|
|
14680
|
-
const timeoutMs = this.options.timeoutMs ?? DEFAULT_TIMEOUT_MS8;
|
|
14681
|
-
const status = await this.run("mdutil", ["-s", "/"], timeoutMs);
|
|
14682
|
-
if (status.ok && /indexing disabled/iu.test(status.stdout)) {
|
|
14683
|
-
return {
|
|
14684
|
-
ok: false,
|
|
14685
|
-
reason: "unavailable",
|
|
14686
|
-
message: "Spotlight indexing is disabled; enable it with `sudo mdutil -i on /`"
|
|
14687
|
-
};
|
|
14688
|
-
}
|
|
14689
|
-
return;
|
|
14690
|
-
}
|
|
14691
|
-
}
|
|
14692
|
-
var DEFAULT_MAX_RESULTS_PER_QUERY = 100, DEFAULT_MAX_DOCUMENTS4 = 300, DEFAULT_MAX_BYTES_PER_FILE2, DEFAULT_TIMEOUT_MS8 = 15000, MAX_CONTENT_CHARS3 = 1e5, MAX_BUFFER_BYTES, FDA_GUIDANCE = "grant Full Disk Access to the terminal or app running AutoRAG (System Settings -> Privacy & Security -> Full Disk Access), then restart it", spawnRunner = (command, args, timeoutMs) => new Promise((resolve) => {
|
|
14693
|
-
const child = spawn13(command, [...args], { stdio: ["ignore", "pipe", "pipe"] });
|
|
14694
|
-
let stdout = "";
|
|
14695
|
-
let stderr = "";
|
|
14696
|
-
let settled = false;
|
|
14697
|
-
const finish = (result) => {
|
|
14698
|
-
if (settled)
|
|
14699
|
-
return;
|
|
14700
|
-
settled = true;
|
|
14701
|
-
clearTimeout(timer);
|
|
14702
|
-
resolve(result);
|
|
14703
|
-
};
|
|
14704
|
-
const timer = setTimeout(() => {
|
|
14705
|
-
child.kill("SIGKILL");
|
|
14706
|
-
finish({ ok: false, stdout, stderr: "process timed out", code: null });
|
|
14707
|
-
}, timeoutMs);
|
|
14708
|
-
child.stdout.setEncoding("utf8");
|
|
14709
|
-
child.stderr.setEncoding("utf8");
|
|
14710
|
-
child.stdout.on("data", (chunk) => {
|
|
14711
|
-
if (stdout.length < MAX_BUFFER_BYTES)
|
|
14712
|
-
stdout += chunk;
|
|
14713
|
-
});
|
|
14714
|
-
child.stderr.on("data", (chunk) => {
|
|
14715
|
-
if (stderr.length < MAX_BUFFER_BYTES)
|
|
14716
|
-
stderr += chunk;
|
|
14717
|
-
});
|
|
14718
|
-
child.on("error", (error) => {
|
|
14719
|
-
finish({ ok: false, stdout, stderr: error.message, code: null, error: error.code });
|
|
14720
|
-
});
|
|
14721
|
-
child.on("close", (code) => {
|
|
14722
|
-
finish({ ok: code === 0, stdout, stderr, code });
|
|
14723
|
-
});
|
|
14724
|
-
});
|
|
14725
|
-
var init_connector5 = __esm(() => {
|
|
14726
|
-
DEFAULT_MAX_BYTES_PER_FILE2 = 256 * 1024;
|
|
14727
|
-
MAX_BUFFER_BYTES = 4 * 1024 * 1024;
|
|
14728
|
-
});
|
|
14729
|
-
|
|
14730
|
-
// src/datasource/skills/spotlight/skill.ts
|
|
14731
|
-
class SpotlightSkill {
|
|
14732
|
-
connector;
|
|
14733
|
-
skillName;
|
|
14734
|
-
instanceId;
|
|
14735
|
-
instances;
|
|
14736
|
-
tags;
|
|
14737
|
-
lastIndexedAt;
|
|
14738
|
-
lastError;
|
|
14739
|
-
constructor(options = {}) {
|
|
14740
|
-
this.skillName = options.skillName ?? "spotlight";
|
|
14741
|
-
this.instanceId = options.instanceId ?? "default";
|
|
14742
|
-
this.instances = options.instances !== undefined && options.instances.length > 0 ? options.instances : [this.instanceId];
|
|
14743
|
-
this.tags = options.tags ?? DEFAULT_TAGS4;
|
|
14744
|
-
this.connector = options.connector ?? new SpotlightConnector(options.connectorOptions ?? {});
|
|
14745
|
-
}
|
|
14746
|
-
describe() {
|
|
14747
|
-
return {
|
|
14748
|
-
name: this.skillName,
|
|
14749
|
-
id: this.skillName,
|
|
14750
|
-
type: "spotlight-search",
|
|
14751
|
-
description: "Live macOS Spotlight search via the built-in mdfind CLI",
|
|
14752
|
-
capabilities: ["files", "macos-only", "local-search", "live-search", "scoped", "external-cli"],
|
|
14753
|
-
tags: this.tags,
|
|
14754
|
-
status: "active",
|
|
14755
|
-
requiresExternalCli: true,
|
|
14756
|
-
datasourceId: this.skillName,
|
|
14757
|
-
instanceId: this.instanceId,
|
|
14758
|
-
instances: this.instances
|
|
14759
|
-
};
|
|
14760
|
-
}
|
|
14761
|
-
polling() {
|
|
14762
|
-
return {
|
|
14763
|
-
mode: "none",
|
|
14764
|
-
...this.lastIndexedAt !== undefined ? { lastIndexedAt: this.lastIndexedAt } : {},
|
|
14765
|
-
...this.lastError !== undefined ? { lastError: this.lastError } : {}
|
|
14766
|
-
};
|
|
14767
|
-
}
|
|
14768
|
-
async index() {
|
|
14769
|
-
try {
|
|
14770
|
-
const result = await this.connector.probe();
|
|
14771
|
-
if (!result.ok) {
|
|
14772
|
-
const code = connectorFailureToDiagnosticCode(result.reason);
|
|
14773
|
-
const message = boundDiagnosticText(result.message ?? result.reason);
|
|
14774
|
-
this.lastError = message;
|
|
14775
|
-
return this.fail(code, message);
|
|
14776
|
-
}
|
|
14777
|
-
this.lastError = undefined;
|
|
14778
|
-
this.lastIndexedAt = Date.now();
|
|
14779
|
-
return {
|
|
14780
|
-
ok: true,
|
|
14781
|
-
instanceId: this.instanceId,
|
|
14782
|
-
skill: this.skillName,
|
|
14783
|
-
chunkCount: 0,
|
|
14784
|
-
indexedAt: this.lastIndexedAt,
|
|
14785
|
-
diagnostics: [this.note(LIVE_NOTE, "datasource-empty", "info")]
|
|
14786
|
-
};
|
|
14787
|
-
} catch (error) {
|
|
14788
|
-
const message = boundDiagnosticText(error instanceof Error ? error.message : "spotlight probe failed");
|
|
14789
|
-
this.lastError = message;
|
|
14790
|
-
return this.fail("datasource-unavailable", message);
|
|
14791
|
-
}
|
|
14792
|
-
}
|
|
14793
|
-
retrievalMethods() {
|
|
14794
|
-
return [new SpotlightLiveMethod(this)];
|
|
14795
|
-
}
|
|
14796
|
-
describeSources() {
|
|
14797
|
-
return this.instances.map((instanceId) => ({
|
|
14798
|
-
source: datasourceSourcePath(this.skillName, instanceId),
|
|
14799
|
-
datasourceId: this.skillName,
|
|
14800
|
-
skill: this.skillName,
|
|
14801
|
-
instanceId,
|
|
14802
|
-
contentType: "document",
|
|
14803
|
-
metadata: { datasourceId: this.skillName, instanceId, tags: this.tags }
|
|
14804
|
-
}));
|
|
14805
|
-
}
|
|
14806
|
-
skillManifest() {
|
|
14807
|
-
const scopes = this.instances.map((instanceId) => `- \`${datasourceSourcePath(this.skillName, instanceId)}\``).join(`
|
|
14808
|
-
`);
|
|
14809
|
-
return {
|
|
14810
|
-
name: `datasource-${this.skillName}`,
|
|
14811
|
-
description: "Search the current macOS Spotlight index directly. AutoRAG keeps no file snapshot.",
|
|
14812
|
-
content: [
|
|
14813
|
-
"# macOS Spotlight (live mdfind search)",
|
|
14814
|
-
"",
|
|
14815
|
-
"Search files indexed by macOS Spotlight via the built-in `mdfind` CLI. macOS owns and refreshes the index; AutoRAG does not copy files into a local snapshot.",
|
|
14816
|
-
"",
|
|
14817
|
-
"## Platform requirements",
|
|
14818
|
-
"- macOS only: this datasource is unavailable on any other platform.",
|
|
14819
|
-
"- Spotlight indexing must be enabled (`sudo mdutil -i on /`; check with `mdutil -s /`).",
|
|
14820
|
-
"- Full Disk Access may be required to read protected hits. Grant it under System Settings -> Privacy & Security -> Full Disk Access, then restart the host app.",
|
|
14821
|
-
"",
|
|
14822
|
-
"## How to search",
|
|
14823
|
-
`Call the dedicated \`${datasourceSearchToolName(this.skillName)}\` tool with a query and optional narrowing scope. Available scopes:`,
|
|
14824
|
-
scopes,
|
|
14825
|
-
"Each configured Spotlight filter is AND-ed with the user query. Only the requested hits are read; refresh performs a readiness probe without running `mdfind`.",
|
|
14826
|
-
"Result metadata carries the real absolute file path (`path`) so hits are traceable back to disk. If paths must not leave this machine, run AutoRAG with a local LLM.",
|
|
14827
|
-
"",
|
|
14828
|
-
"## Native CLI",
|
|
14829
|
-
"- `mdfind <query>` searches Spotlight; `mdfind -onlyin <dir> <query>` scopes to a directory; `mdfind -name <text>` matches file names.",
|
|
14830
|
-
"- `mdls <file>` shows Spotlight metadata for one file.",
|
|
14831
|
-
"- `mdutil -s /` checks index status; `sudo mdutil -i on /` enables indexing."
|
|
14832
|
-
].join(`
|
|
14833
|
-
`)
|
|
14834
|
-
};
|
|
14835
|
-
}
|
|
14836
|
-
async search(query, options) {
|
|
14837
|
-
const trimmed = query.trim();
|
|
14838
|
-
if (trimmed.length === 0)
|
|
14839
|
-
return [];
|
|
14840
|
-
const scope = options.scope?.trim() ? normalizeVirtualPath2(options.scope) : undefined;
|
|
14841
|
-
if (scope !== undefined) {
|
|
14842
|
-
const chunksRoot = normalizeVirtualPath2(`/${this.skillName}/${this.instanceId}/chunks`);
|
|
14843
|
-
const scopeProbe = datasourceSourcePath(this.skillName, this.instanceId, "__scope_probe__");
|
|
14844
|
-
if (!matchesDatasourceScope(chunksRoot, scope) && !matchesDatasourceScope(scopeProbe, scope) && !scope.startsWith(`${chunksRoot}/`)) {
|
|
14845
|
-
return [];
|
|
14846
|
-
}
|
|
14847
|
-
}
|
|
14848
|
-
const topK = options.topK ?? DEFAULT_TOP_K9;
|
|
14849
|
-
const result = await this.connector.search(trimmed, topK, (docId) => matchesDatasourceScope(datasourceSourcePath(this.skillName, this.instanceId, docId), scope));
|
|
14850
|
-
if (!result.ok) {
|
|
14851
|
-
throw datasourceCliError(this.skillName, "search", {
|
|
14852
|
-
reason: result.reason,
|
|
14853
|
-
stderr: result.stderr ?? result.message,
|
|
14854
|
-
stdout: result.stdout,
|
|
14855
|
-
code: result.code
|
|
14856
|
-
});
|
|
14857
|
-
}
|
|
14858
|
-
const hits = [];
|
|
14859
|
-
for (const [index, document] of result.documents.entries()) {
|
|
14860
|
-
const source = datasourceSourcePath(this.skillName, this.instanceId, document.docId);
|
|
14861
|
-
if (!matchesDatasourceScope(source, options.scope))
|
|
14862
|
-
continue;
|
|
14863
|
-
hits.push({
|
|
14864
|
-
id: `${this.skillName}:${this.instanceId}:${document.docId}`,
|
|
14865
|
-
content: document.content,
|
|
14866
|
-
source,
|
|
14867
|
-
score: 1 / (index + 1),
|
|
14868
|
-
metadata: {
|
|
14869
|
-
...document.metadata,
|
|
14870
|
-
method: `${this.skillName}-live`,
|
|
14871
|
-
datasourceId: this.skillName,
|
|
14872
|
-
instanceId: this.instanceId,
|
|
14873
|
-
chunkId: document.docId,
|
|
14874
|
-
...document.title !== undefined ? { title: document.title } : {},
|
|
14875
|
-
...document.hierarchy !== undefined && document.hierarchy.length > 0 ? { hierarchy: document.hierarchy.join("/") } : {},
|
|
14876
|
-
...document.publishedAt !== undefined ? { publishedAt: document.publishedAt } : {},
|
|
14877
|
-
...result.warnings !== undefined && result.warnings.length > 0 ? { warnings: result.warnings } : {}
|
|
14878
|
-
}
|
|
14879
|
-
});
|
|
14880
|
-
if (hits.length >= topK)
|
|
14881
|
-
break;
|
|
14882
|
-
}
|
|
14883
|
-
return hits;
|
|
14884
|
-
}
|
|
14885
|
-
fail(code, message) {
|
|
14886
|
-
return {
|
|
14887
|
-
ok: false,
|
|
14888
|
-
instanceId: this.instanceId,
|
|
14889
|
-
skill: this.skillName,
|
|
14890
|
-
indexedAt: Date.now(),
|
|
14891
|
-
diagnostics: [
|
|
14892
|
-
this.note(message, code, code === "datasource-unavailable" || code === "datasource-empty" ? "warning" : "error")
|
|
14893
|
-
],
|
|
14894
|
-
error: message,
|
|
14895
|
-
code,
|
|
14896
|
-
message
|
|
14897
|
-
};
|
|
14898
|
-
}
|
|
14899
|
-
note(message, code, severity) {
|
|
14900
|
-
return { code, severity, message, instanceId: this.instanceId, source: this.skillName };
|
|
14901
|
-
}
|
|
14902
|
-
}
|
|
14903
|
-
|
|
14904
|
-
class SpotlightLiveMethod {
|
|
14905
|
-
skill;
|
|
14906
|
-
constructor(skill) {
|
|
14907
|
-
this.skill = skill;
|
|
14908
|
-
}
|
|
14909
|
-
describe() {
|
|
14910
|
-
const descriptor = this.skill.describe();
|
|
14911
|
-
return {
|
|
14912
|
-
name: `${descriptor.datasourceId ?? "spotlight"}-live`,
|
|
14913
|
-
type: "remote",
|
|
14914
|
-
description: "Live macOS Spotlight search via mdfind",
|
|
14915
|
-
status: "active",
|
|
14916
|
-
capabilities: ["live-search", "scoped", "external-cli", "path-opaque-sources"],
|
|
14917
|
-
datasourceId: descriptor.datasourceId,
|
|
14918
|
-
tags: descriptor.tags
|
|
14919
|
-
};
|
|
14920
|
-
}
|
|
14921
|
-
retrieve(query, options) {
|
|
14922
|
-
return this.skill.search(query, options);
|
|
14923
|
-
}
|
|
14924
|
-
}
|
|
14925
|
-
var DEFAULT_TAGS4, DEFAULT_TOP_K9 = 20, LIVE_NOTE = "live-search datasource: macOS owns the Spotlight index; AutoRAG stores no snapshot";
|
|
14926
|
-
var init_skill12 = __esm(() => {
|
|
14927
|
-
init_connector();
|
|
14928
|
-
init_errors2();
|
|
14929
|
-
init_scope2();
|
|
14930
|
-
init_connector5();
|
|
14931
|
-
DEFAULT_TAGS4 = ["spotlight", "files"];
|
|
14932
|
-
});
|
|
14933
|
-
|
|
14934
|
-
// src/datasource/skills/spotlight/index.ts
|
|
14935
|
-
var init_spotlight = __esm(() => {
|
|
14936
|
-
init_connector5();
|
|
14937
|
-
init_skill12();
|
|
14938
|
-
});
|
|
14939
|
-
|
|
14940
14580
|
// src/datasource/skills/telecrawl/index.ts
|
|
14941
14581
|
function globalArgs3(options) {
|
|
14942
14582
|
return [
|
|
@@ -15341,7 +14981,6 @@ var init_factory = __esm(() => {
|
|
|
15341
14981
|
init_obsidian();
|
|
15342
14982
|
init_rss();
|
|
15343
14983
|
init_slack();
|
|
15344
|
-
init_spotlight();
|
|
15345
14984
|
init_telecrawl();
|
|
15346
14985
|
init_wacrawl();
|
|
15347
14986
|
BUILDERS = {
|
|
@@ -15478,12 +15117,6 @@ var init_factory = __esm(() => {
|
|
|
15478
15117
|
...common(config, workspaceRoot),
|
|
15479
15118
|
skillName: registrationName,
|
|
15480
15119
|
connectorOptions: config.connector
|
|
15481
|
-
}),
|
|
15482
|
-
spotlight: (config, _workspaceRoot, registrationName) => new SpotlightSkill({
|
|
15483
|
-
...config.instanceId !== undefined ? { instanceId: config.instanceId } : {},
|
|
15484
|
-
...config.tags !== undefined ? { tags: config.tags } : {},
|
|
15485
|
-
skillName: registrationName,
|
|
15486
|
-
connectorOptions: config.connector
|
|
15487
15120
|
})
|
|
15488
15121
|
};
|
|
15489
15122
|
PLATFORM_ONLY_SKILLS = { kakao: "darwin" };
|
|
@@ -15765,7 +15398,7 @@ var init_types3 = __esm(() => {
|
|
|
15765
15398
|
// src/cli/config.ts
|
|
15766
15399
|
import { randomUUID as randomUUID4 } from "node:crypto";
|
|
15767
15400
|
import { existsSync as existsSync16, mkdirSync as mkdirSync14, readFileSync as readFileSync19, unlinkSync as unlinkSync2, writeFileSync as writeFileSync10 } from "node:fs";
|
|
15768
|
-
import { basename as
|
|
15401
|
+
import { basename as basename6, dirname as dirname15, isAbsolute as isAbsolute6, join as join27, resolve as resolve7 } from "node:path";
|
|
15769
15402
|
import { findEnvKeys, getEnvApiKey } from "@earendil-works/pi-ai/compat";
|
|
15770
15403
|
import { getAgentDir as getAgentDir2, ModelRuntime, SettingsManager } from "@earendil-works/pi-coding-agent";
|
|
15771
15404
|
function resolveConfigPath(input) {
|
|
@@ -15839,7 +15472,7 @@ function acquireConfigWriteLock(configPath) {
|
|
|
15839
15472
|
});
|
|
15840
15473
|
}
|
|
15841
15474
|
function replaceFileAtomically(path, contents, assertCommitAllowed) {
|
|
15842
|
-
const temporaryPath = join27(dirname15(path), `.${
|
|
15475
|
+
const temporaryPath = join27(dirname15(path), `.${basename6(path)}.${process.pid}.${randomUUID4()}.tmp`);
|
|
15843
15476
|
try {
|
|
15844
15477
|
writeFileSync10(temporaryPath, contents, { encoding: "utf8", flag: "wx", flush: true, mode: 384 });
|
|
15845
15478
|
assertCommitAllowed?.();
|
|
@@ -17351,7 +16984,7 @@ function loopGuardPrompt(rule) {
|
|
|
17351
16984
|
}
|
|
17352
16985
|
|
|
17353
16986
|
// src/convert/cli.ts
|
|
17354
|
-
import { spawn as
|
|
16987
|
+
import { spawn as spawn13 } from "node:child_process";
|
|
17355
16988
|
import { accessSync as accessSync2, constants as constants2, existsSync as existsSync17 } from "node:fs";
|
|
17356
16989
|
import { delimiter as delimiter4, dirname as dirname16, join as join29, resolve as resolve8 } from "node:path";
|
|
17357
16990
|
async function convertWithFilee(request, options = {}) {
|
|
@@ -17429,7 +17062,7 @@ function spawnFilee(executable, args, options) {
|
|
|
17429
17062
|
}
|
|
17430
17063
|
const portable = portableSpawnCommand(executable, args);
|
|
17431
17064
|
const env = options.dataDir === undefined ? process.env : { ...process.env, FILEE_DATA_DIR: resolve8(options.dataDir) };
|
|
17432
|
-
const child =
|
|
17065
|
+
const child = spawn13(portable.command, [...portable.args], {
|
|
17433
17066
|
cwd: options.cwd,
|
|
17434
17067
|
env,
|
|
17435
17068
|
stdio: ["ignore", "pipe", "pipe"]
|
|
@@ -17501,7 +17134,7 @@ var init_cli = __esm(() => {
|
|
|
17501
17134
|
});
|
|
17502
17135
|
|
|
17503
17136
|
// src/convert/installer.ts
|
|
17504
|
-
import { createHash as
|
|
17137
|
+
import { createHash as createHash10 } from "node:crypto";
|
|
17505
17138
|
import { createReadStream as createReadStream2, createWriteStream as createWriteStream2, existsSync as existsSync18, mkdirSync as mkdirSync15, readdirSync as readdirSync4, renameSync as renameSync4, rmSync as rmSync6 } from "node:fs";
|
|
17506
17139
|
import { mkdtemp as mkdtemp2 } from "node:fs/promises";
|
|
17507
17140
|
import { join as join30 } from "node:path";
|
|
@@ -17574,7 +17207,7 @@ async function downloadFile2(url, destination) {
|
|
|
17574
17207
|
await pipeline2(Readable.fromWeb(response.body), createWriteStream2(destination));
|
|
17575
17208
|
}
|
|
17576
17209
|
async function verifySha2562(path, expected, name) {
|
|
17577
|
-
const hash =
|
|
17210
|
+
const hash = createHash10("sha256");
|
|
17578
17211
|
await pipeline2(createReadStream2(path), hash);
|
|
17579
17212
|
const actual = hash.digest("hex");
|
|
17580
17213
|
if (actual !== expected) {
|
|
@@ -18118,7 +17751,7 @@ var init_matrix = __esm(() => {
|
|
|
18118
17751
|
});
|
|
18119
17752
|
|
|
18120
17753
|
// src/dupey/cli.ts
|
|
18121
|
-
import { spawn as
|
|
17754
|
+
import { spawn as spawn14 } from "node:child_process";
|
|
18122
17755
|
import { resolve as resolve9 } from "node:path";
|
|
18123
17756
|
function runDupey(args, options) {
|
|
18124
17757
|
return options.run ? options.run(args) : spawnDupey(options.executable ?? "dupey", args, options);
|
|
@@ -18190,7 +17823,7 @@ function isScanResult(value) {
|
|
|
18190
17823
|
function spawnDupey(executable, args, options) {
|
|
18191
17824
|
return new Promise((resolveOutput, reject) => {
|
|
18192
17825
|
const portable = portableSpawnCommand(executable, args);
|
|
18193
|
-
const child =
|
|
17826
|
+
const child = spawn14(portable.command, [...portable.args], {
|
|
18194
17827
|
cwd: options.cwd,
|
|
18195
17828
|
stdio: ["ignore", "pipe", "pipe"]
|
|
18196
17829
|
});
|
|
@@ -18238,7 +17871,7 @@ var init_cli2 = __esm(() => {
|
|
|
18238
17871
|
});
|
|
18239
17872
|
|
|
18240
17873
|
// src/dupey/filter.ts
|
|
18241
|
-
import { stat as
|
|
17874
|
+
import { stat as stat2 } from "node:fs/promises";
|
|
18242
17875
|
import { resolve as resolve10 } from "node:path";
|
|
18243
17876
|
async function selectExactDuplicateExclusions(root, scan, isUnavailable) {
|
|
18244
17877
|
const byHash = new Map;
|
|
@@ -18293,7 +17926,7 @@ async function rankExactCandidates(paths, dupeyRanking, errors) {
|
|
|
18293
17926
|
}
|
|
18294
17927
|
const ranked = await Promise.all(paths.map(async (path) => {
|
|
18295
17928
|
try {
|
|
18296
|
-
const info = await
|
|
17929
|
+
const info = await stat2(path);
|
|
18297
17930
|
return { path, mtimeMs: info.mtimeMs };
|
|
18298
17931
|
} catch {
|
|
18299
17932
|
errors.push("dupey exact duplicate path disappeared before indexing.");
|
|
@@ -18462,7 +18095,7 @@ var init_retry = __esm(() => {
|
|
|
18462
18095
|
});
|
|
18463
18096
|
|
|
18464
18097
|
// src/everything/bundle.ts
|
|
18465
|
-
import { createHash as
|
|
18098
|
+
import { createHash as createHash11 } from "node:crypto";
|
|
18466
18099
|
import { existsSync as existsSync19, mkdirSync as mkdirSync16, readFileSync as readFileSync20, rmSync as rmSync7, writeFileSync as writeFileSync11 } from "node:fs";
|
|
18467
18100
|
import { dirname as dirname17, join as join31 } from "node:path";
|
|
18468
18101
|
import { fileURLToPath as fileURLToPath2 } from "node:url";
|
|
@@ -18580,7 +18213,7 @@ function writeAtomic(path, bytes) {
|
|
|
18580
18213
|
}
|
|
18581
18214
|
}
|
|
18582
18215
|
function sha256(bytes) {
|
|
18583
|
-
return
|
|
18216
|
+
return createHash11("sha256").update(bytes).digest("hex");
|
|
18584
18217
|
}
|
|
18585
18218
|
function errorMessage2(error) {
|
|
18586
18219
|
return error instanceof Error ? error.message : String(error);
|
|
@@ -18610,13 +18243,13 @@ function createPathExclusionMatcher(excludedPaths, platform = process.platform)
|
|
|
18610
18243
|
var init_path_exclusions = () => {};
|
|
18611
18244
|
|
|
18612
18245
|
// src/everything/client.ts
|
|
18613
|
-
import { spawn as
|
|
18614
|
-
import { createHash as
|
|
18246
|
+
import { spawn as spawn15 } from "node:child_process";
|
|
18247
|
+
import { createHash as createHash12 } from "node:crypto";
|
|
18615
18248
|
import { mkdirSync as mkdirSync17, writeFileSync as writeFileSync12 } from "node:fs";
|
|
18616
18249
|
import { join as join32, resolve as resolve11 } from "node:path";
|
|
18617
18250
|
import { setTimeout as sleep } from "node:timers/promises";
|
|
18618
18251
|
function everythingInstanceName(root) {
|
|
18619
|
-
return `autorag-${
|
|
18252
|
+
return `autorag-${createHash12("sha256").update(resolve11(root).toLowerCase()).digest("hex").slice(0, 12)}`;
|
|
18620
18253
|
}
|
|
18621
18254
|
function buildEverythingIni(input) {
|
|
18622
18255
|
const list = (values) => values.map((value) => `"${value.replace(/\\/g, "\\\\")}"`).join(",");
|
|
@@ -18755,7 +18388,7 @@ class EverythingClient {
|
|
|
18755
18388
|
};
|
|
18756
18389
|
}
|
|
18757
18390
|
const es = { ok: true, esPath: binaries.esPath };
|
|
18758
|
-
const timeoutMs = this.options.timeoutMs ??
|
|
18391
|
+
const timeoutMs = this.options.timeoutMs ?? DEFAULT_TIMEOUT_MS8;
|
|
18759
18392
|
if ((this.options.excludeFolders?.length ?? 0) > 0) {
|
|
18760
18393
|
return this.searchWithExclusions(es.esPath, request, timeoutMs);
|
|
18761
18394
|
}
|
|
@@ -18840,7 +18473,7 @@ class EverythingClient {
|
|
|
18840
18473
|
const binaries = await this.resolveBinaries("cached");
|
|
18841
18474
|
if (!binaries.ok)
|
|
18842
18475
|
return;
|
|
18843
|
-
await this.run(binaries.esPath, ["-instance", this.instanceName, "-exit"], this.options.timeoutMs ??
|
|
18476
|
+
await this.run(binaries.esPath, ["-instance", this.instanceName, "-exit"], this.options.timeoutMs ?? DEFAULT_TIMEOUT_MS8);
|
|
18844
18477
|
});
|
|
18845
18478
|
}
|
|
18846
18479
|
serialize(task) {
|
|
@@ -18870,7 +18503,7 @@ class EverythingClient {
|
|
|
18870
18503
|
const binaries = await this.resolveBinaries("install");
|
|
18871
18504
|
if (!binaries.ok)
|
|
18872
18505
|
return binaries;
|
|
18873
|
-
const timeoutMs = this.options.timeoutMs ??
|
|
18506
|
+
const timeoutMs = this.options.timeoutMs ?? DEFAULT_TIMEOUT_MS8;
|
|
18874
18507
|
let ping = await this.ping(binaries.esPath);
|
|
18875
18508
|
if (ping.code === 0 && !reconfigure)
|
|
18876
18509
|
return { ok: true, esPath: binaries.esPath };
|
|
@@ -18927,7 +18560,7 @@ class EverythingClient {
|
|
|
18927
18560
|
};
|
|
18928
18561
|
}
|
|
18929
18562
|
async ping(esPath) {
|
|
18930
|
-
const result = await this.run(esPath, ["-instance", this.instanceName, "-get-everything-version"], this.options.timeoutMs ??
|
|
18563
|
+
const result = await this.run(esPath, ["-instance", this.instanceName, "-get-everything-version"], this.options.timeoutMs ?? DEFAULT_TIMEOUT_MS8);
|
|
18931
18564
|
return result.code === 0 && !VERSION_PATTERN.test(result.stdout.trim()) ? { ...result, code: -1 } : result;
|
|
18932
18565
|
}
|
|
18933
18566
|
failure(reason, esPath, args, result) {
|
|
@@ -18943,7 +18576,7 @@ function runProcess(command, args, timeoutMs) {
|
|
|
18943
18576
|
const promise = new Promise((resolve) => {
|
|
18944
18577
|
resolvePromise = resolve;
|
|
18945
18578
|
});
|
|
18946
|
-
const child =
|
|
18579
|
+
const child = spawn15(command, args, { windowsHide: true, stdio: ["ignore", "pipe", "pipe"] });
|
|
18947
18580
|
const stdout = [];
|
|
18948
18581
|
const stderr = [];
|
|
18949
18582
|
let bytes = 0;
|
|
@@ -18978,11 +18611,11 @@ killed by ${signal} after ${timeoutMs}ms` : err
|
|
|
18978
18611
|
return promise;
|
|
18979
18612
|
}
|
|
18980
18613
|
function launchDetached(command, args) {
|
|
18981
|
-
const child =
|
|
18614
|
+
const child = spawn15(command, args, { detached: true, stdio: "ignore", windowsHide: true });
|
|
18982
18615
|
child.on("error", () => {});
|
|
18983
18616
|
child.unref();
|
|
18984
18617
|
}
|
|
18985
|
-
var
|
|
18618
|
+
var DEFAULT_TIMEOUT_MS8 = 30000, DEFAULT_STARTUP_TIMEOUT_MS = 20000, DEFAULT_INDEX_TIMEOUT_MS2, DEFAULT_POLL_INTERVAL_MS = 250, DEFAULT_MAX_RESULTS = 100, MAX_FILTER_CANDIDATES = 1000, MAX_OUTPUT_BYTES, VERSION_PATTERN;
|
|
18986
18619
|
var init_client8 = __esm(() => {
|
|
18987
18620
|
init_path_exclusions();
|
|
18988
18621
|
init_bundle();
|
|
@@ -18998,8 +18631,8 @@ var init_everything = __esm(() => {
|
|
|
18998
18631
|
});
|
|
18999
18632
|
|
|
19000
18633
|
// src/fsearch/walk.ts
|
|
19001
|
-
import { readdir, stat as
|
|
19002
|
-
import { basename as
|
|
18634
|
+
import { readdir, stat as stat3 } from "node:fs/promises";
|
|
18635
|
+
import { basename as basename7, join as join33, sep as sep5 } from "node:path";
|
|
19003
18636
|
function compare(a, b) {
|
|
19004
18637
|
return a < b ? -1 : a > b ? 1 : 0;
|
|
19005
18638
|
}
|
|
@@ -19010,11 +18643,11 @@ async function walkFileSearch(folders, request, options = {}) {
|
|
|
19010
18643
|
const deadline = Date.now() + (options.deadlineMs ?? DEFAULT_DEADLINE_MS);
|
|
19011
18644
|
const matches = request.regex ? (() => {
|
|
19012
18645
|
const pattern = new RegExp(request.query, request.matchCase ? "" : "i");
|
|
19013
|
-
return (path) => pattern.test(request.matchPath ? path :
|
|
18646
|
+
return (path) => pattern.test(request.matchPath ? path : basename7(path));
|
|
19014
18647
|
})() : (() => {
|
|
19015
18648
|
const needle = request.matchCase ? request.query : request.query.toLowerCase();
|
|
19016
18649
|
return (path) => {
|
|
19017
|
-
const haystack = request.matchPath ? path :
|
|
18650
|
+
const haystack = request.matchPath ? path : basename7(path);
|
|
19018
18651
|
return (request.matchCase ? haystack : haystack.toLowerCase()).includes(needle);
|
|
19019
18652
|
};
|
|
19020
18653
|
})();
|
|
@@ -19062,14 +18695,14 @@ async function walkFileSearch(folders, request, options = {}) {
|
|
|
19062
18695
|
if (!matches(path))
|
|
19063
18696
|
continue;
|
|
19064
18697
|
try {
|
|
19065
|
-
const info = await
|
|
18698
|
+
const info = await stat3(path);
|
|
19066
18699
|
if (request.kind === "folders" && !info.isDirectory())
|
|
19067
18700
|
continue;
|
|
19068
18701
|
if (request.kind === "files" && info.isDirectory())
|
|
19069
18702
|
continue;
|
|
19070
18703
|
collected.push({
|
|
19071
18704
|
path,
|
|
19072
|
-
name:
|
|
18705
|
+
name: basename7(path),
|
|
19073
18706
|
type: info.isDirectory() ? "folder" : "file",
|
|
19074
18707
|
size: info.isDirectory() ? undefined : info.size,
|
|
19075
18708
|
dateModified: info.mtime.toISOString()
|
|
@@ -19089,12 +18722,12 @@ async function walkFileSearch(folders, request, options = {}) {
|
|
|
19089
18722
|
if (request.kind === "files")
|
|
19090
18723
|
continue;
|
|
19091
18724
|
try {
|
|
19092
|
-
const info = await
|
|
18725
|
+
const info = await stat3(folder);
|
|
19093
18726
|
if (!info.isDirectory())
|
|
19094
18727
|
continue;
|
|
19095
18728
|
collected.push({
|
|
19096
18729
|
path: folder,
|
|
19097
|
-
name:
|
|
18730
|
+
name: basename7(folder),
|
|
19098
18731
|
type: "folder",
|
|
19099
18732
|
size: undefined,
|
|
19100
18733
|
dateModified: info.mtime.toISOString()
|
|
@@ -19124,10 +18757,10 @@ var init_walk = __esm(() => {
|
|
|
19124
18757
|
});
|
|
19125
18758
|
|
|
19126
18759
|
// src/fsearch/client.ts
|
|
19127
|
-
import { spawn as
|
|
19128
|
-
import { createHash as
|
|
18760
|
+
import { spawn as spawn16 } from "node:child_process";
|
|
18761
|
+
import { createHash as createHash13 } from "node:crypto";
|
|
19129
18762
|
import { existsSync as existsSync20, mkdirSync as mkdirSync18, readFileSync as readFileSync21, realpathSync as realpathSync3, rmSync as rmSync8, writeFileSync as writeFileSync13 } from "node:fs";
|
|
19130
|
-
import { basename as
|
|
18763
|
+
import { basename as basename8, join as join34, resolve as resolve12, sep as sep6 } from "node:path";
|
|
19131
18764
|
import { setTimeout as sleep2 } from "node:timers/promises";
|
|
19132
18765
|
function fsearchSocketPath(dbPath) {
|
|
19133
18766
|
let canonical;
|
|
@@ -19136,7 +18769,7 @@ function fsearchSocketPath(dbPath) {
|
|
|
19136
18769
|
} catch {
|
|
19137
18770
|
canonical = resolve12(dbPath);
|
|
19138
18771
|
}
|
|
19139
|
-
const hash =
|
|
18772
|
+
const hash = createHash13("sha256").update(canonical).digest("hex").slice(0, 12);
|
|
19140
18773
|
return `/tmp/autorag-fsearch-${process.getuid?.() ?? 0}-${hash}.sock`;
|
|
19141
18774
|
}
|
|
19142
18775
|
function buildFSearchSearchArgs(dbPath, socketPath, request) {
|
|
@@ -19191,7 +18824,7 @@ function parseFSearchJsonLines(stdout) {
|
|
|
19191
18824
|
const path = String(record.path ?? "");
|
|
19192
18825
|
entries.push({
|
|
19193
18826
|
path,
|
|
19194
|
-
name:
|
|
18827
|
+
name: basename8(path),
|
|
19195
18828
|
type: record.type === "folder" ? "folder" : "file",
|
|
19196
18829
|
size: typeof record.size === "number" ? record.size : undefined,
|
|
19197
18830
|
dateModified: typeof record.mtime === "number" ? new Date(record.mtime * 1000).toISOString() : undefined
|
|
@@ -19269,7 +18902,7 @@ class FSearchClient {
|
|
|
19269
18902
|
const hasExclusions = (this.options.excludeFolders?.length ?? 0) > 0;
|
|
19270
18903
|
const nativeRequest = hasExclusions ? { ...request, offset: 0, maxResults: MAX_RESULTS_CAP } : request;
|
|
19271
18904
|
const args = buildFSearchSearchArgs(this.dbPath, this.socketPath(), nativeRequest);
|
|
19272
|
-
const result = await this.run(binary.path, args, this.options.timeoutMs ??
|
|
18905
|
+
const result = await this.run(binary.path, args, this.options.timeoutMs ?? DEFAULT_TIMEOUT_MS9);
|
|
19273
18906
|
if (result.code !== 0)
|
|
19274
18907
|
return this.failure("search-failed", binary.path, args, result);
|
|
19275
18908
|
let parsed;
|
|
@@ -19336,7 +18969,7 @@ class FSearchClient {
|
|
|
19336
18969
|
if (indexed.code !== 0)
|
|
19337
18970
|
return this.failure("index-failed", binaryPath, indexArgs, indexed);
|
|
19338
18971
|
const statsArgs = ["stats", "--db", this.dbPath, "--socket", this.socketPath()];
|
|
19339
|
-
const stats = await this.run(binaryPath, statsArgs, this.options.timeoutMs ??
|
|
18972
|
+
const stats = await this.run(binaryPath, statsArgs, this.options.timeoutMs ?? DEFAULT_TIMEOUT_MS9);
|
|
19340
18973
|
if (stats.code !== 0)
|
|
19341
18974
|
return this.failure("index-failed", binaryPath, statsArgs, stats);
|
|
19342
18975
|
let counts;
|
|
@@ -19384,7 +19017,7 @@ class FSearchClient {
|
|
|
19384
19017
|
}
|
|
19385
19018
|
}
|
|
19386
19019
|
async serving(binaryPath) {
|
|
19387
|
-
const stats = await this.run(binaryPath, ["stats", "--db", this.dbPath, "--socket", this.socketPath()], this.options.timeoutMs ??
|
|
19020
|
+
const stats = await this.run(binaryPath, ["stats", "--db", this.dbPath, "--socket", this.socketPath()], this.options.timeoutMs ?? DEFAULT_TIMEOUT_MS9);
|
|
19388
19021
|
if (stats.code !== 0)
|
|
19389
19022
|
return false;
|
|
19390
19023
|
try {
|
|
@@ -19417,7 +19050,7 @@ class FSearchClient {
|
|
|
19417
19050
|
if (this.binary !== undefined)
|
|
19418
19051
|
return this.binary;
|
|
19419
19052
|
const path = this.options.binaryPath ?? "fsearch-cli";
|
|
19420
|
-
const probe = await this.run(path, ["--version"], this.options.timeoutMs ??
|
|
19053
|
+
const probe = await this.run(path, ["--version"], this.options.timeoutMs ?? DEFAULT_TIMEOUT_MS9);
|
|
19421
19054
|
this.binary = probe.code === 0 ? { ok: true, path } : {
|
|
19422
19055
|
ok: false,
|
|
19423
19056
|
reason: "binary-missing",
|
|
@@ -19445,7 +19078,7 @@ function runProcess2(command, args, timeoutMs) {
|
|
|
19445
19078
|
const promise = new Promise((resolve) => {
|
|
19446
19079
|
resolvePromise = resolve;
|
|
19447
19080
|
});
|
|
19448
|
-
const child =
|
|
19081
|
+
const child = spawn16(command, args, { windowsHide: true, stdio: ["ignore", "pipe", "pipe"] });
|
|
19449
19082
|
const stdout = [];
|
|
19450
19083
|
const stderr = [];
|
|
19451
19084
|
let bytes = 0;
|
|
@@ -19480,7 +19113,7 @@ killed by ${signal} after ${timeoutMs}ms` : err
|
|
|
19480
19113
|
return promise;
|
|
19481
19114
|
}
|
|
19482
19115
|
function launchDetached2(command, args) {
|
|
19483
|
-
const child =
|
|
19116
|
+
const child = spawn16(command, args, { detached: true, stdio: "ignore", windowsHide: true });
|
|
19484
19117
|
child.on("error", () => {});
|
|
19485
19118
|
child.unref();
|
|
19486
19119
|
return child.pid;
|
|
@@ -19493,7 +19126,7 @@ function defaultIsProcessAlive(pid) {
|
|
|
19493
19126
|
return false;
|
|
19494
19127
|
}
|
|
19495
19128
|
}
|
|
19496
|
-
var
|
|
19129
|
+
var DEFAULT_TIMEOUT_MS9 = 30000, DEFAULT_STARTUP_TIMEOUT_MS2 = 1e4, STOP_TIMEOUT_MS2 = 2000, DEFAULT_INDEX_TIMEOUT_MS3, DEFAULT_POLL_INTERVAL_MS2 = 250, DEFAULT_MAX_RESULTS2 = 100, MAX_RESULTS_CAP = 1000, MAX_OUTPUT_BYTES2, SORT_KEYS;
|
|
19497
19130
|
var init_client9 = __esm(() => {
|
|
19498
19131
|
init_path_exclusions();
|
|
19499
19132
|
init_walk();
|
|
@@ -19723,7 +19356,7 @@ var init_answer_pack = __esm(() => {
|
|
|
19723
19356
|
});
|
|
19724
19357
|
|
|
19725
19358
|
// src/jikji/installer.ts
|
|
19726
|
-
import { spawn as
|
|
19359
|
+
import { spawn as spawn17 } from "node:child_process";
|
|
19727
19360
|
import { existsSync as existsSync21 } from "node:fs";
|
|
19728
19361
|
import { delimiter as delimiter5, join as join36 } from "node:path";
|
|
19729
19362
|
function jikjiExecutableName(platform = process.platform) {
|
|
@@ -19750,7 +19383,7 @@ function lookupExecutableInPath(executable, env) {
|
|
|
19750
19383
|
}
|
|
19751
19384
|
function defaultRunner(cargo, env) {
|
|
19752
19385
|
return (args, timeoutMs) => new Promise((resolvePromise) => {
|
|
19753
|
-
const child =
|
|
19386
|
+
const child = spawn17(cargo, args, { env, stdio: ["ignore", "ignore", "pipe"] });
|
|
19754
19387
|
let stderr = "";
|
|
19755
19388
|
const timeout = setTimeout(() => {
|
|
19756
19389
|
if (!child.killed)
|
|
@@ -19864,7 +19497,7 @@ class SerialQueue {
|
|
|
19864
19497
|
}
|
|
19865
19498
|
|
|
19866
19499
|
// src/jikji/client.ts
|
|
19867
|
-
import { spawn as
|
|
19500
|
+
import { spawn as spawn18 } from "node:child_process";
|
|
19868
19501
|
import { existsSync as existsSync22, realpathSync as realpathSync5 } from "node:fs";
|
|
19869
19502
|
|
|
19870
19503
|
class JikjiClient {
|
|
@@ -19978,7 +19611,7 @@ class JikjiClient {
|
|
|
19978
19611
|
if (perFile <= 0)
|
|
19979
19612
|
return;
|
|
19980
19613
|
const files = await countFiles(root, options.includeHidden === true, signal);
|
|
19981
|
-
return scaledPrepareTimeoutMs(options.timeoutMs ??
|
|
19614
|
+
return scaledPrepareTimeoutMs(options.timeoutMs ?? DEFAULT_TIMEOUT_MS10, perFile, files);
|
|
19982
19615
|
}
|
|
19983
19616
|
async spawn(request) {
|
|
19984
19617
|
return spawnJikji({
|
|
@@ -19991,7 +19624,7 @@ function spawnJikji(request) {
|
|
|
19991
19624
|
return new Promise((resolve) => {
|
|
19992
19625
|
const options = request.options;
|
|
19993
19626
|
const portable = portableSpawnCommand(request.command, request.args);
|
|
19994
|
-
const child =
|
|
19627
|
+
const child = spawn18(portable.command, [...portable.args], {
|
|
19995
19628
|
env: controlledEnv4(options.env),
|
|
19996
19629
|
...request.cwd === undefined ? {} : { cwd: request.cwd },
|
|
19997
19630
|
detached: process.platform !== "win32",
|
|
@@ -20023,7 +19656,7 @@ function spawnJikji(request) {
|
|
|
20023
19656
|
const timeout = setTimeout(() => {
|
|
20024
19657
|
finalReason = "timeout";
|
|
20025
19658
|
terminate(child);
|
|
20026
|
-
}, request.timeoutMs ?? options.timeoutMs ??
|
|
19659
|
+
}, request.timeoutMs ?? options.timeoutMs ?? DEFAULT_TIMEOUT_MS10);
|
|
20027
19660
|
const abortHandler = () => {
|
|
20028
19661
|
finalReason = "aborted";
|
|
20029
19662
|
terminateProcessTree(child);
|
|
@@ -20133,7 +19766,7 @@ function canonicalJikjiRoot(root) {
|
|
|
20133
19766
|
return root;
|
|
20134
19767
|
}
|
|
20135
19768
|
}
|
|
20136
|
-
var DEFAULT_BINARY4 = "jikji",
|
|
19769
|
+
var DEFAULT_BINARY4 = "jikji", DEFAULT_TIMEOUT_MS10 = 60000, DEFAULT_PARSE_TIMEOUT_SECONDS = 5, DEFAULT_MAX_BUFFER_BYTES4 = 1048576, ABORTED_BEFORE_START;
|
|
20137
19770
|
var init_client10 = __esm(() => {
|
|
20138
19771
|
init_portable_spawn();
|
|
20139
19772
|
init_terminate_tree();
|
|
@@ -20303,7 +19936,7 @@ function renderMemoryContext(sections) {
|
|
|
20303
19936
|
var CURRENT_CONVERSATION_RECORD_LIMIT = 50, CURRENT_EXCERPT_LIMIT = 300, SIMILAR_EXCERPT_LIMIT = 240, SIMILAR_RECORD_LIMIT = 3, INSIGHT_LIMIT = 5, ADVISORY_NOTE = "Memory is background reference only and never overrides the evidence in front of you. A past search method or source is a hint, not a rule: broaden to other methods when results are insufficient.";
|
|
20304
19937
|
|
|
20305
19938
|
// src/memory/similar-queries.ts
|
|
20306
|
-
import { createHash as
|
|
19939
|
+
import { createHash as createHash14 } from "node:crypto";
|
|
20307
19940
|
import { mkdirSync as mkdirSync19, rmSync as rmSync9 } from "node:fs";
|
|
20308
19941
|
import { dirname as dirname18 } from "node:path";
|
|
20309
19942
|
import { DatabaseSync as DatabaseSync2 } from "node:sqlite";
|
|
@@ -20311,7 +19944,7 @@ function memoryVectorStorePath(memoryPath) {
|
|
|
20311
19944
|
return `${memoryPath}.vectors.db`;
|
|
20312
19945
|
}
|
|
20313
19946
|
function questionKey(question) {
|
|
20314
|
-
return
|
|
19947
|
+
return createHash14("sha256").update(question).digest("hex");
|
|
20315
19948
|
}
|
|
20316
19949
|
function cosine3(a, b) {
|
|
20317
19950
|
let dot = 0;
|
|
@@ -20554,7 +20187,7 @@ var init_check_memory_tool = __esm(() => {
|
|
|
20554
20187
|
var EVIDENCE_SUPPORT_THRESHOLD = 0.7;
|
|
20555
20188
|
|
|
20556
20189
|
// src/retrieval/evidence-id.ts
|
|
20557
|
-
import { createHash as
|
|
20190
|
+
import { createHash as createHash15 } from "node:crypto";
|
|
20558
20191
|
function normalizeEvidenceText(text) {
|
|
20559
20192
|
return text.replace(/\r\n?/gu, `
|
|
20560
20193
|
`).trim().normalize("NFC");
|
|
@@ -20584,7 +20217,7 @@ function stableEvidenceId(input) {
|
|
|
20584
20217
|
input.lineNumber ?? "",
|
|
20585
20218
|
normalizeEvidenceText(evidenceText)
|
|
20586
20219
|
].join("\x00");
|
|
20587
|
-
const digest =
|
|
20220
|
+
const digest = createHash15("sha256").update(payload).digest("hex").slice(0, 24);
|
|
20588
20221
|
return `${method}:${digest}`;
|
|
20589
20222
|
}
|
|
20590
20223
|
function normalizeEvidenceRef(input) {
|
|
@@ -20596,7 +20229,7 @@ function normalizeEvidenceRef(input) {
|
|
|
20596
20229
|
var init_evidence_id = () => {};
|
|
20597
20230
|
|
|
20598
20231
|
// src/memory/memory.ts
|
|
20599
|
-
import { createHash as
|
|
20232
|
+
import { createHash as createHash16, randomUUID as randomUUID5 } from "node:crypto";
|
|
20600
20233
|
import { existsSync as existsSync23, mkdirSync as mkdirSync20, readFileSync as readFileSync22, unlinkSync as unlinkSync3, writeFileSync as writeFileSync14 } from "node:fs";
|
|
20601
20234
|
import { dirname as dirname19 } from "node:path";
|
|
20602
20235
|
import { z as z2 } from "zod";
|
|
@@ -20690,7 +20323,7 @@ function normalizeEvidenceChunkRecord(record) {
|
|
|
20690
20323
|
return { ...base, ...normalizeEvidenceContext(record) };
|
|
20691
20324
|
}
|
|
20692
20325
|
function hashText(value) {
|
|
20693
|
-
return
|
|
20326
|
+
return createHash16("sha256").update(value).digest("hex");
|
|
20694
20327
|
}
|
|
20695
20328
|
function resultId(sessionId, number) {
|
|
20696
20329
|
return `${sessionId}:${number}`;
|
|
@@ -21224,7 +20857,7 @@ import {
|
|
|
21224
20857
|
rmSync as rmSync10,
|
|
21225
20858
|
writeFileSync as writeFileSync15
|
|
21226
20859
|
} from "node:fs";
|
|
21227
|
-
import { basename as
|
|
20860
|
+
import { basename as basename9, dirname as dirname20, isAbsolute as isAbsolute9, join as join39, relative as relative7, sep as sep8 } from "node:path";
|
|
21228
20861
|
function syncMinSyncWorkspace(root, options = {}) {
|
|
21229
20862
|
const workspacePath = options.workspacePath ?? minSyncWorkspaceRoot(root);
|
|
21230
20863
|
const filesRoot = join39(workspacePath, "files");
|
|
@@ -21265,7 +20898,7 @@ function syncMinSyncWorkspace(root, options = {}) {
|
|
|
21265
20898
|
return { workspacePath, entries, excluded };
|
|
21266
20899
|
}
|
|
21267
20900
|
function stagingStatePath(workspacePath) {
|
|
21268
|
-
return join39(dirname20(workspacePath), `.${
|
|
20901
|
+
return join39(dirname20(workspacePath), `.${basename9(workspacePath)}-autorag-staging.json`);
|
|
21269
20902
|
}
|
|
21270
20903
|
function loadStagingState2(workspacePath) {
|
|
21271
20904
|
const path = stagingStatePath(workspacePath);
|
|
@@ -21316,7 +20949,7 @@ function ensureManagedDirectory(filesRoot, directory) {
|
|
|
21316
20949
|
}
|
|
21317
20950
|
}
|
|
21318
20951
|
function copyFileAtomically(source, destination) {
|
|
21319
|
-
const temporaryPath = join39(dirname20(destination), `.${
|
|
20952
|
+
const temporaryPath = join39(dirname20(destination), `.${basename9(destination)}.${randomUUID6()}.tmp`);
|
|
21320
20953
|
try {
|
|
21321
20954
|
copyFileSync4(source, temporaryPath);
|
|
21322
20955
|
renameWithRetry(temporaryPath, destination);
|
|
@@ -21370,7 +21003,7 @@ var init_workspace = __esm(() => {
|
|
|
21370
21003
|
|
|
21371
21004
|
// src/minsync/method.ts
|
|
21372
21005
|
import { existsSync as existsSync25, readFileSync as readFileSync24, realpathSync as realpathSync6, statSync as statSync7 } from "node:fs";
|
|
21373
|
-
import { basename as
|
|
21006
|
+
import { basename as basename10, join as join40, normalize as normalize2 } from "node:path";
|
|
21374
21007
|
|
|
21375
21008
|
class MinSyncVectorMethod {
|
|
21376
21009
|
root;
|
|
@@ -21471,7 +21104,7 @@ class MinSyncVectorMethod {
|
|
|
21471
21104
|
const entry = byPath.get(hit.path);
|
|
21472
21105
|
if (!entry || !matchesVirtualPathScope(entry.virtualPath, options.scope))
|
|
21473
21106
|
continue;
|
|
21474
|
-
const chunkDiscriminator = hit.docId ??
|
|
21107
|
+
const chunkDiscriminator = hit.docId ?? basename10(hit.path);
|
|
21475
21108
|
const chunkId = `minsync:${entry.virtualPath}:${chunkDiscriminator}`;
|
|
21476
21109
|
const location = locateChunkInMirror(mirrorTexts, entry, hit.text);
|
|
21477
21110
|
results.push({
|
|
@@ -21712,9 +21345,9 @@ var init_isolated = __esm(() => {
|
|
|
21712
21345
|
});
|
|
21713
21346
|
|
|
21714
21347
|
// src/mirror/sync.ts
|
|
21715
|
-
import { createHash as
|
|
21716
|
-
import { opendir as opendir2, readFile as readFile2, stat as
|
|
21717
|
-
import { basename as
|
|
21348
|
+
import { createHash as createHash17 } from "node:crypto";
|
|
21349
|
+
import { opendir as opendir2, readFile as readFile2, stat as stat4 } from "node:fs/promises";
|
|
21350
|
+
import { basename as basename11, extname as extname6, join as join42, resolve as resolve15, sep as sep9 } from "node:path";
|
|
21718
21351
|
import { setTimeout as sleep3 } from "node:timers/promises";
|
|
21719
21352
|
function errorCode(error) {
|
|
21720
21353
|
if (!(error instanceof Error))
|
|
@@ -21764,7 +21397,7 @@ function parseFingerprint(options) {
|
|
|
21764
21397
|
}
|
|
21765
21398
|
return value;
|
|
21766
21399
|
};
|
|
21767
|
-
return
|
|
21400
|
+
return createHash17("sha256").update(JSON.stringify(stable({ format: 1, parser: outputParserOptions(options.parserOptions) }))).digest("hex");
|
|
21768
21401
|
}
|
|
21769
21402
|
function outputParserOptions(options = {}) {
|
|
21770
21403
|
const { fileTimeoutMs: _timeout, maxHeapMb: _heap, ocr, ...parser } = options;
|
|
@@ -21772,7 +21405,7 @@ function outputParserOptions(options = {}) {
|
|
|
21772
21405
|
}
|
|
21773
21406
|
function retryFingerprint(options, fingerprint) {
|
|
21774
21407
|
const parser = options.parserOptions;
|
|
21775
|
-
return
|
|
21408
|
+
return createHash17("sha256").update(JSON.stringify({
|
|
21776
21409
|
fingerprint,
|
|
21777
21410
|
fileTimeoutMs: parser?.fileTimeoutMs,
|
|
21778
21411
|
maxHeapMb: parser?.maxHeapMb,
|
|
@@ -21991,7 +21624,7 @@ async function syncWithRegistry(options, registry, isolated) {
|
|
|
21991
21624
|
}
|
|
21992
21625
|
let info;
|
|
21993
21626
|
try {
|
|
21994
|
-
info = await
|
|
21627
|
+
info = await stat4(entry.sourcePath, { bigint: true });
|
|
21995
21628
|
} catch (error) {
|
|
21996
21629
|
await skipFile(entry, sourceReadFailure(error));
|
|
21997
21630
|
continue;
|
|
@@ -22023,7 +21656,7 @@ async function syncWithRegistry(options, registry, isolated) {
|
|
|
22023
21656
|
continue;
|
|
22024
21657
|
}
|
|
22025
21658
|
await session.commit(mirrorStageKey(entry.virtualPath), versions.get(entry.virtualPath), {
|
|
22026
|
-
path:
|
|
21659
|
+
path: basename11(outputPath),
|
|
22027
21660
|
size: Buffer.byteLength(markdown)
|
|
22028
21661
|
});
|
|
22029
21662
|
for (const diagnostic of parsed.diagnostics ?? [])
|
|
@@ -22099,7 +21732,7 @@ async function detectMirrorStaleness(options) {
|
|
|
22099
21732
|
}
|
|
22100
21733
|
}
|
|
22101
21734
|
function standaloneImageTooSmallMessage(virtualPath, bytes) {
|
|
22102
|
-
if (!STANDALONE_OCR_IMAGE_EXTENSIONS.has(normalizeExtension2(
|
|
21735
|
+
if (!STANDALONE_OCR_IMAGE_EXTENSIONS.has(normalizeExtension2(extname6(virtualPath))))
|
|
22103
21736
|
return;
|
|
22104
21737
|
return ocrImageTooSmallMessage(bytes);
|
|
22105
21738
|
}
|
|
@@ -22155,7 +21788,7 @@ function errnoCode2(error) {
|
|
|
22155
21788
|
async function probeSearchRoot(rootPath) {
|
|
22156
21789
|
let isDirectory;
|
|
22157
21790
|
try {
|
|
22158
|
-
isDirectory = (await
|
|
21791
|
+
isDirectory = (await stat4(rootPath)).isDirectory();
|
|
22159
21792
|
} catch (error) {
|
|
22160
21793
|
const code = errnoCode2(error);
|
|
22161
21794
|
return code === "ENOENT" || code === "ENOTDIR" ? "gone" : "unreadable";
|
|
@@ -22267,12 +21900,12 @@ async function collectFiles(state, directory, depth) {
|
|
|
22267
21900
|
}
|
|
22268
21901
|
if (!entry.isFile())
|
|
22269
21902
|
continue;
|
|
22270
|
-
const extension = normalizeExtension2(
|
|
21903
|
+
const extension = normalizeExtension2(extname6(entry.name));
|
|
22271
21904
|
if (!state.supportedExtensions.has(extension))
|
|
22272
21905
|
continue;
|
|
22273
21906
|
let fileStat;
|
|
22274
21907
|
try {
|
|
22275
|
-
fileStat = await
|
|
21908
|
+
fileStat = await stat4(sourcePath, { bigint: true });
|
|
22276
21909
|
} catch (error) {
|
|
22277
21910
|
const code = errnoCode2(error);
|
|
22278
21911
|
if (code === undefined)
|
|
@@ -26448,7 +26081,7 @@ var init_citations = __esm(() => {
|
|
|
26448
26081
|
});
|
|
26449
26082
|
|
|
26450
26083
|
// src/agent/evidence-ledger.ts
|
|
26451
|
-
import { createHash as
|
|
26084
|
+
import { createHash as createHash18 } from "node:crypto";
|
|
26452
26085
|
import { closeSync as closeSync2, openSync as openSync2, readSync, statSync as statSync8 } from "node:fs";
|
|
26453
26086
|
import { isAbsolute as isAbsolute10 } from "node:path";
|
|
26454
26087
|
import { Type as Type3 } from "typebox";
|
|
@@ -26483,10 +26116,10 @@ function readFileExcerpt(path) {
|
|
|
26483
26116
|
let descriptor;
|
|
26484
26117
|
try {
|
|
26485
26118
|
descriptor = openSync2(path, "r");
|
|
26486
|
-
const buffer = Buffer.alloc(
|
|
26119
|
+
const buffer = Buffer.alloc(MAX_CONTENT_CHARS3 * 4);
|
|
26487
26120
|
const bytes = readSync(descriptor, buffer, 0, buffer.length, 0);
|
|
26488
26121
|
const head = buffer.subarray(0, bytes);
|
|
26489
|
-
return head.includes(0) ? path : head.toString("utf8").slice(0,
|
|
26122
|
+
return head.includes(0) ? path : head.toString("utf8").slice(0, MAX_CONTENT_CHARS3);
|
|
26490
26123
|
} catch {
|
|
26491
26124
|
return path;
|
|
26492
26125
|
} finally {
|
|
@@ -26519,8 +26152,8 @@ class EvidenceLedger {
|
|
|
26519
26152
|
unsaved = new Set;
|
|
26520
26153
|
lastOrdinal = 0;
|
|
26521
26154
|
register(input) {
|
|
26522
|
-
const content = input.content.slice(0,
|
|
26523
|
-
const digest =
|
|
26155
|
+
const content = input.content.slice(0, MAX_CONTENT_CHARS3);
|
|
26156
|
+
const digest = createHash18("sha256").update(input.content.replace(/\s+/gu, " ").trim()).digest("hex");
|
|
26524
26157
|
const key = `${input.source}\x00${digest}`;
|
|
26525
26158
|
const existing = this.byKey.get(key);
|
|
26526
26159
|
if (existing !== undefined) {
|
|
@@ -26606,7 +26239,7 @@ class EvidenceLedger {
|
|
|
26606
26239
|
this.lastOrdinal = Math.max(this.lastOrdinal, ordinalFloor, highestOrdinal(this.entries));
|
|
26607
26240
|
}
|
|
26608
26241
|
}
|
|
26609
|
-
var
|
|
26242
|
+
var MAX_CONTENT_CHARS3 = 2000, EVIDENCE_ENTRY_TYPE = "autorag.evidence", ledgerEntrySchema, persistedEvidenceSchema;
|
|
26610
26243
|
var init_evidence_ledger = __esm(() => {
|
|
26611
26244
|
ledgerEntrySchema = Type3.Object({
|
|
26612
26245
|
id: Type3.String({ pattern: "^e[1-9][0-9]*$" }),
|
|
@@ -26838,7 +26471,7 @@ var init_ask_user = () => {};
|
|
|
26838
26471
|
|
|
26839
26472
|
// src/automation/service.ts
|
|
26840
26473
|
import { execFile as execFile2 } from "node:child_process";
|
|
26841
|
-
import { createHash as
|
|
26474
|
+
import { createHash as createHash19 } from "node:crypto";
|
|
26842
26475
|
import { existsSync as existsSync28, mkdirSync as mkdirSync23, rmSync as rmSync11, writeFileSync as writeFileSync16 } from "node:fs";
|
|
26843
26476
|
import { dirname as dirname24, join as join44, resolve as resolve16 } from "node:path";
|
|
26844
26477
|
import { setTimeout as sleep5 } from "node:timers/promises";
|
|
@@ -26869,7 +26502,7 @@ function automationServiceDescriptor(options = {}) {
|
|
|
26869
26502
|
const userHome = resolveUserHome(env);
|
|
26870
26503
|
const defaultHome = resolve16(join44(userHome, ".autorag"));
|
|
26871
26504
|
const home = resolve16(options.home ?? resolveAutoRAGHome(env));
|
|
26872
|
-
const suffix = home === defaultHome ? "" : `-${
|
|
26505
|
+
const suffix = home === defaultHome ? "" : `-${createHash19("sha256").update(home).digest("hex").slice(0, 8)}`;
|
|
26873
26506
|
const automationsDir = join44(home, "automations");
|
|
26874
26507
|
const envFilePath = join44(automationsDir, "service.env");
|
|
26875
26508
|
const logPath = join44(automationsDir, "daemon.log");
|
|
@@ -27305,7 +26938,7 @@ var init_automation_tool = __esm(() => {
|
|
|
27305
26938
|
});
|
|
27306
26939
|
|
|
27307
26940
|
// src/agent/citation-links.ts
|
|
27308
|
-
import { basename as
|
|
26941
|
+
import { basename as basename12, isAbsolute as isAbsolute12 } from "node:path";
|
|
27309
26942
|
import { pathToFileURL as pathToFileURL3 } from "node:url";
|
|
27310
26943
|
function openableTarget(source) {
|
|
27311
26944
|
if (/^https?:\/\//iu.test(source)) {
|
|
@@ -27323,7 +26956,7 @@ function linkCitations(markdown, sourceOf, isFile) {
|
|
|
27323
26956
|
for (const marker of answerMarkers(markdown, isFile)) {
|
|
27324
26957
|
if (marker.kind === "number")
|
|
27325
26958
|
continue;
|
|
27326
|
-
const labels = marker.kind === "file" ? [{ label:
|
|
26959
|
+
const labels = marker.kind === "file" ? [{ label: basename12(marker.path), source: marker.path }] : marker.ids.map((id) => ({ label: id, source: sourceOf(id) }));
|
|
27327
26960
|
let linked = false;
|
|
27328
26961
|
const parts = labels.map(({ label, source }) => {
|
|
27329
26962
|
const target = source === undefined ? undefined : openableTarget(source);
|
|
@@ -28671,7 +28304,7 @@ class DazziJevBackend {
|
|
|
28671
28304
|
this.apiKey = apiKey;
|
|
28672
28305
|
this.baseUrl = options.baseUrl ?? resolveBaseUrl(env);
|
|
28673
28306
|
this.defaultModel = options.defaultModel ?? DAZZI_DEFAULT_JEV_MODEL;
|
|
28674
|
-
this.timeoutMs = options.timeoutMs ??
|
|
28307
|
+
this.timeoutMs = options.timeoutMs ?? DEFAULT_TIMEOUT_MS11;
|
|
28675
28308
|
this.maxRetries = options.maxRetries ?? DEFAULT_MAX_RETRIES;
|
|
28676
28309
|
this.fetchImpl = options.fetchImpl;
|
|
28677
28310
|
}
|
|
@@ -28858,13 +28491,49 @@ async function extractErrorMessage(response) {
|
|
|
28858
28491
|
function sleep6(ms) {
|
|
28859
28492
|
return new Promise((resolve) => setTimeout(resolve, ms));
|
|
28860
28493
|
}
|
|
28861
|
-
var JEV_PATH, DAZZI_DEFAULT_JEV_MODEL = "jev-1.13",
|
|
28494
|
+
var JEV_PATH, DAZZI_DEFAULT_JEV_MODEL = "jev-1.13", DEFAULT_TIMEOUT_MS11 = 1e4, DEFAULT_MAX_RETRIES = 2, RETRY_BASE_MS = 500, RETRY_MAX_MS = 5000;
|
|
28862
28495
|
var init_jev_backend = __esm(() => {
|
|
28863
28496
|
init_config2();
|
|
28864
28497
|
init_credential();
|
|
28865
28498
|
JEV_PATH = `${API_PATH}/jev`;
|
|
28866
28499
|
});
|
|
28867
28500
|
|
|
28501
|
+
// src/agent/token-count.ts
|
|
28502
|
+
import { createHash as createHash20 } from "node:crypto";
|
|
28503
|
+
import { countTokens } from "gpt-tokenizer/encoding/o200k_base";
|
|
28504
|
+
function estimateTextTokens(text) {
|
|
28505
|
+
return Math.max(Math.ceil(text.length / 4), countText(text));
|
|
28506
|
+
}
|
|
28507
|
+
function tokensBeyondCharGuess(parts) {
|
|
28508
|
+
let excess = 0;
|
|
28509
|
+
for (const part of parts)
|
|
28510
|
+
excess += Math.max(0, countText(part) - Math.ceil(part.length / 4));
|
|
28511
|
+
return excess;
|
|
28512
|
+
}
|
|
28513
|
+
function countText(text) {
|
|
28514
|
+
if (text.length === 0)
|
|
28515
|
+
return 0;
|
|
28516
|
+
if (text.length < CACHE_MIN_CHARS)
|
|
28517
|
+
return countTokens(text, PLAIN_TEXT);
|
|
28518
|
+
const key = `${text.length}:${createHash20("sha1").update(text).digest("base64")}`;
|
|
28519
|
+
const hit = cache.get(key);
|
|
28520
|
+
if (hit !== undefined) {
|
|
28521
|
+
cache.delete(key);
|
|
28522
|
+
cache.set(key, hit);
|
|
28523
|
+
return hit;
|
|
28524
|
+
}
|
|
28525
|
+
const count = countTokens(text, PLAIN_TEXT);
|
|
28526
|
+
cache.set(key, count);
|
|
28527
|
+
if (cache.size > CACHE_ENTRIES)
|
|
28528
|
+
cache.delete(cache.keys().next().value);
|
|
28529
|
+
return count;
|
|
28530
|
+
}
|
|
28531
|
+
var PLAIN_TEXT, CACHE_MIN_CHARS = 2000, CACHE_ENTRIES = 64, cache;
|
|
28532
|
+
var init_token_count = __esm(() => {
|
|
28533
|
+
PLAIN_TEXT = { disallowedSpecial: new Set };
|
|
28534
|
+
cache = new Map;
|
|
28535
|
+
});
|
|
28536
|
+
|
|
28868
28537
|
// src/agent/context-token-guard.ts
|
|
28869
28538
|
import { calculateContextTokens, estimateTokens } from "@earendil-works/pi-coding-agent";
|
|
28870
28539
|
function createContextTokenGuardedTransform(model, base, fixedOverheadTokens = () => 0) {
|
|
@@ -28880,12 +28549,20 @@ function withBoundedOutput(model) {
|
|
|
28880
28549
|
return { ...model, maxTokens: MAX_OUTPUT_TOKENS };
|
|
28881
28550
|
}
|
|
28882
28551
|
function guardAgentContextMessages(model, messages, useReportedUsage = true, fixedOverheadTokens = 0) {
|
|
28552
|
+
const guarded = guardWithinBudget(model, messages, useReportedUsage, fixedOverheadTokens);
|
|
28553
|
+
if (model !== undefined && guarded.length > 0) {
|
|
28554
|
+
recordRequestEstimate(model, estimateContextMessageTokens(guarded, false) + fixedOverheadTokens);
|
|
28555
|
+
}
|
|
28556
|
+
return guarded;
|
|
28557
|
+
}
|
|
28558
|
+
function guardWithinBudget(model, messages, useReportedUsage = true, fixedOverheadTokens = 0) {
|
|
28883
28559
|
if (model === undefined || !Number.isFinite(model.contextWindow) || model.contextWindow <= 0 || messages.length === 0) {
|
|
28884
28560
|
return messages;
|
|
28885
28561
|
}
|
|
28886
28562
|
const usableContext = Math.floor(model.contextWindow / CONTEXT_HEADROOM);
|
|
28887
28563
|
const outputReserve = Math.min(Math.floor(usableContext / 4), MAX_OUTPUT_TOKENS, Number.isFinite(model.maxTokens) ? Math.max(0, model.maxTokens) : 0);
|
|
28888
|
-
const
|
|
28564
|
+
const overflowCeiling = contextOverflowCeiling(model);
|
|
28565
|
+
const inputBudget = Math.min(Math.max(0, usableContext - outputReserve), overflowCeiling ?? Number.POSITIVE_INFINITY);
|
|
28889
28566
|
const budget = Math.max(0, inputBudget - fixedOverheadTokens);
|
|
28890
28567
|
const reported = useReportedUsage && findLastAssistantUsage(messages) !== undefined;
|
|
28891
28568
|
if (estimateContextMessageTokens(messages, useReportedUsage) <= (reported ? inputBudget : budget)) {
|
|
@@ -28907,50 +28584,40 @@ function guardAgentContextMessages(model, messages, useReportedUsage = true, fix
|
|
|
28907
28584
|
}
|
|
28908
28585
|
let guarded = messages;
|
|
28909
28586
|
if (candidates.length > 0) {
|
|
28910
|
-
const
|
|
28911
|
-
const maximumOmitted = candidates.reduce((total, section) => total + section.blocks.length, 0);
|
|
28587
|
+
const entries = candidates.flatMap((section, sectionIndex) => section.blocks.map((block, blockIndex) => ({ block, sectionIndex, blockIndex })));
|
|
28912
28588
|
const omissionMarker = (count) => `
|
|
28913
28589
|
|
|
28914
28590
|
${GUARD_MARKER} Retrieval candidates omitted: ${count}.
|
|
28915
28591
|
`;
|
|
28916
|
-
|
|
28917
|
-
|
|
28918
|
-
|
|
28919
|
-
|
|
28920
|
-
for (const
|
|
28921
|
-
|
|
28922
|
-
|
|
28923
|
-
if (tokens <= remaining) {
|
|
28924
|
-
kept[sectionIndex]?.push(block);
|
|
28925
|
-
remaining -= tokens;
|
|
28926
|
-
continue;
|
|
28927
|
-
}
|
|
28928
|
-
omitted += section.blocks.length - (kept[sectionIndex]?.length ?? 0);
|
|
28929
|
-
for (const later of candidates.slice(sectionIndex + 1))
|
|
28930
|
-
omitted += later.blocks.length;
|
|
28931
|
-
firstOmitted = sectionIndex;
|
|
28932
|
-
break;
|
|
28933
|
-
}
|
|
28934
|
-
if (firstOmitted !== -1)
|
|
28592
|
+
const markerTokens = candidates.length * Math.ceil(omissionMarker(entries.length).length / 4);
|
|
28593
|
+
let remaining = Math.max(0, budget - estimateContextMessageTokens(base, false) - markerTokens);
|
|
28594
|
+
entries.sort((a, b) => a.block.rank - b.block.rank || a.sectionIndex - b.sectionIndex || a.blockIndex - b.blockIndex);
|
|
28595
|
+
const kept = new Set;
|
|
28596
|
+
for (const { block } of entries) {
|
|
28597
|
+
const tokens = Math.max(1, estimateTextTokens(block.text));
|
|
28598
|
+
if (tokens > remaining)
|
|
28935
28599
|
break;
|
|
28600
|
+
remaining -= tokens;
|
|
28601
|
+
kept.add(block);
|
|
28936
28602
|
}
|
|
28937
|
-
if (
|
|
28938
|
-
const
|
|
28939
|
-
for (const [sectionIndex, messageIndex] of candidateIndexes.entries())
|
|
28940
|
-
candidateByMessage.set(messageIndex, sectionIndex);
|
|
28603
|
+
if (kept.size < entries.length) {
|
|
28604
|
+
const sectionByMessage = new Map(candidateIndexes.map((messageIndex, i) => [messageIndex, candidates[i]]));
|
|
28941
28605
|
guarded = base.map((message, index) => {
|
|
28942
|
-
const
|
|
28943
|
-
if (
|
|
28606
|
+
const section = sectionByMessage.get(index);
|
|
28607
|
+
if (section === undefined)
|
|
28944
28608
|
return message;
|
|
28945
|
-
const
|
|
28946
|
-
const
|
|
28947
|
-
|
|
28609
|
+
const keptBlocks = section.blocks.filter((block) => kept.has(block));
|
|
28610
|
+
const omitted = section.blocks.length - keptBlocks.length;
|
|
28611
|
+
if (omitted === 0)
|
|
28612
|
+
return messages[index] ?? message;
|
|
28613
|
+
const marker = omissionMarker(omitted);
|
|
28614
|
+
return replaceTextContent(message, `${section.prefix}${keptBlocks.map((block) => block.text).join("")}${marker}${section.suffix}`);
|
|
28948
28615
|
});
|
|
28949
28616
|
}
|
|
28950
28617
|
}
|
|
28951
|
-
if (estimateContextMessageTokens(guarded, false) <= budget
|
|
28618
|
+
if (guarded !== messages && estimateContextMessageTokens(guarded, false) <= budget)
|
|
28952
28619
|
return guarded;
|
|
28953
|
-
return
|
|
28620
|
+
return fitNewestToolResult(guarded, budget);
|
|
28954
28621
|
}
|
|
28955
28622
|
function estimateContextMessageTokens(messages, useReportedUsage = false) {
|
|
28956
28623
|
if (useReportedUsage) {
|
|
@@ -28961,82 +28628,37 @@ function estimateContextMessageTokens(messages, useReportedUsage = false) {
|
|
|
28961
28628
|
}
|
|
28962
28629
|
return messages.reduce((total, message) => total + estimateMessageTokens(message), 0);
|
|
28963
28630
|
}
|
|
28964
|
-
function
|
|
28965
|
-
const
|
|
28966
|
-
const
|
|
28967
|
-
|
|
28968
|
-
|
|
28969
|
-
const
|
|
28970
|
-
|
|
28971
|
-
|
|
28972
|
-
|
|
28973
|
-
|
|
28974
|
-
trimmed[index] = fitMessageToTokens(message, Math.max(floorTokens, inputBudget - others));
|
|
28975
|
-
};
|
|
28976
|
-
for (const [index, message] of trimmed.entries()) {
|
|
28977
|
-
if (index === lastIndex || index === queryIndex || message.role === "system")
|
|
28978
|
-
continue;
|
|
28979
|
-
const replacement = replaceMessageWithMarker(message);
|
|
28980
|
-
if (replacement === message || estimateMessageTokens(replacement) >= estimateMessageTokens(message))
|
|
28981
|
-
continue;
|
|
28982
|
-
trimmed[index] = replacement;
|
|
28983
|
-
if (fits())
|
|
28984
|
-
return trimmed;
|
|
28985
|
-
}
|
|
28986
|
-
if (lastIndex !== queryIndex && trimmed[lastIndex]?.role !== "system") {
|
|
28987
|
-
fitInto(lastIndex, 0);
|
|
28988
|
-
if (fits())
|
|
28989
|
-
return trimmed;
|
|
28990
|
-
}
|
|
28991
|
-
for (const [index, message] of trimmed.entries()) {
|
|
28992
|
-
if (message.role !== "system")
|
|
28993
|
-
continue;
|
|
28994
|
-
fitInto(index, 0);
|
|
28995
|
-
if (fits())
|
|
28996
|
-
return trimmed;
|
|
28997
|
-
}
|
|
28998
|
-
if (queryIndex >= 0)
|
|
28999
|
-
fitInto(queryIndex, MIN_QUERY_TOKENS);
|
|
29000
|
-
return trimmed;
|
|
28631
|
+
function fitNewestToolResult(messages, inputBudget) {
|
|
28632
|
+
const lastIndex = messages.length - 1;
|
|
28633
|
+
const last = messages[lastIndex];
|
|
28634
|
+
if (last?.role !== "toolResult")
|
|
28635
|
+
return messages;
|
|
28636
|
+
const others = messages.reduce((total, message, index) => index === lastIndex ? total : total + estimateMessageTokens(message), 0);
|
|
28637
|
+
if (others >= inputBudget)
|
|
28638
|
+
return messages;
|
|
28639
|
+
const fitted = fitMessageToTokens(last, inputBudget - others);
|
|
28640
|
+
return fitted === last ? messages : [...messages.slice(0, lastIndex), fitted];
|
|
29001
28641
|
}
|
|
29002
28642
|
function fitMessageToTokens(message, maxTokens) {
|
|
29003
28643
|
const original = textContent(message);
|
|
29004
28644
|
if (original === undefined)
|
|
29005
|
-
return
|
|
28645
|
+
return message;
|
|
29006
28646
|
const marker = `
|
|
29007
28647
|
|
|
29008
28648
|
${GUARD_MARKER}
|
|
29009
28649
|
`;
|
|
29010
|
-
|
|
29011
|
-
|
|
29012
|
-
let
|
|
29013
|
-
|
|
29014
|
-
const
|
|
29015
|
-
const
|
|
29016
|
-
if (
|
|
29017
|
-
|
|
29018
|
-
|
|
29019
|
-
|
|
29020
|
-
high = middle - 1;
|
|
29021
|
-
}
|
|
28650
|
+
const overhead = estimateMessageTokens(replaceTextContent(message, ""));
|
|
28651
|
+
const density = Math.max(0, estimateMessageTokens(message) - overhead) / Math.max(1, original.length);
|
|
28652
|
+
let chars = density > 0 ? Math.floor((maxTokens - overhead) / density) : original.length;
|
|
28653
|
+
for (let attempt = 0;attempt < MAX_FIT_ATTEMPTS && chars > 0; attempt++) {
|
|
28654
|
+
const candidate = replaceTextContent(message, excerpt(original, chars, marker));
|
|
28655
|
+
const tokens = estimateMessageTokens(candidate);
|
|
28656
|
+
if (tokens <= maxTokens)
|
|
28657
|
+
return candidate;
|
|
28658
|
+
const scaled = Math.floor(chars * Math.max(0, maxTokens - overhead) / Math.max(1, tokens - overhead) * 0.98);
|
|
28659
|
+
chars = Math.min(chars - 1, scaled);
|
|
29022
28660
|
}
|
|
29023
|
-
return
|
|
29024
|
-
}
|
|
29025
|
-
function stripNonTextContent(message) {
|
|
29026
|
-
if (message.role !== "user" || typeof message.content === "string")
|
|
29027
|
-
return replaceMessageWithMarker(message);
|
|
29028
|
-
const marker = `
|
|
29029
|
-
|
|
29030
|
-
${GUARD_MARKER}
|
|
29031
|
-
`;
|
|
29032
|
-
let replacedImage = false;
|
|
29033
|
-
const content = message.content.map((block) => {
|
|
29034
|
-
if (block.type === "text")
|
|
29035
|
-
return block;
|
|
29036
|
-
replacedImage = true;
|
|
29037
|
-
return { type: "text", text: marker };
|
|
29038
|
-
});
|
|
29039
|
-
return replacedImage ? { ...message, content } : message;
|
|
28661
|
+
return replaceTextContent(message, marker);
|
|
29040
28662
|
}
|
|
29041
28663
|
function excerpt(text, maxChars, marker) {
|
|
29042
28664
|
if (text.length <= maxChars)
|
|
@@ -29046,32 +28668,54 @@ function excerpt(text, maxChars, marker) {
|
|
|
29046
28668
|
const tail = Math.max(0, available - head);
|
|
29047
28669
|
return `${text.slice(0, head)}${marker}${tail > 0 ? text.slice(-tail) : ""}`;
|
|
29048
28670
|
}
|
|
29049
|
-
function replaceMessageWithMarker(message) {
|
|
29050
|
-
return replaceTextContent(message, `
|
|
29051
|
-
|
|
29052
|
-
${GUARD_MARKER}
|
|
29053
|
-
`);
|
|
29054
|
-
}
|
|
29055
28671
|
function estimateMessageTokens(message) {
|
|
29056
28672
|
if (message.role === "system")
|
|
29057
28673
|
return estimateSystemMessageTokens(message);
|
|
29058
|
-
const estimate = estimateTokens(message);
|
|
28674
|
+
const estimate = estimateTokens(message) + tokensBeyondCharGuess(messageTextParts(message));
|
|
29059
28675
|
return message.role === "toolResult" ? estimate + Math.ceil(message.toolName.length / 4) : estimate;
|
|
29060
28676
|
}
|
|
29061
28677
|
function estimateSystemMessageTokens(message) {
|
|
29062
|
-
|
|
29063
|
-
|
|
28678
|
+
const parts = [];
|
|
28679
|
+
let chars = 0;
|
|
28680
|
+
if (typeof message.content === "string")
|
|
28681
|
+
parts.push(message.content);
|
|
28682
|
+
else {
|
|
29064
28683
|
for (const block of message.content) {
|
|
29065
28684
|
if (block.type === "text")
|
|
29066
|
-
|
|
28685
|
+
parts.push(block.text);
|
|
29067
28686
|
else if (block.type === "image")
|
|
29068
28687
|
chars += 4800;
|
|
29069
28688
|
}
|
|
29070
28689
|
}
|
|
29071
|
-
|
|
29072
|
-
|
|
29073
|
-
|
|
29074
|
-
return Math.ceil(chars / 4);
|
|
28690
|
+
parts.push(JSON.stringify(message.sections ?? {}), JSON.stringify(message.toolsAdded ?? []), JSON.stringify(message.toolsRemoved ?? []));
|
|
28691
|
+
for (const part of parts)
|
|
28692
|
+
chars += part.length;
|
|
28693
|
+
return Math.ceil(chars / 4) + tokensBeyondCharGuess(parts);
|
|
28694
|
+
}
|
|
28695
|
+
function messageTextParts(message) {
|
|
28696
|
+
switch (message.role) {
|
|
28697
|
+
case "user":
|
|
28698
|
+
case "custom":
|
|
28699
|
+
case "toolResult":
|
|
28700
|
+
return typeof message.content === "string" ? [message.content] : message.content.flatMap((block) => block.type === "text" ? [block.text] : []);
|
|
28701
|
+
case "assistant":
|
|
28702
|
+
return message.content.flatMap((block) => {
|
|
28703
|
+
if (block.type === "text")
|
|
28704
|
+
return [block.text];
|
|
28705
|
+
if (block.type === "thinking")
|
|
28706
|
+
return [block.thinking];
|
|
28707
|
+
if (block.type === "toolCall")
|
|
28708
|
+
return [`${block.name}${JSON.stringify(block.arguments)}`];
|
|
28709
|
+
return [];
|
|
28710
|
+
});
|
|
28711
|
+
case "bashExecution":
|
|
28712
|
+
return [message.command, message.output];
|
|
28713
|
+
case "branchSummary":
|
|
28714
|
+
case "compactionSummary":
|
|
28715
|
+
return [message.summary];
|
|
28716
|
+
default:
|
|
28717
|
+
return [];
|
|
28718
|
+
}
|
|
29075
28719
|
}
|
|
29076
28720
|
function findLastAssistantUsage(messages) {
|
|
29077
28721
|
for (let index = messages.length - 1;index >= 0; index--) {
|
|
@@ -29145,7 +28789,7 @@ function parseCandidateSection(message, text) {
|
|
|
29145
28789
|
const sectionEnd = findBaselineSectionEnd(text, sectionStart);
|
|
29146
28790
|
if (!/^\[e?\d+\] /mu.test(text.slice(sectionStart, sectionEnd)))
|
|
29147
28791
|
return;
|
|
29148
|
-
return splitCandidates(text, sectionStart, sectionEnd);
|
|
28792
|
+
return splitCandidates(text, sectionStart, sectionEnd, { lists: true });
|
|
29149
28793
|
}
|
|
29150
28794
|
if (message.role !== "toolResult")
|
|
29151
28795
|
return;
|
|
@@ -29156,7 +28800,9 @@ function parseCandidateSection(message, text) {
|
|
|
29156
28800
|
const directiveStart = text.indexOf(`
|
|
29157
28801
|
|
|
29158
28802
|
directive:`);
|
|
29159
|
-
return splitCandidates(text, 0, directiveStart >= 0 ? directiveStart : text.length,
|
|
28803
|
+
return splitCandidates(text, 0, directiveStart >= 0 ? directiveStart : text.length, {
|
|
28804
|
+
pattern: /^- [^\n]*(?:\n|$)/gmu
|
|
28805
|
+
});
|
|
29160
28806
|
}
|
|
29161
28807
|
const diagnosticsStart = text.indexOf(`
|
|
29162
28808
|
|
|
@@ -29178,17 +28824,23 @@ Formatting and content rules`
|
|
|
29178
28824
|
const positions = endMarkers.map((marker) => text.indexOf(marker, startIndex)).filter((index) => index >= 0);
|
|
29179
28825
|
return positions.length > 0 ? Math.min(...positions) : text.length;
|
|
29180
28826
|
}
|
|
29181
|
-
function splitCandidates(text, sectionStart, sectionEnd,
|
|
28827
|
+
function splitCandidates(text, sectionStart, sectionEnd, options = {}) {
|
|
29182
28828
|
const region = text.slice(sectionStart, sectionEnd);
|
|
29183
|
-
const matches = [...region.matchAll(pattern)];
|
|
28829
|
+
const matches = [...region.matchAll(options.pattern ?? /^\[e?\d+\] [^\n]*(?:\n|$)/gmu)];
|
|
29184
28830
|
const firstStart = matches[0]?.index;
|
|
29185
28831
|
if (firstStart === undefined)
|
|
29186
28832
|
return;
|
|
29187
28833
|
const blocks = [];
|
|
28834
|
+
let rank = 0;
|
|
28835
|
+
let heading = "";
|
|
29188
28836
|
for (const [index, match] of matches.entries()) {
|
|
29189
28837
|
const start = match.index ?? 0;
|
|
29190
28838
|
const end = index + 1 < matches.length ? matches[index + 1]?.index ?? region.length : region.length;
|
|
29191
|
-
|
|
28839
|
+
const raw = region.slice(start, end);
|
|
28840
|
+
const tail = options.lists === true ? LIST_HEADING_TAIL.exec(raw) : null;
|
|
28841
|
+
blocks.push({ text: heading + (tail === null ? raw : raw.slice(0, tail.index)), rank });
|
|
28842
|
+
rank = tail === null ? rank + 1 : 0;
|
|
28843
|
+
heading = tail === null ? "" : tail[0];
|
|
29192
28844
|
}
|
|
29193
28845
|
return {
|
|
29194
28846
|
prefix: text.slice(0, sectionStart) + region.slice(0, firstStart),
|
|
@@ -29196,8 +28848,10 @@ function splitCandidates(text, sectionStart, sectionEnd, pattern = /^\[e?\d+\] [
|
|
|
29196
28848
|
blocks
|
|
29197
28849
|
};
|
|
29198
28850
|
}
|
|
29199
|
-
var CONTEXT_HEADROOM = 1.2, MAX_OUTPUT_TOKENS = 32000,
|
|
28851
|
+
var CONTEXT_HEADROOM = 1.2, MAX_OUTPUT_TOKENS = 32000, GUARD_MARKER = "[AutoRAG context guard: omitted context to stay within the model context budget.]", RETRIEVAL_TOOL_PREFIX = "search_datasource_", RETRIEVAL_TOOL_NAMES, MAX_FIT_ATTEMPTS = 6, LIST_HEADING_TAIL;
|
|
29200
28852
|
var init_context_token_guard = __esm(() => {
|
|
28853
|
+
init_context_overflow();
|
|
28854
|
+
init_token_count();
|
|
29201
28855
|
RETRIEVAL_TOOL_NAMES = {
|
|
29202
28856
|
jikji_find: true,
|
|
29203
28857
|
search_all_documents: true,
|
|
@@ -29206,6 +28860,7 @@ var init_context_token_guard = __esm(() => {
|
|
|
29206
28860
|
everything_search: true,
|
|
29207
28861
|
fsearch_search: true
|
|
29208
28862
|
};
|
|
28863
|
+
LIST_HEADING_TAIL = /\n[^\n]*initial candidates[^\n]*:\n$/u;
|
|
29209
28864
|
});
|
|
29210
28865
|
|
|
29211
28866
|
// src/agent/current-date.ts
|
|
@@ -29542,7 +29197,7 @@ function guardContext(pi, contextTransform) {
|
|
|
29542
29197
|
pi.on("context", async (event, ctx) => {
|
|
29543
29198
|
const activeTools = new Set(pi.getActiveTools());
|
|
29544
29199
|
const toolDeclarations = pi.getAllTools().filter((tool) => activeTools.has(tool.name)).map(({ name, description, parameters }) => ({ name, description, parameters }));
|
|
29545
|
-
const fixedOverheadTokens =
|
|
29200
|
+
const fixedOverheadTokens = estimateTextTokens(ctx.getSystemPrompt()) + estimateTextTokens(JSON.stringify(toolDeclarations));
|
|
29546
29201
|
return {
|
|
29547
29202
|
messages: await createContextTokenGuardedTransform(ctx.model, contextTransform, () => fixedOverheadTokens)(event.messages)
|
|
29548
29203
|
};
|
|
@@ -29776,6 +29431,7 @@ var init_pi_session = __esm(() => {
|
|
|
29776
29431
|
init_intent_tracing();
|
|
29777
29432
|
init_mcp_client();
|
|
29778
29433
|
init_request_limits();
|
|
29434
|
+
init_token_count();
|
|
29779
29435
|
init_welcome_header();
|
|
29780
29436
|
PI_BUILTIN_TOOL_NAMES = ["read", "bash", "edit", "write", "grep", "find", "ls"];
|
|
29781
29437
|
});
|
|
@@ -31547,7 +31203,7 @@ var init_page_loader = __esm(() => {
|
|
|
31547
31203
|
});
|
|
31548
31204
|
|
|
31549
31205
|
// src/web/fetch/url-target.ts
|
|
31550
|
-
import { extname as
|
|
31206
|
+
import { extname as extname7 } from "node:path";
|
|
31551
31207
|
function repairCollapsedScheme(value) {
|
|
31552
31208
|
const m = value.match(/^(https?):\/(?!\/)/i);
|
|
31553
31209
|
return m ? `${m[1]}://${value.slice(m[0].length)}` : value;
|
|
@@ -31566,7 +31222,7 @@ function getFilenameExtensionHint(filename) {
|
|
|
31566
31222
|
const lower = filename.toLowerCase();
|
|
31567
31223
|
if (lower.endsWith(".tar.gz"))
|
|
31568
31224
|
return ".tar.gz";
|
|
31569
|
-
return
|
|
31225
|
+
return extname7(filename).toLowerCase();
|
|
31570
31226
|
}
|
|
31571
31227
|
function getExtensionHint(url, contentDisposition) {
|
|
31572
31228
|
if (contentDisposition) {
|
|
@@ -31743,7 +31399,7 @@ var init_convert2 = __esm(() => {
|
|
|
31743
31399
|
});
|
|
31744
31400
|
|
|
31745
31401
|
// src/web/fetch/feeds.ts
|
|
31746
|
-
import { extname as
|
|
31402
|
+
import { extname as extname8 } from "node:path";
|
|
31747
31403
|
import { XMLParser as XMLParser3 } from "fast-xml-parser";
|
|
31748
31404
|
function getHtmlAttribute(tag, attribute) {
|
|
31749
31405
|
const pattern = new RegExp(`\\b${attribute}\\s*=\\s*(?:"([^"]*)"|'([^']*)'|([^\\s"'=<>]+))`, "i");
|
|
@@ -31806,7 +31462,7 @@ function extractDocumentLinks(html, baseUrl) {
|
|
|
31806
31462
|
const href = getHtmlAttribute(tag, "href");
|
|
31807
31463
|
if (!href)
|
|
31808
31464
|
continue;
|
|
31809
|
-
const ext =
|
|
31465
|
+
const ext = extname8(href).toLowerCase();
|
|
31810
31466
|
if (!CONVERTIBLE_EXTENSIONS2.has(ext))
|
|
31811
31467
|
continue;
|
|
31812
31468
|
const resolved = href.startsWith("http") ? href : new URL(href, baseUrl).href;
|
|
@@ -33474,7 +33130,7 @@ var init_web_search_tool = __esm(() => {
|
|
|
33474
33130
|
// src/agent/agent.ts
|
|
33475
33131
|
import { randomUUID as randomUUID7 } from "node:crypto";
|
|
33476
33132
|
import { existsSync as existsSync32, watch as fsWatch, mkdirSync as mkdirSync24, realpathSync as realpathSync7, statSync as statSync9, writeFileSync as writeFileSync18 } from "node:fs";
|
|
33477
|
-
import { basename as
|
|
33133
|
+
import { basename as basename13, dirname as dirname26, join as join50, resolve as resolve17 } from "node:path";
|
|
33478
33134
|
import { clampThinkingLevel } from "@earendil-works/pi-ai/compat";
|
|
33479
33135
|
import { getAgentDir as getAgentDir4, keyText } from "@earendil-works/pi-coding-agent";
|
|
33480
33136
|
function positiveLimit(value, fallback, path) {
|
|
@@ -36397,7 +36053,7 @@ function toMinSyncReasonDiagnostic(reason) {
|
|
|
36397
36053
|
function pinExcludedPath(path) {
|
|
36398
36054
|
const resolvedPath = resolve17(path);
|
|
36399
36055
|
try {
|
|
36400
|
-
return join50(realpathSync7(dirname26(resolvedPath)),
|
|
36056
|
+
return join50(realpathSync7(dirname26(resolvedPath)), basename13(resolvedPath));
|
|
36401
36057
|
} catch {
|
|
36402
36058
|
return resolvedPath;
|
|
36403
36059
|
}
|
|
@@ -37813,7 +37469,7 @@ var init_embedding2 = __esm(() => {
|
|
|
37813
37469
|
});
|
|
37814
37470
|
|
|
37815
37471
|
// src/datasource/skills/hister/setup.ts
|
|
37816
|
-
import { spawn as
|
|
37472
|
+
import { spawn as spawn19 } from "node:child_process";
|
|
37817
37473
|
import { copyFileSync as copyFileSync5, existsSync as existsSync36, readFileSync as readFileSync31, writeFileSync as writeFileSync19 } from "node:fs";
|
|
37818
37474
|
import { homedir as homedir7 } from "node:os";
|
|
37819
37475
|
import { dirname as dirname28, join as join53 } from "node:path";
|
|
@@ -37860,7 +37516,7 @@ function defaultHisterConfigPath(env, exists = existsSync36, platform = process.
|
|
|
37860
37516
|
function commandRun(command, args, timeoutMs) {
|
|
37861
37517
|
return new Promise((resolve) => {
|
|
37862
37518
|
let stderr = "";
|
|
37863
|
-
const child =
|
|
37519
|
+
const child = spawn19(command, args, { stdio: ["ignore", "ignore", "pipe"] });
|
|
37864
37520
|
const timer = setTimeout(() => {
|
|
37865
37521
|
child.kill("SIGTERM");
|
|
37866
37522
|
resolve({ ok: false, reason: `${command} ${args.join(" ")} timed out after ${timeoutMs}ms` });
|
|
@@ -38149,8 +37805,7 @@ function datasourceNames(config, platform) {
|
|
|
38149
37805
|
"github",
|
|
38150
37806
|
"cloud-drive",
|
|
38151
37807
|
"obsidian",
|
|
38152
|
-
"rss"
|
|
38153
|
-
"spotlight"
|
|
37808
|
+
"rss"
|
|
38154
37809
|
])
|
|
38155
37810
|
];
|
|
38156
37811
|
}
|
|
@@ -38954,7 +38609,7 @@ function sanitizeMessage(raw) {
|
|
|
38954
38609
|
function parseTimeoutMs(flags) {
|
|
38955
38610
|
const raw = flags["timeout-ms"];
|
|
38956
38611
|
if (raw === undefined || raw === true)
|
|
38957
|
-
return
|
|
38612
|
+
return DEFAULT_TIMEOUT_MS12;
|
|
38958
38613
|
const text = typeof raw === "string" ? raw.trim() : "";
|
|
38959
38614
|
if (!/^\d+$/.test(text) || Number(text) <= 0) {
|
|
38960
38615
|
return `--timeout-ms must be a positive integer (got "${text}")`;
|
|
@@ -39137,7 +38792,7 @@ async function runHealth(ctx, deps = {}) {
|
|
|
39137
38792
|
ctx.stdout(renderHealth(report, { json: ctx.json, debug: ctx.debug }));
|
|
39138
38793
|
return exitCode(probe.category);
|
|
39139
38794
|
}
|
|
39140
|
-
var
|
|
38795
|
+
var DEFAULT_TIMEOUT_MS12 = 1e4;
|
|
39141
38796
|
var init_health = __esm(() => {
|
|
39142
38797
|
init_config5();
|
|
39143
38798
|
init_output();
|
|
@@ -39202,7 +38857,7 @@ var init_duplicates = __esm(() => {
|
|
|
39202
38857
|
});
|
|
39203
38858
|
|
|
39204
38859
|
// src/cli/open-target.ts
|
|
39205
|
-
import { spawn as
|
|
38860
|
+
import { spawn as spawn20 } from "node:child_process";
|
|
39206
38861
|
import { fileURLToPath as fileURLToPath5 } from "node:url";
|
|
39207
38862
|
function systemOpener(url) {
|
|
39208
38863
|
if (process.platform === "darwin")
|
|
@@ -39227,7 +38882,7 @@ function launch(spawnFn, command, args, onFailure) {
|
|
|
39227
38882
|
});
|
|
39228
38883
|
child.unref();
|
|
39229
38884
|
}
|
|
39230
|
-
function openCitationTarget(url, spawnFn =
|
|
38885
|
+
function openCitationTarget(url, spawnFn = spawn20) {
|
|
39231
38886
|
const [command, args] = systemOpener(url);
|
|
39232
38887
|
if (!url.startsWith("file:")) {
|
|
39233
38888
|
launch(spawnFn, command, args);
|