@autorag/librarian 2.4.0 → 2.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.md CHANGED
@@ -16,6 +16,25 @@ AutoRAG itself is the specialized search agent, not a coordinator for other
16
16
  model roles. You configure one model, and that model owns the complete
17
17
  retrieval, reading, judgment, and curation loop.
18
18
 
19
+ ## Core values
20
+
21
+ Three principles drive every design decision:
22
+
23
+ 1. **Never migrate your data to search it.** AutoRAG federates CLI-owned
24
+ stores (katok, discrawl, qmd, msgvault, rclone, …) in place. No forced
25
+ ingestion into a central index, no third-party server holding a copy of
26
+ your corpus. Results carry source-native identities
27
+ (`kakao:<chat>/<sender>/<chunk>`) with scope-checked access — see the
28
+ [competitive landscape study](docs/competitive-landscape-2026-09.md) for
29
+ why this is the durable differentiator.
30
+ 2. **Just works — no RAG degree required.** Install it and it works: minimal
31
+ configuration, no pipeline tuning, no vector-DB operations, no API keys.
32
+ The local embedder (EmbeddingGemma via Ollama) and MinSync auto-install
33
+ handle the "RAG plumbing" invisibly.
34
+ 3. **Fast by design.** One configured model owns the whole loop; retrieval
35
+ runs locally over MinSync CDC chunks (BM25 / vector / hybrid); interactive
36
+ search is optimized for low latency.
37
+
19
38
  ## Why AutoRAG
20
39
 
21
40
  ### The problem with search tools
