@autorag/librarian 2.7.0 → 2.8.0

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.
Files changed (46) hide show
  1. package/NOTICE +6 -0
  2. package/README.md +66 -23
  3. package/dist/agent/agent.d.ts +119 -25
  4. package/dist/agent/answer-guidelines.d.ts +19 -0
  5. package/dist/agent/citations.d.ts +20 -0
  6. package/dist/agent/index.d.ts +1 -0
  7. package/dist/agent/jev-extension.d.ts +68 -0
  8. package/dist/agent/pi-session.d.ts +21 -1
  9. package/dist/agent/query-decomposition.d.ts +25 -0
  10. package/dist/agent/query-routing.d.ts +54 -0
  11. package/dist/agent/search-documents.d.ts +2 -2
  12. package/dist/agent/system-prompt.d.ts +1 -0
  13. package/dist/cli/commands/evidence.d.ts +22 -0
  14. package/dist/cli/commands/init.d.ts +2 -1
  15. package/dist/cli/commands/update-check.d.ts +8 -0
  16. package/dist/cli/config.d.ts +66 -1
  17. package/dist/cli/index.d.ts +1 -1
  18. package/dist/cli/index.js +9432 -8427
  19. package/dist/cli/update-check.d.ts +34 -0
  20. package/dist/cli/version.d.ts +5 -0
  21. package/dist/core.d.ts +33 -1
  22. package/dist/core.js +9505 -8630
  23. package/dist/everything/bundle.d.ts +15 -3
  24. package/dist/everything/client.d.ts +22 -5
  25. package/dist/everything/index.d.ts +1 -1
  26. package/dist/filesystem/name-search.d.ts +57 -0
  27. package/dist/fsearch/client.d.ts +7 -1
  28. package/dist/index.d.ts +1 -0
  29. package/dist/index.js +10824 -8655
  30. package/dist/jikji/client.d.ts +6 -1
  31. package/dist/mcp/index.d.ts +2 -0
  32. package/dist/mcp/index.js +29949 -0
  33. package/dist/mcp/server.d.ts +9 -0
  34. package/dist/minsync/method.d.ts +6 -3
  35. package/dist/mirror/index.d.ts +1 -1
  36. package/dist/mirror/paths.d.ts +6 -0
  37. package/dist/retrieval/engine.d.ts +32 -1
  38. package/dist/retrieval/index.d.ts +2 -1
  39. package/dist/retrieval/rerank.d.ts +2 -0
  40. package/dist/retrieval/selection.d.ts +97 -0
  41. package/package.json +7 -3
  42. package/skills/autorag/SKILL.md +25 -4
  43. package/skills/autorag-doctor/SKILL.md +27 -18
  44. package/skills/autorag-lite-setup/SKILL.md +115 -59
  45. package/skills/autorag-setup/SKILL.md +79 -7
  46. package/skills/autorag-lite-search/SKILL.md +0 -245
package/NOTICE CHANGED
@@ -18,6 +18,9 @@ License: MIT
18
18
  @earendil-works/pi-tui@0.86.1
19
19
  License: MIT
20
20
 
21
+ @modelcontextprotocol/server@2.3.0
22
+ License: Apache-2.0
23
+
21
24
  @openrouter/sdk@1.4.21
22
25
  License: Apache-2.0
23
26
 
@@ -30,6 +33,9 @@ License: MIT
30
33
  iconv-lite@0.7.3
31
34
  License: MIT
32
35
 
36
+ jev-use@0.8.0
37
+ License: MIT
38
+
33
39
  jszip@3.10.1
34
40
  License: (MIT OR GPL-3.0-or-later)
35
41
 
package/README.md CHANGED
@@ -80,6 +80,8 @@ AutoRAG uses `@earendil-works/pi-coding-agent` as the runtime host for model ses
80
80
 
81
81
  The CLI TUI (`autorag tui`) is Pi's interactive mode hosted on the AutoRAG librarian: there is no separate AutoRAG renderer. Pi owns the terminal UI and its native in-session commands — `/login`/`/logout`, `/model`, `/resume`, `/new`, `/tree`, `/compact`, and `/settings` — so provider sign-in and model selection work on first launch even when no AutoRAG model is configured. AutoRAG registers its retrieval tools and streams progress, preliminary answers, and final results into the same Pi session, so resume and two-phase search keep working together.
82
82
 
83
+ Update notices are AutoRAG's, not Pi's: `autorag tui` suppresses Pi's "run `pi update`" banner (Pi is a bundled host, not a separate install) and instead checks the published `@autorag/librarian` release, showing a one-line notice in the session when a newer version exists. Set `AUTORAG_NO_UPDATE_CHECK=1` to skip the lookup; `AUTORAG_UPDATE_CHECK_URL` overrides the registry endpoint.
84
+
83
85
 
84
86
  ---
85
87
 
