@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/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 basename7, dirname as dirname15, isAbsolute as isAbsolute6, join as join27, resolve as resolve7 } from "node:path";
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), `.${basename7(path)}.${process.pid}.${randomUUID4()}.tmp`);
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 spawn14 } from "node:child_process";
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 = spawn14(portable.command, [...portable.args], {
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 createHash11 } from "node:crypto";
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 = createHash11("sha256");
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 spawn15 } from "node:child_process";
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 = spawn15(portable.command, [...portable.args], {
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 stat3 } from "node:fs/promises";
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 stat3(path);
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 createHash12 } from "node:crypto";
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 createHash12("sha256").update(bytes).digest("hex");
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 spawn16 } from "node:child_process";
18614
- import { createHash as createHash13 } from "node:crypto";
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-${createHash13("sha256").update(resolve11(root).toLowerCase()).digest("hex").slice(0, 12)}`;
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 ?? DEFAULT_TIMEOUT_MS9;
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 ?? DEFAULT_TIMEOUT_MS9);
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 ?? DEFAULT_TIMEOUT_MS9;
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 ?? DEFAULT_TIMEOUT_MS9);
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 = spawn16(command, args, { windowsHide: true, stdio: ["ignore", "pipe", "pipe"] });
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 = spawn16(command, args, { detached: true, stdio: "ignore", windowsHide: true });
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 DEFAULT_TIMEOUT_MS9 = 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;
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 stat4 } from "node:fs/promises";
19002
- import { basename as basename8, join as join33, sep as sep5 } from "node:path";
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 : basename8(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 : basename8(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 stat4(path);
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: basename8(path),
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 stat4(folder);
18725
+ const info = await stat3(folder);
19093
18726
  if (!info.isDirectory())
19094
18727
  continue;
19095
18728
  collected.push({
19096
18729
  path: folder,
19097
- name: basename8(folder),
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 spawn17 } from "node:child_process";
19128
- import { createHash as createHash14 } from "node:crypto";
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 basename9, join as join34, resolve as resolve12, sep as sep6 } from "node:path";
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 = createHash14("sha256").update(canonical).digest("hex").slice(0, 12);
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: basename9(path),
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 ?? DEFAULT_TIMEOUT_MS10);
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 ?? DEFAULT_TIMEOUT_MS10);
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 ?? DEFAULT_TIMEOUT_MS10);
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 ?? DEFAULT_TIMEOUT_MS10);
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 = spawn17(command, args, { windowsHide: true, stdio: ["ignore", "pipe", "pipe"] });
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 = spawn17(command, args, { detached: true, stdio: "ignore", windowsHide: true });
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 DEFAULT_TIMEOUT_MS10 = 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;
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 spawn18 } from "node:child_process";
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 = spawn18(cargo, args, { env, stdio: ["ignore", "ignore", "pipe"] });
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 spawn19 } from "node:child_process";
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 ?? DEFAULT_TIMEOUT_MS11, perFile, files);
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 = spawn19(portable.command, [...portable.args], {
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 ?? DEFAULT_TIMEOUT_MS11);
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", DEFAULT_TIMEOUT_MS11 = 60000, DEFAULT_PARSE_TIMEOUT_SECONDS = 5, DEFAULT_MAX_BUFFER_BYTES4 = 1048576, ABORTED_BEFORE_START;
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 createHash15 } from "node:crypto";
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 createHash15("sha256").update(question).digest("hex");
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 createHash16 } from "node:crypto";
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 = createHash16("sha256").update(payload).digest("hex").slice(0, 24);
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 createHash17, randomUUID as randomUUID5 } from "node:crypto";
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 createHash17("sha256").update(value).digest("hex");
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 basename10, dirname as dirname20, isAbsolute as isAbsolute9, join as join39, relative as relative7, sep as sep8 } from "node:path";
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), `.${basename10(workspacePath)}-autorag-staging.json`);
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), `.${basename10(destination)}.${randomUUID6()}.tmp`);
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 basename11, join as join40, normalize as normalize2 } from "node:path";
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 ?? basename11(hit.path);
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 createHash18 } from "node:crypto";
21716
- import { opendir as opendir2, readFile as readFile2, stat as stat5 } from "node:fs/promises";
21717
- import { basename as basename12, extname as extname7, join as join42, resolve as resolve15, sep as sep9 } from "node:path";
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 createHash18("sha256").update(JSON.stringify(stable({ format: 1, parser: outputParserOptions(options.parserOptions) }))).digest("hex");
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 createHash18("sha256").update(JSON.stringify({
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 stat5(entry.sourcePath, { bigint: true });
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: basename12(outputPath),
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(extname7(virtualPath))))
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 stat5(rootPath)).isDirectory();
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(extname7(entry.name));
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 stat5(sourcePath, { bigint: true });
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 createHash19 } from "node:crypto";
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(MAX_CONTENT_CHARS4 * 4);
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, MAX_CONTENT_CHARS4);
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, MAX_CONTENT_CHARS4);
26523
- const digest = createHash19("sha256").update(input.content.replace(/\s+/gu, " ").trim()).digest("hex");
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 MAX_CONTENT_CHARS4 = 2000, EVIDENCE_ENTRY_TYPE = "autorag.evidence", ledgerEntrySchema, persistedEvidenceSchema;
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 createHash20 } from "node:crypto";
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 ? "" : `-${createHash20("sha256").update(home).digest("hex").slice(0, 8)}`;
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 basename13, isAbsolute as isAbsolute12 } from "node:path";
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: basename13(marker.path), source: marker.path }] : marker.ids.map((id) => ({ label: id, source: sourceOf(id) }));
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 ?? DEFAULT_TIMEOUT_MS12;
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", DEFAULT_TIMEOUT_MS12 = 1e4, DEFAULT_MAX_RETRIES = 2, RETRY_BASE_MS = 500, RETRY_MAX_MS = 5000;
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 inputBudget = Math.max(0, usableContext - outputReserve);
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 fixedTokens = estimateContextMessageTokens(base, false);
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
- let remaining = Math.max(0, budget - fixedTokens - Math.ceil(omissionMarker(maximumOmitted).length / 4));
28917
- const kept = candidates.map(() => []);
28918
- let omitted = 0;
28919
- let firstOmitted = -1;
28920
- for (const [sectionIndex, section] of candidates.entries()) {
28921
- for (const block of section.blocks) {
28922
- const tokens = Math.max(1, Math.ceil(block.length / 4));
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 (omitted > 0) {
28938
- const candidateByMessage = new Map;
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 sectionIndex = candidateByMessage.get(index);
28943
- if (sectionIndex === undefined)
28606
+ const section = sectionByMessage.get(index);
28607
+ if (section === undefined)
28944
28608
  return message;
28945
- const section = candidates[sectionIndex];
28946
- const marker = sectionIndex === firstOmitted ? omissionMarker(omitted) : "";
28947
- return replaceTextContent(message, `${section.prefix}${kept[sectionIndex]?.join("") ?? ""}${marker}${section.suffix}`);
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 && guarded !== messages)
28618
+ if (guarded !== messages && estimateContextMessageTokens(guarded, false) <= budget)
28952
28619
  return guarded;
28953
- return trimFixedContext(guarded, budget);
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 trimFixedContext(messages, inputBudget) {
28965
- const trimmed = messages.slice();
28966
- const lastIndex = trimmed.length - 1;
28967
- const queryIndex = trimmed.reduce((found, message, index) => message.role === "user" ? index : found, -1);
28968
- const fits = () => estimateContextMessageTokens(trimmed, false) <= inputBudget;
28969
- const fitInto = (index, floorTokens) => {
28970
- const message = trimmed[index];
28971
- if (message === undefined)
28972
- return;
28973
- const others = trimmed.reduce((total, other, i) => i === index ? total : total + estimateMessageTokens(other), 0);
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 stripNonTextContent(message);
28645
+ return message;
29006
28646
  const marker = `