@@ -205,7 +224,7 @@ Security defaults are intentionally strict:
205
224
  | Notion | `notion` | external [`notcrawl`](https://github.com/openclaw/notcrawl) CLI | local-first page/database/block archive + FTS5 search |
206
225
  | GitHub Issues/PRs | `github` | GitHub REST (token optional) | issues + PR bodies per `owner/repo`; public repos work unauthenticated |
207
226
  | Cloud drives | `cloud-drive` | **[`rclone`](https://rclone.org) CLI** | Incremental Google Drive Tier-1; OneDrive/network remotes; iCloud experimental |
208
- | Gmail / IMAP | `gmail` | Gmail REST v1, or **[`himalaya`](https://pimalaya.org) CLI** (`backend: "himalaya"`) | the himalaya backend indexes any IMAP/Maildir account it has configured — no OAuth plumbing |
227
+ | Gmail | `gmail` | Gmail REST v1 | OAuth access token is referenced by environment variable name |
209
228
  | Local mail exports | `mail-export` | filesystem (`.mbox` / `.eml`) | classic `From_` splitting, mailparser-based; count-only warnings |
210
229
  | Mail archives | `mailcrawl` | external [`mailcrawl`](https://github.com/NomaDamas/mailcrawl) CLI | local email sync plus BM25, semantic, and hybrid retrieval |
211
230
  | Obsidian vault | `obsidian` | external [`qmd`](https://github.com/tobi/qmd) CLI | incremental `qmd update`, BM25 `qmd search`, semantic `qmd vsearch`; vault path via `connector.vaultPath` |
@@ -223,7 +242,7 @@ Configure them in `config.json` (CLI) or pass `datasourceSkills` programmaticall
223
242
  "slack": { "connector": { "binaryPath": "slacrawl", "configPath": "/path/to/slacrawl.yaml", "syncSource": "primary" } },
224
243
  "notion": { "connector": { "binaryPath": "notcrawl", "configPath": "/path/to/notcrawl.yaml" } },
225
244
  "github": { "connector": { "repos": ["owner/repo"] } },
226
- "gmail": { "connector": { "backend": "himalaya", "account": "gmail", "folder": "INBOX" } },
245
+ "gmail": { "connector": { "tokenEnv": "GMAIL_ACCESS_TOKEN", "labelIds": ["INBOX"] } },
227
246
  "mailcrawl": { "instanceId": "personal", "connector": { "account": "personal", "mailbox": "INBOX", "binaryPath": "mailcrawl" } },
228
247
  "personal-google-drive": { "type": "cloud-drive", "instanceId": "personal", "connector": { "provider": "google-drive", "remote": "personal-gdrive:", "include": ["**/*.md"] } },
229
248
  "company-onedrive": { "type": "cloud-drive", "instanceId": "work", "connector": { "provider": "onedrive", "remote": "company-onedrive:Documents" } },
@@ -253,6 +272,9 @@ in mailcrawl's native store unless the operator explicitly sets
253
272
  `connector.dataDir`; Himalaya credentials and provider configuration remain
254
273
  owned by mailcrawl. 0.1.3 and earlier fail a repeated
255
274
  `index` after a no-op sync.
275
+ Use `mailcrawl` for all Himalaya-backed IMAP/Maildir retrieval. The retired
276
+ `gmail` connector option `backend: "himalaya"` is no longer registered; migrate
277
+ that configuration to an explicit `mailcrawl` datasource.
256
278
 
257
279
  Install and authenticate rclone separately (`brew install rclone && rclone
258
280
  config` on macOS), then configure the provider-neutral `cloud-drive` skill.
@@ -5,22 +5,21 @@ import type { DatasourceIndexResult, DatasourceSkill } from "../datasource/types
5
5
  import { type DupeyCliOptions } from "../dupey/index.js";
6
6
  import { type JikjiFailureReason, type JikjiOptions } from "../jikji/index.js";
7
7
  import type { ResultFeedback } from "../memory/memory.js";
8
- import { type MinSyncBM25MethodOptions, type MinSyncSyncResult, type MinSyncVectorMethodOptions } from "../minsync/index.js";
8
+ import { type MinSyncSyncResult, type MinSyncVectorMethodOptions } from "../minsync/index.js";
9
9
  import { type ParsedMirrorSyncResult } from "../mirror/sync.js";
10
10
  import type { DefaultParserRegistryOptions } from "../parser/index.js";
11
- import { type BM25SyncResult } from "../retrieval/methods/bm25.js";
12
11
  import { RetrievalMethodRegistry } from "../retrieval/registry.js";
13
12
  import type { CuratedResult, RetrievalDiagnostic, RetrievalOptions, RetrievalResult } from "../retrieval/types.js";
14
13
  import { type ScanDuplicateDocumentsDetails } from "./dupey-tool.js";
15
14
  import { type JikjiFindProviderResult } from "./jikji-find-tool.js";
16
- import { type SearchDocumentDiagnostic, type SearchDocumentsResponse } from "./search-documents.js";
15
+ import { type SearchDocumentDiagnostic, type SearchDocumentsResponse, type SearchDocumentsStreamEvent } from "./search-documents.js";
17
16
  import { type WatcherFactory, type WatchRefreshHandle } from "./watch-refresh.js";
18
17
  export interface AutoRefreshOptions {
19
18
  readonly intervalMs: number;
20
19
  readonly immediate?: boolean;
21
20
  }
22
21
  /** Methods that `refresh` can selectively run. Defaults to all when omitted. */
23
- export type RefreshMethod = "parsed" | "bm25" | "minsync" | "datasources" | "jikji";
22
+ export type RefreshMethod = "parsed" | "minsync" | "datasources" | "jikji";
24
23
  export interface AutoRAGRefreshOptions {
25
24
  /** Restrict refresh to specific methods. Defaults to all when undefined. */
26
25
  readonly methods?: readonly RefreshMethod[];
@@ -32,12 +31,10 @@ export interface AutoRAGMinSyncRefreshResult {
32
31
  }
33
32
  export interface AutoRAGRefreshResult extends Omit<ParsedMirrorSyncResult, "diagnostics"> {
34
33
  readonly diagnostics: readonly SearchDocumentDiagnostic[];
35
- readonly bm25?: BM25SyncResult;
36
34
  readonly minsync?: AutoRAGMinSyncRefreshResult;
37
35
  readonly datasources?: readonly DatasourceIndexResult[];
38
36
  }
39
37
  export interface AutoRAGRefreshComponentStatus {
40
- readonly bm25?: string;
41
38
  readonly minsync?: string;
42
39
  readonly jikji?: string;
43
40
  readonly datasources?: string;
@@ -78,7 +75,6 @@ export interface AutoRAGAgentOptions {
78
75
  workspacePath?: string;
79
76
  tools?: AgentTool[];
80
77
  minSync?: Omit<MinSyncVectorMethodOptions, "root"> | false;
81
- bm25?: Omit<MinSyncBM25MethodOptions, "root"> | false;
82
78
  jikji?: JikjiOptions | false;
83
79
  autoRefresh?: AutoRefreshOptions;
84
80
  parserOptions?: DefaultParserRegistryOptions;
@@ -126,6 +122,10 @@ export declare class AutoRAGAgent {
126
122
  private resultCapture;
127
123
  private autoRefreshTimer;
128
124
  private refreshing;
125
+ private jikjiPrepareInFlight;
126
+ private jikjiReady;
127
+ private minSyncPrepareInFlight;
128
+ private minSyncReady;
129
129
  private refreshState;
130
130
  private readonly searchPaths;
131
131
  private readonly configuredSearchPaths;
@@ -137,7 +137,6 @@ export declare class AutoRAGAgent {
137
137
  private readonly merger;
138
138
  private readonly datasourceFilter;
139
139
  private readonly minSyncMethod;
140
- private readonly bm25Method;
141
140
  private readonly jikjiClient;
142
141
  private readonly datasourceSkills;
143
142
  private readonly datasourceAccessOptions;
@@ -151,12 +150,14 @@ export declare class AutoRAGAgent {
151
150
  private readonly searchTimeoutMs;
152
151
  private readonly maxSearchToolCalls;
153
152
  private searchToolCallCount;
153
+ private readonly sourceSearchCallCounts;
154
154
  constructor(options: AutoRAGAgentOptions);
155
155
  scanDuplicateDocuments(): Promise<ScanDuplicateDocumentsDetails>;
156
156
  private withMemoryContext;
157
157
  private resolveSessionModel;
158
158
  private createSearchSession;
159
159
  private configureSearchSession;
160
+ private withPerSourceSearchLimit;
160
161
  private recordSearchToolEvent;
161
162
  private currentSystemPromptConfig;
162
163
  subscribe(listener: Parameters<Agent["subscribe"]>[0]): () => void;
@@ -177,6 +178,13 @@ export declare class AutoRAGAgent {
177
178
  recordFeedbackByIds(usefulFeedbackIds: readonly string[], notUsefulFeedbackIds?: readonly string[]): void;
178
179
  getResultRegistry(sessionId?: string): ReadonlyMap<number, CuratedResult>;
179
180
  searchDocuments(query: string, options?: RetrievalOptions): Promise<SearchDocumentsResponse>;
181
+ /**
182
+ * Stream bounded progress updates while retaining the stable
183
+ * {@link searchDocuments} promise API. Progress is sourced from model text
184
+ * deltas, so callers can render it in a TUI, CLI, or parent agent and can
185
+ * stop by calling {@link abort}.
186
+ */
187
+ searchDocumentsStream(query: string, options?: RetrievalOptions): AsyncGenerator<SearchDocumentsStreamEvent, void, void>;
180
188
  private datasourceAccessContext;
181
189
  /**
182
190
  * Build the Pi agent-skill list for datasource skills authorized by the
@@ -191,9 +199,16 @@ export declare class AutoRAGAgent {
191
199
  */
192
200
  loadDatasourceSkill(name: string): Skill | undefined;
193
201
  private indexDatasources;
194
- /** Path-opaque component diagnostics (e.g. BM25 readiness) for the search response. */
202
+ /** Path-opaque component diagnostics for the search response. */
195
203
  private collectComponentDiagnostics;
196
204
  private prefetchInitialRetrievalContext;
205
+ /**
206
+ * Prepare MinSync lazily without holding up the current search. Parsed
207
+ * mirrors are built first because MinSync stages and indexes those mirrors.
208
+ */
209
+ /** Prepare MinSync in the background; the returned promise is for tests. */
210
+ scheduleMinSyncPrepareForTest(): Promise<MinSyncSyncResult | undefined> | undefined;
211
+ private scheduleMinSyncPrepare;
197
212
  buildSearchPrompt(query: string, options: RetrievalOptions, initialRetrievalContext?: string): string;
198
213
  refresh(force?: boolean, opts?: AutoRAGRefreshOptions): Promise<AutoRAGRefreshResult>;
199
214
  /**
@@ -221,10 +236,15 @@ export declare class AutoRAGAgent {
221
236
  */
222
237
  private scanMirrorStaleness;
223
238
  private exactDuplicateExclusions;
224
- syncBM25(minsync?: MinSyncSyncResult): Promise<BM25SyncResult | undefined>;
225
239
  syncMinSync(): Promise<MinSyncSyncResult | undefined>;
226
240
  prepareJikji(): Promise<readonly AutoRAGJikjiPrepareResult[] | undefined>;
227
241
  private executeJikjiPrepare;
242
+ /**
243
+ * Start Jikji preparation without delaying the current search turn. A
244
+ * subsequent turn can use the prepared index, while the child process keeps
245
+ * running after emit_autorag_results has terminated the agent loop.
246
+ */
247
+ private scheduleJikjiPrepare;
228
248
  private sanitizeJikjiPrepareResult;
229
249
  /**
230
250
  * Provider method for the jikji_find tool. Runs JikjiClient.find over all
@@ -283,7 +303,7 @@ export declare class AutoRAGAgent {
283
303
  results: RetrievalResult[];
284
304
  diagnostics: RetrievalDiagnostic[];
285
305
  }>;
286
- /** The retrieval method registry (posix active; vector/bm25/hybrid pluggable). */
306
+ /** The retrieval method registry (posix, MinSync, and datasource methods). */
287
307
  getMethodRegistry(): RetrievalMethodRegistry;
288
308
  getSystemPrompt(): string;
289
309
  private rerankWithMemory;
@@ -7,6 +7,6 @@ export { createEmitResultsTool, EMIT_AUTORAG_RESULTS_TOOL_NAME } from "./emit-re
7
7
  export { createJikjiFindTool, JIKJI_FIND_TOOL_NAME, type JikjiFindDetails, type JikjiFindPerRootPolicy, type JikjiFindProvider, type JikjiFindProviderResult, type MergedJikjiPolicy, } from "./jikji-find-tool.js";
8
8
  export { createSearchAllDocumentsTool, SEARCH_ALL_DOCUMENTS_TOOL_NAME, type SearchAllDocumentsDetails, type SearchAllDocumentsProvider, type SearchAllDocumentsResult, } from "./search-all-tool.js";
9
9
  export { createSearchDatasourceDocumentsTool, type DatasourceSearchProvider, SEARCH_DATASOURCE_DOCUMENTS_TOOL_NAME, type SearchDatasourceDocumentsDetails, } from "./search-datasource-tool.js";
10
- export type { SearchDocumentDiagnostic, SearchDocumentDiagnosticCode, SearchDocumentDiagnosticSeverity, SearchDocumentEvidence, SearchDocumentResult, SearchDocumentsResponse, SearchDocumentWarning, } from "./search-documents.js";
10
+ export type { SearchDocumentDiagnostic, SearchDocumentDiagnosticCode, SearchDocumentDiagnosticSeverity, SearchDocumentEvidence, SearchDocumentResult, SearchDocumentsResponse, SearchDocumentsStreamEvent, SearchDocumentWarning, } from "./search-documents.js";
11
11
  export { createSearchMinSyncDocumentsTool, SEARCH_MINSYNC_DOCUMENTS_TOOL_NAME, type SearchMinSyncDocumentsDetails, } from "./search-minsync-tool.js";
12
12
  export { buildSystemPrompt, type SystemPromptConfig } from "./system-prompt.js";
@@ -9,12 +9,12 @@ export type SearchDocumentDiagnosticSeverity = "info" | "warning" | "error";
9
9
  * (#21/#22) does not require another source-breaking type change; codes not yet
10
10
  * emitted are still valid members.
11
11
  */
12
- export type SearchDocumentDiagnosticCode = "empty-query" | "unknown-warning" | "caller-tool-dropped" | "bm25-unavailable" | "bm25-degraded-fallback" | "minsync-unavailable" | "parser-skipped" | "parser-failed" | "pdf-java-version" | "duplicate-excluded" | "unsupported-file" | "stale-index" | "deleted-mirror" | "pdf-extract-thin" | "pdf-hybrid-unavailable" | "retrieval-method-failed" | "jikji-unavailable" | "jikji-prepare-failed" | "jikji-find-failed" | "refresh-failed" | "watch-failed" | "watch-limited" | "unknown-datasource-skill";
12
+ export type SearchDocumentDiagnosticCode = "empty-query" | "unknown-warning" | "caller-tool-dropped" | "minsync-unavailable" | "parser-skipped" | "parser-failed" | "pdf-java-version" | "duplicate-excluded" | "unsupported-file" | "stale-index" | "deleted-mirror" | "pdf-extract-thin" | "pdf-hybrid-unavailable" | "retrieval-method-failed" | "jikji-unavailable" | "jikji-prepare-failed" | "jikji-find-failed" | "refresh-failed" | "watch-failed" | "watch-limited" | "unknown-datasource-skill";
13
13
  export interface SearchDocumentDiagnostic {
14
14
  readonly code: SearchDocumentDiagnosticCode;
15
15
  readonly severity: SearchDocumentDiagnosticSeverity;
16
16
  readonly message: string;
17
- /** Component label (e.g. "sanitizer", "bm25") or opaque virtual path — never a real filesystem path. */
17
+ /** Component label (e.g. "sanitizer", "minsync") or opaque virtual path — never a real filesystem path. */
18
18
  readonly source?: string;
19
19
  }
20
20
  export interface SearchDocumentEvidence {
@@ -43,6 +43,15 @@ export interface SearchDocumentsResponse {
43
43
  */
44
44
  readonly diagnostics?: readonly SearchDocumentDiagnostic[];
45
45
  }
46
+ export type SearchDocumentsStreamEvent = {
47
+ readonly type: "progress";
48
+ readonly sessionId: string;
49
+ readonly query: string;
50
+ readonly text: string;
51
+ } | {
52
+ readonly type: "complete";
53
+ readonly response: SearchDocumentsResponse;
54
+ };
46
55
  type SearchSessions = Map<string, {
47
56
  query: string;
48
57
  registry: Map<number, CuratedResult>;
@@ -0,0 +1,3 @@
1
+ import type { CommandContext } from "./types.js";
2
+ /** Show the persisted source/chunk evidence attached to a search session. */
3
+ export declare function runEvidence(ctx: CommandContext): Promise<number>;
@@ -1,7 +1,7 @@
1
1
  import type { CommandContext } from "./types.js";
2
2
  /**
3
3
  * Run the `autorag index` command. `reset` removes the parsed mirror
4
- * MinSync, and leftover legacy BM25 index directories under `.autorag`
4
+ * and MinSync indexes
5
5
  * (preserving `bin`, `datasources`, and the memory file). `rebuild` resets then re-runs a forced
6
6
  * refresh. Returns 0 on success, 2 for usage/decline errors, 1 for runtime
7
7
  * errors including path-escape guard violations.
@@ -2,13 +2,12 @@ import { type RefreshMethod } from "../../agent/agent.js";
2
2
  import type { CommandContext } from "./types.js";
3
3
  /**
4
4
  * `autorag refresh` — parse configured search paths and resync every active
5
- * index (parsed mirror, BM25, MinSync, datasources, jikji). Model-free: no LLM
5
+ * index (parsed mirror, MinSync, datasources, jikji). Model-free: no LLM
6
6
  * is constructed. Output is rendered through the path-opaque refresh renderer;
7
7
  * the raw result (which carries absolute `indexPath`) is never printed.
8
8
  *
9
- * `--method bm25,minsync,parsed` restricts which methods run. When omitted, all
10
- * methods run. Parsed mirrors are always synced when BM25 or MinSync is selected
11
- * (they index over the parsed mirrors).
9
+ * `--method minsync,parsed` restricts which methods run. When omitted, all
10
+ * methods run. Parsed mirrors are always synced when MinSync is selected.
12
11
  */
13
12
  export declare function runRefresh(ctx: CommandContext): Promise<number>;
14
13
  /**
@@ -21,10 +21,10 @@ export declare function classifySearchHealthHint(error: unknown): SearchHealthHi
21
21
  /**
22
22
  * Search-command dependencies. Tests inject `agentFactory` to bypass real
23
23
  * model construction and AutoRAGAgent instantiation, returning a stub whose
24
- * `searchDocuments` resolves a canned {@link SearchDocumentsResponse}.
24
+ * `searchDocumentsStream` yields progress and a canned completion.
25
25
  */
26
26
  export interface SearchDeps {
27
- agentFactory?: (opts: AutoRAGAgentOptions) => Pick<AutoRAGAgent, "searchDocuments">;
27
+ agentFactory?: (opts: AutoRAGAgentOptions) => Pick<AutoRAGAgent, "searchDocumentsStream">;
28
28
  modelResolver?: (config: CliConfig) => ResolvedAgentModel;
29
29
  }
30
30
  /**
@@ -24,7 +24,7 @@ export interface TuiPresenter {
24
24
  status(): string;
25
25
  reset(): void;
26
26
  }
27
- type TuiAgent = Pick<AutoRAGAgent, "searchDocuments"> & Partial<Pick<AutoRAGAgent, "subscribe" | "abort">>;
27
+ type TuiAgent = Pick<AutoRAGAgent, "searchDocumentsStream"> & Partial<Pick<AutoRAGAgent, "subscribe" | "abort">>;
28
28
  export interface TuiDeps {
29
29
  agentFactory?: (opts?: AutoRAGAgentOptions) => TuiAgent;
30
30
  modelResolver?: (config: CliConfig) => ResolvedAgentModel;
@@ -1,6 +1,6 @@
1
1
  import type { CommandContext } from "./types.js";
2
2
  /**
3
- * `autorag watch` — keep parsed/BM25/MinSync indexes current.
3
+ * `autorag watch` — keep parsed/MinSync indexes current.
4
4
  *
5
5
  * - default: long-running recursive fs watch with debounced refresh
6
6
  * - `--once`: single refresh tick (for cron / launchd / Task Scheduler)
@@ -10,13 +10,6 @@ export { AUTORAG_HOME_ENV, resolveAutoRAGHome } from "../config/home.js";
10
10
  export declare class ConfigError extends Error {
11
11
  constructor(message: string);
12
12
  }
13
- /**
14
- * Typed BM25 method config persisted in `config.json`. Missing `enabled` means
15
- * enabled (true). `false` as a top-level value is also accepted and disables.
16
- */
17
- export interface Bm25MethodConfig {
18
- enabled?: boolean;
19
- }
20
13
  /**
21
14
  * Typed MinSync method config persisted in `config.json`. Missing `enabled`
22
15
  * means enabled (true); `autoInstall` defaults to true. `embedder` carries
@@ -25,7 +18,6 @@ export interface Bm25MethodConfig {
25
18
  export interface MinSyncMethodConfig {
26
19
  enabled?: boolean;
27
20
  autoInstall?: boolean;
28
- binaryPath?: string;
29
21
  workspacePath?: string;
30
22
  maxChunkSize?: number;
31
23
  installer?: Omit<EnsureMinSyncBinaryOptions, "root">;
@@ -33,12 +25,10 @@ export interface MinSyncMethodConfig {
33
25
  }
34
26
  /** Indexing method config as it appears in a raw config file (before normalization). */
35
27
  export interface RawIndexingMethods {
36
- bm25?: Bm25MethodConfig | false;
37
28
  minSync?: MinSyncMethodConfig | false;
38
29
  }
39
30
  /** Result of {@link normalizeIndexingConfig}: always fully populated. */
40
31
  export interface NormalizedIndexingConfig {
41
- bm25: Bm25MethodConfig;
42
32
  minSync: MinSyncMethodConfig;
43
33
  }
44
34
  export interface UiConfig {
@@ -82,7 +72,6 @@ export interface CliConfig {
82
72
  memoryPath: string;
83
73
  model?: AgentModelConfig;
84
74
  minSync?: MinSyncMethodConfig;
85
- bm25?: Bm25MethodConfig;
86
75
  jikji?: Record<string, unknown> | false;
87
76
  parserOptions?: Record<string, unknown>;
88
77
  dupey?: {