@@ -89,19 +91,20 @@ If you are an AI coding agent or LLM (Claude Code, Cursor, Windsurf, Codex, Senp
89
91
 
90
92
  | Skill | Directory | When to Use |
91
93
  |---|---|---|
92
- | **`autorag`** | [`skills/autorag/`](skills/autorag/SKILL.md) | Querying, searching, comparing, and summarizing documents with an already configured AutoRAG librarian. |
93
- | **`autorag-setup`** | [`skills/autorag-setup/`](skills/autorag-setup/SKILL.md) | Installing AutoRAG, configuring models, adding document roots/datasources, running health checks, and repairing indexes. |
94
- | **`autorag-lite-setup`** | [`skills/autorag-lite-setup/`](skills/autorag-lite-setup/SKILL.md) | Initializing and maintaining the model-free AutoRAG Lite lifecycle without an LLM. |
95
- | **`autorag-lite-search`** | [`skills/autorag-lite-search/`](skills/autorag-lite-search/SKILL.md) | Performing model-free retrieval, reporting evidence, and recording feedback without an LLM. |
94
+ | **`autorag`** | [`skills/autorag/`](skills/autorag/SKILL.md) | Model-backed querying, searching, comparing, and summarizing with an already configured AutoRAG librarian. |
95
+ | **`autorag-setup`** | [`skills/autorag-setup/`](skills/autorag-setup/SKILL.md) | Installing AutoRAG, configuring the model-backed librarian, adding roots/datasources, running health checks, and registering Lite MCP when needed. |
96
+ | **`autorag-lite-setup`** | [`skills/autorag-lite-setup/`](skills/autorag-lite-setup/SKILL.md) | Installing/registering `autorag-mcp`, initializing model-free config, maintaining indexes, and verifying MCP search. |
96
97
 
97
98
  ### Install the skills into your coding agent
98
99
 
99
- Skills are not auto-discovered — copy the folders you want into the agent's skill directory. For **Claude Code** that directory is `.claude/skills/` in the project (or `~/.claude/skills/` to enable them everywhere). Once `autorag-lite-setup` and `autorag-lite-search` are in place, Claude Code drives `autorag lite retrieve` as a search tool:
100
+ Skills are not auto-discovered — copy only the setup skill when an agent needs
101
+ to bootstrap AutoRAG. **Routine AutoRAG Lite retrieval is provided by MCP
102
+ tools, not by a `autorag-lite-search` skill or shell command.**
100
103
 
101
104
  ```bash
102
105
  # From a clone of this repository
103
106
  mkdir -p .claude/skills
104
- cp -R skills/autorag-lite-setup skills/autorag-lite-search .claude/skills/
107
+ cp -R skills/autorag-lite-setup .claude/skills/
105
108
  ```
106
109
 
107
110
  ```bash
@@ -109,10 +112,19 @@ cp -R skills/autorag-lite-setup skills/autorag-lite-search .claude/skills/
109
112
  AUTORAG_SKILLS="$(npm root -g)/@autorag/librarian/skills"
110
113
  # Bun global installs live at ~/.bun/install/global/node_modules/@autorag/librarian/skills
111
114
  mkdir -p .claude/skills
112
- cp -R "$AUTORAG_SKILLS/autorag-lite-setup" "$AUTORAG_SKILLS/autorag-lite-search" .claude/skills/
115
+ cp -R "$AUTORAG_SKILLS/autorag-lite-setup" .claude/skills/
113
116
  ```
114
117
 
115
- Copy `skills/autorag` and `skills/autorag-setup` the same way when the agent should also drive the model-backed librarian, and `skills/autorag-doctor` for diagnostics. Other agents read their own directories (for example `~/.agents/skills/`) — copy the same folders there and reload the agent session so it picks them up.
118
+ Run the setup skill once to register the stdio server with the host. Reload the
119
+ agent, then discover the actual tool names and schemas with MCP `tools/list`.
120
+ The normal Lite path is `autorag.status` → `autorag.refresh` when needed →
121
+ `autorag.search`; use `autorag.report`, `autorag.evidence`, and
122
+ `autorag.feedback` for the optional curation lifecycle. Copy `skills/autorag`
123
+ and `skills/autorag-setup` only when the agent should also drive the
124
+ model-backed librarian, and `skills/autorag-doctor` for diagnostics. Other
125
+ agents read their own skill directories; copy the same setup folder there and
126
+ reload the agent session so it picks up the MCP registration instructions.
127
+ Do not copy or retain the removed `autorag-lite-search` skill.
116
128
 
117
129
  ### Quick Agent Workflow
118
130
 
@@ -136,6 +148,29 @@ Copy `skills/autorag` and `skills/autorag-setup` the same way when the agent sho
136
148
 
137
149
  ---
138
150
 
151
+ ## AutoRAG Lite MCP Server
152
+
153
+ Register the package's stdio server with the host; the host owns the process
154
+ lifecycle and sends MCP tool calls:
155
+
156
+ ```bash
157
+ AUTORAG_CONFIG=/absolute/path/to/.autorag/config.json autorag-mcp
158
+ ```
159
+
160
+ For Claude Code and Codex registration commands, use
161
+ [`skills/autorag-lite-setup/SKILL.md`](skills/autorag-lite-setup/SKILL.md).
162
+ The MCP contract source of truth is [`src/mcp/server.ts`](src/mcp/server.ts)
163
+ (tool registration, schemas, handlers) plus [`src/mcp/index.ts`](src/mcp/index.ts)
164
+ (stdio entrypoint). Discover tools and schemas with MCP `tools/list`; do not
165
+ hard-code a tool count.
166
+
167
+ Core Lite tools include `autorag.status`, `autorag.search`,
168
+ `autorag.search.files`, `autorag.datasources.list`, `autorag.datasources.get`,
169
+ `autorag.refresh`, `autorag.report`, `autorag.evidence`, and
170
+ `autorag.feedback`. Configured integrated datasources expose additional scoped
171
+ search tools. Read-only MCP mode omits mutating tools such as refresh, report,
172
+ and feedback.
173
+
139
174
  ## ⚡ AutoRAG Lite: Model-Free Retrieval Engine
140
175
 
141
176
  Need blazing fast local search without configuring an LLM or paying for API tokens? Use **AutoRAG Lite**.
@@ -143,8 +178,8 @@ Need blazing fast local search without configuring an LLM or paying for API toke
143
178
  AutoRAG Lite provides the exact same high-performance indexing, BM25 ranking, and local MinSync vector/hybrid retrieval engine as the full librarian, but **runs 100% model-free**:
144
179
 
145
180
  - **Zero LLM Token Usage:** Run purely local BM25 and vector search offline.
146
- - **Agent Integration Ready:** Use `autorag lite retrieve` inside your own agentic workflows to supply raw context chunks to an external model.
147
- - **Fast Local CLI:** Instant responses directly from your terminal.
181
+ - **Agent Integration Ready:** Use the AutoRAG Lite MCP server to supply raw context chunks to an external model; the CLI remains a bootstrap and maintenance interface.
182
+ - **Fast Local CLI:** The CLI remains available for terminal-only indexing and repair.
148
183
 
149
184
  ```bash
150
185
  # Initialize a model-free workspace
@@ -152,14 +187,12 @@ autorag lite init --search-paths ./documents
152
187
 
153
188
  # Index local files and datasources
154
189
  autorag lite refresh
155
-
156
- # Retrieve ranked document chunks (returns JSON candidates with scores)
157
- autorag lite retrieve "compliance policy exception process" --top-k 5 --json
158
-
159
- # Check index status and freshness
160
- autorag lite status
161
190
  ```
162
191
 
192
+ Normal Lite retrieval runs through the MCP tools (`autorag.status`,
193
+ `autorag.search`); the CLI remains the bootstrap and maintenance interface for
194
+ indexing and repair.
195
+
163
196
  ---
164
197
 
165
198
  ## 🔌 Supported Datasources
@@ -179,6 +212,7 @@ AutoRAG Agent connects to external tools and communication platforms using dedic
179
212
  | **Local Mail Export**| `mail-export` | Built-in `.mbox` / `.eml` parser | Local filesystem mailboxes | Lexical |
180
213
  | **Obsidian Vaults** | `obsidian` | [`qmd`](https://github.com/tobi/qmd) CLI | Direct markdown vault indexing | BM25, Semantic |
181
214
  | **GitHub** | `github` | GitHub REST API | In-memory fetched Issues and Pull Requests | Lexical, Scoped |
215
+ | **GitHub Gists** | `github-gist` | GitHub REST API | Incremental local index of own-account public and permitted secret Gist content/metadata; token not stored | Lexical (BM25), Local Semantic, Scoped |
182
216
  | **Cloud Drives** | `cloud-drive` | [`rclone`](https://rclone.org) CLI | Google Drive (Tier-1), OneDrive, Dropbox, etc. | Incremental Mirror + BM25 |
183
217
  | **Photos & Shots** | `clawgallery` | `clawgallery` CLI | Local screenshot and photo store | Hybrid OCR/Visual Search |
184
218
  | **RSS / News** | `rss` | Native HTTP Poller | RSS 2.0 & Atom feeds (24h deduplication) | Lexical |
@@ -295,11 +329,12 @@ agent.recordFeedbackByNumbers(response.sessionId, [1], [2]);
295
329
  | `autorag status` | Inspect corpus freshness, indexing status, and vector readiness |
296
330
  | `autorag health` | Check model provider authentication, token validity, and API reachability |
297
331
  | `autorag models list` | List chat models the pi runtime can resolve (built-ins, `models.json`, custom/extension providers) with provider auth status; never prints credential values |
332
+ | `autorag update-check` | Compare the running `autorag` against the published npm version (also runs on `autorag tui` launch) |
298
333
  | `autorag tui` | Open Pi's interactive librarian TUI (`/login`, `/model`, `/resume`, …) |
299
334
  | `autorag duplicates [DIR]` | Read-only scan for exact and near-duplicate document families with `dupey` |
300
- | `autorag lite ...` | Model-free indexing, retrieval, report generation, and status |
301
- | `autorag feedback <session>` | Record useful / not-useful feedback by item number |
302
- | `autorag evidence <session>` | Inspect exact underlying document chunks and sources for a past query |
335
+ | `autorag lite ...` | CLI bootstrap, indexing repair, terminal maintenance, and fallback interface; agents use MCP for normal Lite operation |
336
+ | `autorag feedback <session>` | Record numbered feedback; MCP clients normally use `autorag.feedback`, and the CLI stays available for terminal maintenance |
337
+ | `autorag evidence <session>` | Inspect persisted evidence behind numbered results; MCP clients normally use `autorag.evidence`, and the CLI stays available for terminal maintenance |
303
338
  | `autorag serve` | Start the P2P query server over SimpleX (opt-in) |
304
339
  | `autorag p2p ...` | Manage peer trust, query approvals, and sharing policies |
305
340
 
@@ -312,6 +347,7 @@ Deep dive into AutoRAG Agent's architecture, security, and integration guides:
312
347
  - **[MinSync Setup & Embedding QA](docs/minsync-setup.md):** Automatic binary installation, CDC chunking, and EmbeddingGemma verification.
313
348
  - **[Local Embedding Runtime & Gateway](docs/embedding-runtime.md):** AutoRAG-owned local gateway, model prefetching, and zero-egress semantic search. Model cards: [`qwen3-embedding-0.6b`](docs/model-cards/qwen3-embedding-0.6b.md), [`embeddinggemma-300m`](docs/model-cards/embeddinggemma-300m.md).
314
349
  - **[Datasource Skills Reference](docs/datasource-skills.md):** Full configuration contracts, connection aliases, and connector options.
350
+ - **[Jev Decisions](docs/jev-decisions.md):** Jev query pipeline, **on by default** via OpenRouter: it routes each question to local search, web search, or a direct answer, splits multi-part questions into up to five parallel searches (`openrouter/qwen/qwen3.7-flash`), and ends the run after the fast answer when that answer is complete. Also covers the `jev` judgment tool, backends (OpenRouter, TypeSafe, Vercel AI Gateway), and how to opt out.
315
351
  - **[Manual QA & Datasource Test Harnesses](docs/manual-qa-datasources.md):** Real-world testing guides for Discord, KakaoTalk, Slack, Notion, and email.
316
352
  - **[P2P SimpleX Sharing & Path Standard](docs/p2p-path-standard.md):** Decentralized peer query sharing with SimpleX, PII redaction, and approval queues.
317
353
  - **[Supply Chain Security & License Audits](docs/supply-chain.md):** Software bill of materials (SBOM) and dependency gate policies.
@@ -357,13 +393,19 @@ autorag health --json # model resolution + one live completion probe
357
393
  autorag gateway status --format json # on-demand embedding runtime
358
394
  ```
359
395
 
360
- Indexing is not the same thing as searchability, so always confirm retrieval itself — this needs no model:
396
+ Indexing is not the same thing as searchability, so always confirm retrieval
397
+ itself through the connected Lite MCP server:
361
398
 
362
- ```bash
363
- autorag lite retrieve 'a word that certainly appears' --top-k 3 --json
364
- autorag lite retrieve 'recent topic' --tags discord --top-k 3 --json
399
+ ```text
400
+ autorag.status {}
401
+ autorag.refresh {}
402
+ autorag.search {"query":"a word that certainly appears","topK":3}
403
+ autorag.search {"query":"recent topic","tags":["discord"],"topK":3}
365
404
  ```
366
405
 
406
+ The CLI equivalents remain available for terminal repair, but do not use them
407
+ as the agent's normal Lite search path.
408
+
367
409
  Common failures and their fix:
368
410
 
369
411
  | Symptom | Diagnostic code | Fix |
@@ -375,6 +417,7 @@ Common failures and their fix:
375
417
  | A datasource errors during refresh | `datasource-index-failed` | run that CLI's own `doctor` |
376
418
  | MinSync or Jikji missing | `minsync-unavailable`, `jikji-unavailable` | check the Rust toolchain, re-run refresh |
377
419
  | Windows file-name search fails during refresh | `everything-index-failed` | read the ES exit code and stderr in the message, then `autorag refresh --method everything --json` |
420
+ | Every search does a full local search and verification, even for small talk | `query-route-fallback` | set `OPENROUTER_API_KEY` (Jev routing and decomposition are on by default) |
378
421
 
379
422
  Native datasource stores stay owned by their CLIs — AutoRAG never rebuilds them. Fix a broken archive with `lazykatok doctor`, `discrawl --json metadata`, `slacrawl --json doctor`, `wacrawl --json doctor`, `telecrawl --json doctor`, `notcrawl doctor`, `qmd status`, or `mailcrawl doctor`, then re-run `autorag refresh --method datasources --json`.
380
423
 
@@ -17,11 +17,14 @@ import type { PeerQueryResponse } from "../p2p/wire.js";
17
17
  import { type DefaultParserRegistryOptions } from "../parser/index.js";
18
18
  import { RetrievalEngine } from "../retrieval/engine.js";
19
19
  import { RetrievalMethodRegistry } from "../retrieval/registry.js";
20
+ import type { DatasourceCatalogEntry } from "../retrieval/selection.js";
20
21
  import type { CuratedResult, RetrievalDiagnostic, RetrievalOptions, RetrievalResult } from "../retrieval/types.js";
21
22
  import { type ScanDuplicateDocumentsDetails } from "./dupey-tool.js";
22
23
  import { type AutoRAGFastAnswerDetails } from "./fast-answer-tool.js";
24
+ import { type JevToolOptions } from "./jev-extension.js";
23
25
  import { type JikjiFindProviderResult } from "./jikji-find-tool.js";
24
26
  import { type AutoRAGPiInteractiveRuntime, type AutoRAGPiSession } from "./pi-session.js";
27
+ import { type QueryRoute } from "./query-routing.js";
25
28
  import { type RefreshProgressCounts, type RefreshProgressPhase } from "./refresh-progress.js";
26
29
  import { type SearchDocumentDiagnostic, type SearchDocumentsResponse, type SearchDocumentsStreamEvent } from "./search-documents.js";
27
30
  import { type WatcherFactory, type WatchRefreshHandle } from "./watch-refresh.js";
@@ -36,7 +39,7 @@ import { type WebSearchToolOptions } from "./web-search-tool.js";
36
39
  export interface AutoRAGRetrievalLimits {
37
40
  /** `search_all_documents` merge ceiling when the model omits `topK`. Default 500. */
38
41
  readonly mergedEvidenceCeiling?: number;
39
- /** `search_datasource_*` merge default when the model omits `topK`. Default 50. */
42
+ /** `search_datasource_*` merge default when the model omits `topK`. Default 20. */
40
43
  readonly singleDatasourceTopK?: number;
41
44
  /** MinSync semantic retrieval default `topK`. Default 50. */
42
45
  readonly minSyncTopK?: number;
@@ -160,12 +163,10 @@ export declare class RemoteSessionRejectedError extends Error {
160
163
  /** Thinking level applied per search phase. "off" requests no reasoning. */
161
164
  export type AutoRAGThinkingLevel = "off" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max";
162
165
  /**
163
- * Two-phase progressive answers: the fast phase delivers an immediate first
164
- * answer with {@link AutoRAGThinkingOptions.fast} thinking (default "off"),
165
- * then the verification phase re-checks and finalizes with
166
- * {@link AutoRAGThinkingOptions.final} thinking (default "high"). Pass
167
- * `false` on {@link AutoRAGAgentOptions.thinking} to keep the legacy
168
- * single-phase flow.
166
+ * Per-phase thinking for AutoRAG's two-phase search: the fast phase delivers
167
+ * an immediate first answer with {@link AutoRAGThinkingOptions.fast} thinking
168
+ * (default "off"), then the verification phase re-checks and finalizes with
169
+ * {@link AutoRAGThinkingOptions.final} thinking (default "high").
169
170
  */
170
171
  export interface AutoRAGThinkingOptions {
171
172
  /** Thinking level for the immediate first answer. Default "off". */
@@ -233,6 +234,29 @@ export interface AutoRAGAgentOptions {
233
234
  autoRefresh?: AutoRefreshOptions;
234
235
  parserOptions?: DefaultParserRegistryOptions;
235
236
  dupey?: DupeyCliOptions | false;
237
+ /**
238
+ * Jev (TypeSafe's judgment model: typed questions in, calibrated
239
+ * probabilities out). When set, the two-phase search asks Jev before the
240
+ * fast answer whether the question needs local search, web search, or a
241
+ * direct answer, and whether to decompose it; after the fast answer, whether
242
+ * verification is needed. It also exposes the `jev` tool. Always omitted for
243
+ * remote P2P sessions.
244
+ *
245
+ * The CLI config enables this by default on OpenRouter (`buildAgentOptions`
246
+ * fills it in). On this programmatic option, absent or `false` keeps Jev
247
+ * off, so library callers never make paid network calls they did not ask for.
248
+ */
249
+ jev?: JevToolOptions | false;
250
+ /**
251
+ * Question decomposition used by the Jev query pipeline. `model` (with its
252
+ * `apiKey`) is the LLM that splits one question into at most five search
253
+ * queries; omitted, the search session's own model decomposes. The CLI
254
+ * resolves its configured or default model (`openrouter/qwen/qwen3.7-flash`).
255
+ */
256
+ queryDecomposition?: {
257
+ readonly model?: Model<Api>;
258
+ readonly apiKey?: string;
259
+ };
236
260
  excludeExactDuplicates?: boolean;
237
261
  excludePaths?: readonly string[];
238
262
  /**
@@ -256,14 +280,20 @@ export interface AutoRAGAgentOptions {
256
280
  peerQuery?: PeerQueryOptions | false;
257
281
  /** Restrict the agent to retrieval and result-emission tools for remote runs. */
258
282
  remoteSession?: boolean;
259
- /** Two-phase progressive answers with per-phase thinking control. Default enabled. */
260
- thinking?: AutoRAGThinkingOptions | false;
283
+ /** Per-phase thinking levels for the two-phase (fast → verification) search. */
284
+ thinking?: AutoRAGThinkingOptions;
261
285
  /** pi agent directory for auth/models/extensions. Defaults to ~/.pi/agent. */
262
286
  piAgentDir?: string;
263
287
  /** Optional persistent pi session directory. */
264
288
  piSessionDir?: string;
265
289
  /** Persist one pi session transcript per AutoRAG search. Defaults true. */
266
290
  persistPiSessions?: boolean;
291
+ /**
292
+ * Best-effort provider for an interactive-only startup notice (e.g. a newer
293
+ * AutoRAG release). Resolves to the notice text or `undefined`; never fails
294
+ * a launch.
295
+ */
296
+ updateNotice?: () => Promise<string | undefined>;
267
297
  }
268
298
  /** Post-merge reranking options. Mirrors the CLI `RerankConfig` (secrets via env). */
269
299
  export interface RerankAgentOptions {
@@ -320,15 +350,11 @@ export declare class AutoRAGAgent {
320
350
  private modelNativeSearchAuth;
321
351
  private retrievalTrace;
322
352
  private preliminaryCallback;
323
- /** Per-phase thinking levels; undefined marks the legacy single-phase flow. */
353
+ /** Per-phase thinking levels of the two-phase search. */
324
354
  private readonly fastThinkingLevel;
325
355
  private readonly finalThinkingLevel;
326
356
  private autoRefreshTimer;
327
357
  private refreshing;
328
- private jikjiPrepareInFlight;
329
- private jikjiReady;
330
- private minSyncPrepareInFlight;
331
- private minSyncReady;
332
358
  private refreshState;
333
359
  private readonly searchPaths;
334
360
  private readonly configuredSearchPaths;
@@ -352,6 +378,15 @@ export declare class AutoRAGAgent {
352
378
  private readonly datasourceAgentSkills;
353
379
  private readonly parserOptions;
354
380
  private readonly dupeyOptions;
381
+ /** pi extension registering the optional `jev` tool; undefined when disabled. */
382
+ private readonly jevExtension;
383
+ /** Jev judge shared by the `jev` tool and the query router; undefined when disabled. */
384
+ private readonly jevJudge;
385
+ private readonly queryDecompositionModel;
386
+ /** Web search routing for the pipeline's web branch; undefined when web tools are off. */
387
+ private readonly webSearchOptions;
388
+ /** Routing diagnostics for the in-flight search; reset per run. */
389
+ private routingDiagnostics;
355
390
  private readonly excludeExactDuplicates;
356
391
  private readonly excludePaths;
357
392
  private readonly baseSystemPromptConfig;
@@ -361,6 +396,7 @@ export declare class AutoRAGAgent {
361
396
  private readonly piAgentDir;
362
397
  private readonly piSessionDir;
363
398
  private readonly persistPiSessions;
399
+ private readonly updateNotice;
364
400
  private boundPiRuntime;
365
401
  /** True when this agent was constructed for an untrusted remote peer. */
366
402
  readonly remoteSession: boolean;
@@ -416,6 +452,23 @@ export declare class AutoRAGAgent {
416
452
  * datasource skill; duplicate ids collapse to the first registration.
417
453
  */
418
454
  private singleDatasourceToolSpecs;
455
+ /**
456
+ * Authorized configured datasource descriptors for catalog/listing surfaces.
457
+ *
458
+ * Built from the same trusted, server-bound access context as
459
+ * {@link buildAuthorizedDatasourceSkills}: only tag-authorized datasources
460
+ * are listed — including ones that expose no retrieval methods — and each
461
+ * entry carries only identity, capability tags, and authorized source scope
462
+ * strings (never credentials, config paths, or raw instance metadata).
463
+ * Duplicate datasource ids collapse to the first registration.
464
+ */
465
+ listDatasources(): DatasourceCatalogEntry[];
466
+ /**
467
+ * Opaque source scope strings for one datasource that the trusted context
468
+ * authorizes. Datasources without the `scoped` capability expose their
469
+ * sources unfiltered (they are gated only at the tag level).
470
+ */
471
+ private authorizedSourceScopes;
419
472
  /**
420
473
  * Resolve an authorized datasource agent skill by model-visible name for the
421
474
  * `load_datasource_skill` tool. Returns `undefined` for unknown or
@@ -425,20 +478,53 @@ export declare class AutoRAGAgent {
425
478
  private indexDatasources;
426
479
  /** Path-opaque component diagnostics for the search response. */
427
480
  private collectComponentDiagnostics;
481
+ /**
482
+ * Jev check run after emit_fast_answer: does the answer need correction,
483
+ * clarification, or further research? "No" ends the run with the fast
484
+ * answer as the final answer. Without Jev, or when the check fails, the run
485
+ * always continues into verification.
486
+ */
487
+ private shouldFollowUp;
488
+ /**
489
+ * Jev query pipeline, run before the fast answer. Jev picks the branch
490
+ * (local search, web search, or a direct answer) and whether the question
491
+ * needs decomposition; a "yes" splits it into at most five search queries
492
+ * with the configured decomposition model (default: the session model).
493
+ * Without Jev, and on any routing failure, this is today's single local
494
+ * search for the original question.
495
+ */
496
+ private planQuery;
497
+ /**
498
+ * Baseline local evidence for the fast answer. Jikji and MinSync run for
499
+ * every search query in parallel (MinSync itself queues per workspace), the
500
+ * per-query hits are interleaved and deduplicated into one pool, and that
501
+ * pool is reranked against the original question.
502
+ */
428
503
  private prefetchInitialRetrievalContext;
504
+ /** Baseline web evidence for the fast answer: one web search per query, all in parallel. */
505
+ private prefetchWebContext;
429
506
  /**
430
- * Prepare MinSync lazily without holding up the current search. Parsed
431
- * mirrors are built first because MinSync stages and indexes those mirrors.
507
+ * Rerank the pre-fast-answer baseline pool — Jikji answer paths plus MinSync
508
+ * chunks — down to the configured `rerank.topN`. With decomposition the pool
509
+ * merges every search query's hits (interleaved), capped at the same
510
+ * per-source sizes as a single query so the rerank request does not grow
511
+ * with the query count. Returns `undefined` when reranking is
512
+ * disabled/unavailable or the pool is empty, so the caller keeps the
513
+ * unranked sections; a rerank failure never blocks the fast answer.
432
514
  */
433
- /** Prepare MinSync in the background; the returned promise is for tests. */
434
- scheduleMinSyncPrepareForTest(): Promise<MinSyncSyncResult | undefined> | undefined;
435
- private scheduleMinSyncPrepare;
515
+ private rerankPrefetchPool;
436
516
  /**
437
517
  * Fast-phase prompt for two-phase searches. The baseline retrieval context
438
518
  * is already gathered, so the model answers immediately with thinking off
439
519
  * via emit_fast_answer, without any further tool calls.
440
520
  */
441
521
  buildFastAnswerPrompt(query: string, options: RetrievalOptions, baseline: string): string;
522
+ /**
523
+ * Prompt for a question Jev routed to a direct answer: general knowledge or
524
+ * small talk. No retrieval ran and no verification phase follows, so the
525
+ * answer emitted here is final.
526
+ */
527
+ buildDirectAnswerPrompt(query: string): string;
442
528
  /** Discovery-tool hint naming only the registered discovery tools; empty when none. */
443
529
  private discoveryHint;
444
530
  /**
@@ -447,7 +533,7 @@ export declare class AutoRAGAgent {
447
533
  * against it; the model then verifies with thinking on and finalizes with
448
534
  * emit_autorag_results exactly once, returning only the delta.
449
535
  */
450
- buildRefinementPrompt(query: string, options: RetrievalOptions, fastAnswer: AutoRAGFastAnswerDetails | undefined, fastAnswerDelivered: boolean): string;
536
+ buildRefinementPrompt(query: string, options: RetrievalOptions, fastAnswer: AutoRAGFastAnswerDetails | undefined, fastAnswerDelivered: boolean, route?: QueryRoute): string;
451
537
  buildSearchPrompt(query: string, options: RetrievalOptions, initialRetrievalContext?: string): string;
452
538
  refresh(force?: boolean, opts?: AutoRAGRefreshOptions): Promise<AutoRAGRefreshResult>;
453
539
  /**
@@ -504,13 +590,13 @@ export declare class AutoRAGAgent {
504
590
  */
505
591
  stopFsearch(): Promise<void>;
506
592
  prepareJikji(): Promise<readonly AutoRAGJikjiPrepareResult[] | undefined>;
507
- private executeJikjiPrepare;
508
593
  /**
509
- * Start Jikji preparation without delaying the current search turn. A
510
- * subsequent turn can use the prepared index, while the child process keeps
511
- * running after emit_autorag_results has terminated the agent loop.
594
+ * Build or incrementally update every root's Jikji index. Called only by
595
+ * refresh/watch (and the explicit `prepareJikji()` API), never by a query:
596
+ * `jikji prepare` reuses unchanged documents, and roots run in parallel so
597
+ * one slow root does not serialize the rest.
512
598
  */
513
- private scheduleJikjiPrepare;
599
+ private executeJikjiPrepare;
514
600
  private sanitizeJikjiPrepareResult;
515
601
  /**
516
602
  * Provider method for the jikji_find tool. Runs JikjiClient.find over all
@@ -527,6 +613,14 @@ export declare class AutoRAGAgent {
527
613
  * Merge per-root answer packs into one. Concatenates answer_paths/candidates
528
614
  * preserving per-root order; dedupes by normalized path. Does NOT cross-root
529
615
  * rerank when any root has agentShouldNotRerank=true.
616
+ *
617
+ * Honours `excludePaths` at the retrieval boundary: Jikji indexes the source
618
+ * folders directly, bypassing the parsed mirror, so an excluded source still
619
+ * appears in the on-disk `.jikji_agent_map.md`. Dropping excluded paths here
620
+ * keeps them out of the agent-facing answer pack (the `jikji_find` tool and
621
+ * the baseline prefetch) while leaving the shared map artifact complete.
622
+ * Excluded paths remain reachable through direct file reads, as Jikji never
623
+ * blocks source verification.
530
624
  */
531
625
  private mergeAnswerPacks;
532
626
  /**
@@ -0,0 +1,19 @@
1
+ /**
2
+ * The single file-path exception to the answer "no file paths" rule
3
+ * (issue #1790). Every prompt and tool description that shapes `answer` uses
4
+ * this exact wording so a caller that can render images receives a markdown
5
+ * image embed whose path is a real result source, while the no-path rule
6
+ * otherwise still stands.
7
+ */
8
+ export declare const ANSWER_IMAGE_EMBED_RULE = "**Images**: when a retrieved result is itself an image file (png, jpg, jpeg, gif, webp, svg, bmp, avif, heic, tiff) and showing it answers the question, embed it in `answer` as a markdown image on its own line: `![short description](<absolute source path>)`, followed by its citation, e.g. `![Q3 revenue chart](</data/reports/q3 chart.png>) [2]`. Use only the real source path of a result in `results`/`mapping`. Never invent a path, use relative paths, or embed remote URLs. Apart from these image embeds, the no-file-paths rule stands.";
9
+ /**
10
+ * Delta (verification) answers must not re-embed an image the first answer
11
+ * already showed.
12
+ */
13
+ export declare const ANSWER_IMAGE_DELTA_RULE = "An image already embedded in the first answer must not be embedded again.";
14
+ /**
15
+ * One numbering space for citations (issue #1788): every `[n]` in `answer`
16
+ * must be a `results[].number` emitted in the same call. Retrieval candidate
17
+ * numbers and first-answer unit numbers are never citation numbers.
18
+ */
19
+ export declare const ANSWER_CITATION_RULE = "**Citation numbers**: every bracketed citation [n] in `answer` must be the `number` of a result you emit in `results` of the same call. Numbers shown in retrieval candidates or in an earlier first answer are NOT citation numbers \u2014 renumber against your own `results`, and add a result for any evidence you cite.";
@@ -0,0 +1,20 @@
1
+ /** Sorted, de-duplicated citation numbers in `answer` with no matching result. */
2
+ export declare function unresolvedCitations(answer: string, results: readonly {
3
+ readonly number: number;
4
+ }[]): number[];
5
+ /** Remove citation markers whose number has no matching result. */
6
+ export declare function stripUnresolvedCitations(answer: string, results: readonly {
7
+ readonly number: number;
8
+ }[]): {
9
+ readonly answer: string;
10
+ readonly unresolved: readonly number[];
11
+ };
12
+ export declare function formatCitationList(numbers: readonly number[]): string;
13
+ /**
14
+ * Throw a corrective error when `answer` cites numbers absent from `results`.
15
+ * Emit tools surface the message to the model as a tool error so it re-emits
16
+ * with one consistent numbering.
17
+ */
18
+ export declare function assertCitationsResolve(label: string, answer: string, results: readonly {
19
+ readonly number: number;
20
+ }[]): void;
@@ -4,6 +4,7 @@ export { buildDatasourceSkillsPrompt, createLoadDatasourceSkillTool, type Dataso
4
4
  export { createScanDuplicateDocumentsTool, SCAN_DUPLICATE_DOCUMENTS_TOOL_NAME, type ScanDuplicateDocumentsDetails, type ScanDuplicateDocumentsProvider, } from "./dupey-tool.js";
5
5
  export type { AutoRAGEmittedResult, AutoRAGMappingEntry, AutoRAGResultsDetails, } from "./emit-results-tool.js";
6
6
  export { createEmitResultsTool, EMIT_AUTORAG_RESULTS_TOOL_NAME, emitResultsSchema, } from "./emit-results-tool.js";
7
+ export { createJevExtension, JEV_TOOL_NAME, type JevBackendName, type JevToolOptions, } from "./jev-extension.js";
7
8
  export { createJikjiFindTool, JIKJI_FIND_TOOL_NAME, type JikjiFindDetails, type JikjiFindPerRootPolicy, type JikjiFindProvider, type JikjiFindProviderResult, type MergedJikjiPolicy, } from "./jikji-find-tool.js";
8
9
  export { createQueryPeerAgentTool, QUERY_PEER_AGENT_TOOL_NAME, type QueryPeerAgentDetails, type QueryPeerAgentResult, type QueryPeerAgentToolOptions, } from "./query-peer-tool.js";
9
10
  export { createSearchAllDocumentsTool, SEARCH_ALL_DOCUMENTS_TOOL_NAME, type SearchAllDocumentsDetails, type SearchAllDocumentsProvider, type SearchAllDocumentsResult, } from "./search-all-tool.js";
@@ -0,0 +1,68 @@
1
+ import type { ExtensionFactory } from "@earendil-works/pi-coding-agent";
2
+ import { type JevBackend, type Judgment, type Question, type State } from "jev-use";
3
+ /** `jev` tool name, kept in AutoRAG's reserved set and system prompt. */
4
+ export declare const JEV_TOOL_NAME = "jev";
5
+ /**
6
+ * Jev backends the `jev-use` engine resolves from the environment, in
7
+ * auto-select order: TypeSafe -> OpenRouter -> Vercel AI Gateway.
8
+ */
9
+ export type JevBackendName = "typesafe" | "openrouter" | "vercel";
10
+ /**
11
+ * OpenRouter's live Jev model id. `jev-use` 0.8.0 ships `typesafe/jev-latest`,
12
+ * which OpenRouter rejects with HTTP 400 ("Model ... does not exist"), so the
13
+ * OpenRouter path is pinned here.
14
+ */
15
+ export declare const OPENROUTER_DEFAULT_MODEL = "typesafe/jev-1.13";
16
+ /**
17
+ * Options for the `jev` decision tool. Secrets never appear here: `jev-use`
18
+ * reads the backend credential from its own environment variable
19
+ * (`TYPESAFE_API_KEY`, `OPENROUTER_API_KEY`, or `AI_GATEWAY_API_KEY`).
20
+ */
21
+ export interface JevToolOptions {
22
+ /**
23
+ * Force one backend by name; omit to let the first credential present win.
24
+ * A ready-made `jev-use` backend instance is a programmatic seam (tests,
25
+ * custom transports); config only accepts names.
26
+ */
27
+ readonly backend?: JevBackendName | JevBackend;
28
+ /**
29
+ * Wire model id sent with every call. Omit for the backend default;
30
+ * OpenRouter is pinned to {@link OPENROUTER_DEFAULT_MODEL} because
31
+ * `jev-use` 0.8.0's own default (`typesafe/jev-latest`) is not a live
32
+ * OpenRouter model id.
33
+ */
34
+ readonly model?: string;
35
+ /** Escalate verdicts below this confidence. Default: per-source thresholds. */
36
+ readonly confidenceThreshold?: number;
37
+ }
38
+ /** {@link JevToolOptions} plus the environment `jev-use` resolves credentials from. */
39
+ export interface JevJudgeOptions extends JevToolOptions {
40
+ /** Environment consulted for the backend credential. Default `process.env`. */
41
+ readonly env?: Record<string, string | undefined>;
42
+ }
43
+ /**
44
+ * One batched Jev judgment. Rejects only when no backend can be built (for
45
+ * example a missing credential); an unreachable backend resolves with
46
+ * `escalate: true` verdicts, per `jev-use`'s contract.
47
+ */
48
+ export type JevJudge = (state: State, questions: Question[], options?: {
49
+ readonly confidenceThreshold?: number;
50
+ }) => Promise<Judgment>;
51
+ /**
52
+ * Builds the Jev judge shared by the `jev` tool and the query router. The
53
+ * `jev-use` client is created lazily on the first call, so no credential
54
+ * resolves at construction time, and the OpenRouter model pin applies to
55
+ * every caller.
56
+ */
57
+ export declare function createJevJudge(options?: JevJudgeOptions): JevJudge;
58
+ /**
59
+ * Builds the pi extension that registers the `jev` decision tool on top of the
60
+ * [`jev-use`](https://www.npmjs.com/package/jev-use) engine.
61
+ *
62
+ * Jev is TypeSafe's judgment model: typed questions about a state in, calibrated
63
+ * probabilities out — no generated text. `jev-use` owns backend auto-selection,
64
+ * request screening, and response validation; this extension only adapts the
65
+ * pi tool surface over {@link createJevJudge}. Pass the agent's shared judge
66
+ * so the tool and the query router reuse one lazily built client.
67
+ */
68
+ export declare function createJevExtension(judgeOrOptions?: JevJudge | JevToolOptions): ExtensionFactory;
@@ -1,6 +1,6 @@
1
1
  import type { AgentMessage, AgentTool } from "@earendil-works/pi-agent-core";
2
2
  import type { Api, Model } from "@earendil-works/pi-ai";
3
- import { type AgentSession, type AgentSessionRuntime, type ExtensionAPI } from "@earendil-works/pi-coding-agent";
3
+ import { type AgentSession, type AgentSessionRuntime, type ExtensionAPI, type ExtensionFactory, type ToolDefinition } from "@earendil-works/pi-coding-agent";
4
4
  export declare const PI_BUILTIN_TOOL_NAMES: readonly ["read", "bash", "edit", "write", "grep", "find", "ls"];
5
5
  export interface AutoRAGPiSessionOptions {
6
6
  readonly cwd: string;
@@ -13,6 +13,17 @@ export interface AutoRAGPiSessionOptions {
13
13
  readonly providerApiKeys?: Readonly<Record<string, string>>;
14
14
  readonly getSystemPrompt: () => string;
15
15
  readonly customTools: readonly AgentTool[];
16
+ /**
17
+ * Extra pi extensions to load alongside AutoRAG's own prompt/context
18
+ * extension. Each factory registers its tools, commands, and events with pi.
19
+ */
20
+ readonly extensionFactories?: readonly ExtensionFactory[];
21
+ /**
22
+ * Tool names registered by {@link extensionFactories}. pi's `tools`
23
+ * allow-list keeps only named tools active, so every extension tool that
24
+ * should be callable must appear here too.
25
+ */
26
+ readonly extensionToolNames?: readonly string[];
16
27
  readonly remoteSession?: boolean;
17
28
  readonly contextTransform?: (messages: AgentMessage[]) => Promise<AgentMessage[]>;
18
29
  }
@@ -20,12 +31,21 @@ export interface AutoRAGPiInteractiveRuntimeOptions extends Omit<AutoRAGPiSessio
20
31
  readonly model?: Model<Api>;
21
32
  readonly inactiveToolNames?: readonly string[];
22
33
  readonly onQuery: (query: string, pi: ExtensionAPI) => void | Promise<void>;
34
+ /**
35
+ * Optional best-effort provider for a startup update notice. Resolves to the
36
+ * notice text, or `undefined` when there is nothing to announce. Called once
37
+ * per session; failures are swallowed so the check never blocks or fails a
38
+ * launch.
39
+ */
40
+ readonly updateNotice?: () => Promise<string | undefined>;
23
41
  }
24
42
  export interface AutoRAGPiSession {
25
43
  readonly session: AgentSession;
26
44
  readonly baseToolNames: readonly string[];
27
45
  readonly sessionFile: string | undefined;
28
46
  }
47
+ /** Adapts a pi-agent-core {@link AgentTool} to pi's extension {@link ToolDefinition}. */
48
+ export declare function toToolDefinition(tool: AgentTool): ToolDefinition;
29
49
  /** Creates a pi session with AutoRAG's tools and prompt. */
30
50
  export declare function createAutoRAGPiSession(options: AutoRAGPiSessionOptions): Promise<AutoRAGPiSession>;
31
51
  export interface AutoRAGPiInteractiveRuntime {