29007
28647
 
29008
28648
  ${GUARD_MARKER}
29009
28649
  `;
29010
- let low = 0;
29011
- let high = original.length;
29012
- let best = replaceTextContent(message, marker);
29013
- while (low <= high) {
29014
- const middle = Math.floor((low + high) / 2);
29015
- const candidate = replaceTextContent(message, excerpt(original, middle, marker));
29016
- if (estimateMessageTokens(candidate) <= maxTokens) {
29017
- best = candidate;
29018
- low = middle + 1;
29019
- } else {
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 best;
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
- let chars = typeof message.content === "string" ? message.content.length : 0;
29063
- if (Array.isArray(message.content)) {
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
- chars += block.text.length;
28685
+ parts.push(block.text);
29067
28686
  else if (block.type === "image")
29068
28687
  chars += 4800;
29069
28688
  }
29070
28689
  }
29071
- chars += JSON.stringify(message.sections ?? {}).length;
29072
- chars += JSON.stringify(message.toolsAdded ?? []).length;
29073
- chars += JSON.stringify(message.toolsRemoved ?? []).length;
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, /^- [^\n]*(?:\n|$)/gmu);
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, pattern = /^\[e?\d+\] [^\n]*(?:\n|$)/gmu) {
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
- blocks.push(region.slice(start, end));
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, MIN_QUERY_TOKENS = 2000, GUARD_MARKER = "[AutoRAG context guard: omitted context to stay within the model context budget.]", RETRIEVAL_TOOL_PREFIX = "search_datasource_", RETRIEVAL_TOOL_NAMES;
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 = Math.ceil((ctx.getSystemPrompt().length + JSON.stringify(toolDeclarations).length) / 4);
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 extname8 } from "node:path";
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 extname8(filename).toLowerCase();
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 extname9 } from "node:path";
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 = extname9(href).toLowerCase();
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 basename14, dirname as dirname26, join as join50, resolve as resolve17 } from "node:path";
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)), basename14(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 spawn20 } from "node:child_process";
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 = spawn20(command, args, { stdio: ["ignore", "ignore", "pipe"] });
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 DEFAULT_TIMEOUT_MS13;
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 DEFAULT_TIMEOUT_MS13 = 1e4;
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 spawn21 } from "node:child_process";
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 = spawn21) {
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);