@autorag/librarian 2.6.3 → 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 (54) hide show
  1. package/NOTICE +6 -0
  2. package/README.md +76 -25
  3. package/dist/agent/agent.d.ts +135 -27
  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 +55 -0
  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/health.d.ts +2 -3
  15. package/dist/cli/commands/init.d.ts +2 -1
  16. package/dist/cli/commands/models.d.ts +20 -0
  17. package/dist/cli/commands/search.d.ts +2 -2
  18. package/dist/cli/commands/serve.d.ts +2 -2
  19. package/dist/cli/commands/tui.d.ts +12 -35
  20. package/dist/cli/commands/update-check.d.ts +8 -0
  21. package/dist/cli/config.d.ts +82 -5
  22. package/dist/cli/index.d.ts +1 -1
  23. package/dist/cli/index.js +9802 -9324
  24. package/dist/cli/update-check.d.ts +34 -0
  25. package/dist/cli/version.d.ts +5 -0
  26. package/dist/core.d.ts +34 -2
  27. package/dist/core.js +9848 -8977
  28. package/dist/everything/bundle.d.ts +15 -3
  29. package/dist/everything/client.d.ts +22 -5
  30. package/dist/everything/index.d.ts +1 -1
  31. package/dist/filesystem/name-search.d.ts +57 -0
  32. package/dist/fsearch/client.d.ts +7 -1
  33. package/dist/index.d.ts +1 -0
  34. package/dist/index.js +11181 -9015
  35. package/dist/jikji/client.d.ts +6 -1
  36. package/dist/mcp/index.d.ts +2 -0
  37. package/dist/mcp/index.js +29949 -0
  38. package/dist/mcp/server.d.ts +9 -0
  39. package/dist/minsync/method.d.ts +6 -3
  40. package/dist/mirror/index.d.ts +1 -1
  41. package/dist/mirror/paths.d.ts +6 -0
  42. package/dist/retrieval/engine.d.ts +32 -1
  43. package/dist/retrieval/index.d.ts +2 -1
  44. package/dist/retrieval/rerank.d.ts +8 -3
  45. package/dist/retrieval/selection.d.ts +97 -0
  46. package/package.json +10 -3
  47. package/skills/autorag/SKILL.md +25 -4
  48. package/skills/autorag-doctor/SKILL.md +27 -18
  49. package/skills/autorag-lite-setup/SKILL.md +115 -59
  50. package/skills/autorag-setup/SKILL.md +99 -16
  51. package/dist/agent/bash-tool.d.ts +0 -32
  52. package/dist/cli/tui-commands.d.ts +0 -16
  53. package/dist/cli/tui-session-store.d.ts +0 -16
  54. 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
@@ -74,6 +74,15 @@ AutoRAG Agent orchestrates five integrated subsystems:
74
74
  4. **Direct Evidence Reading (`bash`):** The agent directly opens and inspects promising files with `cat`, `grep`, or `find` to verify facts against ground truth.
75
75
  5. **Curation & Active Feedback:** Structured findings are returned via `emit_autorag_results`. When callers provide feedback on which items were useful, AutoRAG records this to optimize future queries.
76
76
 
77
+ ### Pi host boundary
78
+
79
+ AutoRAG uses `@earendil-works/pi-coding-agent` as the runtime host for model sessions. Pi owns provider credentials and OAuth storage, model-runtime dispatch, session JSONL persistence/resume, extension loading, lifecycle events, and the built-in `read`/`bash`/`edit`/`write`/`grep`/`find`/`ls` tools. AutoRAG registers only its domain tools and keeps orchestration outside the host: datasource authorization, MinSync/Jikji preparation, memory hints, fast-to-verification two-phase search, structured result emission, and remote-session filtering.
80
+
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
+
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
+
85
+
77
86
  ---
78
87
 
79
88
  ## 🤖 For AI Agents & LLMs: Setup & Skills
@@ -82,19 +91,20 @@ If you are an AI coding agent or LLM (Claude Code, Cursor, Windsurf, Codex, Senp
82
91
 
83
92
  | Skill | Directory | When to Use |
84
93
  |---|---|---|
85
- | **`autorag`** | [`skills/autorag/`](skills/autorag/SKILL.md) | Querying, searching, comparing, and summarizing documents with an already configured AutoRAG librarian. |
86
- | **`autorag-setup`** | [`skills/autorag-setup/`](skills/autorag-setup/SKILL.md) | Installing AutoRAG, configuring models, adding document roots/datasources, running health checks, and repairing indexes. |
87
- | **`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. |
88
- | **`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. |
89
97
 
90
98
  ### Install the skills into your coding agent
91
99
 
92
- 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.**
93
103
 
94
104
  ```bash
95
105
  # From a clone of this repository
96
106
  mkdir -p .claude/skills
97
- cp -R skills/autorag-lite-setup skills/autorag-lite-search .claude/skills/
107
+ cp -R skills/autorag-lite-setup .claude/skills/
98
108
  ```
99
109
 
100
110
  ```bash
@@ -102,10 +112,19 @@ cp -R skills/autorag-lite-setup skills/autorag-lite-search .claude/skills/
102
112
  AUTORAG_SKILLS="$(npm root -g)/@autorag/librarian/skills"
103
113
  # Bun global installs live at ~/.bun/install/global/node_modules/@autorag/librarian/skills
104
114
  mkdir -p .claude/skills
105
- cp -R "$AUTORAG_SKILLS/autorag-lite-setup" "$AUTORAG_SKILLS/autorag-lite-search" .claude/skills/
115
+ cp -R "$AUTORAG_SKILLS/autorag-lite-setup" .claude/skills/
106
116
  ```
107
117
 
108
- 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.
109
128
 
110
129
  ### Quick Agent Workflow
111
130
 
@@ -129,6 +148,29 @@ Copy `skills/autorag` and `skills/autorag-setup` the same way when the agent sho
129
148
 
130
149
  ---
131
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
+
132
174
  ## ⚡ AutoRAG Lite: Model-Free Retrieval Engine
133
175
 
134
176
  Need blazing fast local search without configuring an LLM or paying for API tokens? Use **AutoRAG Lite**.
@@ -136,8 +178,8 @@ Need blazing fast local search without configuring an LLM or paying for API toke
136
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**:
137
179
 
138
180
  - **Zero LLM Token Usage:** Run purely local BM25 and vector search offline.
139
- - **Agent Integration Ready:** Use `autorag lite retrieve` inside your own agentic workflows to supply raw context chunks to an external model.
140
- - **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.
141
183
 
142
184
  ```bash
143
185
  # Initialize a model-free workspace
@@ -145,14 +187,12 @@ autorag lite init --search-paths ./documents
145
187
 
146
188
  # Index local files and datasources
147
189
  autorag lite refresh
148
-
149
- # Retrieve ranked document chunks (returns JSON candidates with scores)
150
- autorag lite retrieve "compliance policy exception process" --top-k 5 --json
151
-
152
- # Check index status and freshness
153
- autorag lite status
154
190
  ```
155
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
+
156
196
  ---
157
197
 
158
198
  ## 🔌 Supported Datasources
@@ -172,6 +212,7 @@ AutoRAG Agent connects to external tools and communication platforms using dedic
172
212
  | **Local Mail Export**| `mail-export` | Built-in `.mbox` / `.eml` parser | Local filesystem mailboxes | Lexical |
173
213
  | **Obsidian Vaults** | `obsidian` | [`qmd`](https://github.com/tobi/qmd) CLI | Direct markdown vault indexing | BM25, Semantic |
174
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 |
175
216
  | **Cloud Drives** | `cloud-drive` | [`rclone`](https://rclone.org) CLI | Google Drive (Tier-1), OneDrive, Dropbox, etc. | Incremental Mirror + BM25 |
176
217
  | **Photos & Shots** | `clawgallery` | `clawgallery` CLI | Local screenshot and photo store | Hybrid OCR/Visual Search |
177
218
  | **RSS / News** | `rss` | Native HTTP Poller | RSS 2.0 & Atom feeds (24h deduplication) | Lexical |
@@ -249,7 +290,7 @@ PDF pages.
249
290
  # Perform a curated search (uses your configured reasoning model)
250
291
  autorag search "What are our primary Q3 deliverables?"
251
292
 
252
- # Launch the interactive Terminal UI (beta)
293
+ # Launch the interactive Terminal UI (Pi host: /login, /model, /resume, …)
253
294
  autorag tui
254
295
  ```
255
296
 
@@ -287,11 +328,13 @@ agent.recordFeedbackByNumbers(response.sessionId, [1], [2]);
287
328
  | `autorag search "<query>"` | Run the librarian agent to curate structured answers |
288
329
  | `autorag status` | Inspect corpus freshness, indexing status, and vector readiness |
289
330
  | `autorag health` | Check model provider authentication, token validity, and API reachability |
290
- | `autorag tui` | Open the interactive librarian terminal UI |
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) |
333
+ | `autorag tui` | Open Pi's interactive librarian TUI (`/login`, `/model`, `/resume`, …) |
291
334
  | `autorag duplicates [DIR]` | Read-only scan for exact and near-duplicate document families with `dupey` |
292
- | `autorag lite ...` | Model-free indexing, retrieval, report generation, and status |
293
- | `autorag feedback <session>` | Record useful / not-useful feedback by item number |
294
- | `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 |
295
338
  | `autorag serve` | Start the P2P query server over SimpleX (opt-in) |
296
339
  | `autorag p2p ...` | Manage peer trust, query approvals, and sharing policies |
297
340
 
@@ -304,6 +347,7 @@ Deep dive into AutoRAG Agent's architecture, security, and integration guides:
304
347
  - **[MinSync Setup & Embedding QA](docs/minsync-setup.md):** Automatic binary installation, CDC chunking, and EmbeddingGemma verification.
305
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).
306
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.
307
351
  - **[Manual QA & Datasource Test Harnesses](docs/manual-qa-datasources.md):** Real-world testing guides for Discord, KakaoTalk, Slack, Notion, and email.
308
352
  - **[P2P SimpleX Sharing & Path Standard](docs/p2p-path-standard.md):** Decentralized peer query sharing with SimpleX, PII redaction, and approval queues.
309
353
  - **[Supply Chain Security & License Audits](docs/supply-chain.md):** Software bill of materials (SBOM) and dependency gate policies.
@@ -349,13 +393,19 @@ autorag health --json # model resolution + one live completion probe
349
393
  autorag gateway status --format json # on-demand embedding runtime
350
394
  ```
351
395
 
352
- 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:
353
398
 
354
- ```bash
355
- autorag lite retrieve 'a word that certainly appears' --top-k 3 --json
356
- 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}
357
404
  ```
358
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
+
359
409
  Common failures and their fix:
360
410
 
361
411
  | Symptom | Diagnostic code | Fix |
@@ -367,6 +417,7 @@ Common failures and their fix:
367
417
  | A datasource errors during refresh | `datasource-index-failed` | run that CLI's own `doctor` |
368
418
  | MinSync or Jikji missing | `minsync-unavailable`, `jikji-unavailable` | check the Rust toolchain, re-run refresh |
369
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) |
370
421
 
371
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`.
372
423
 
@@ -1,4 +1,4 @@
1
- import { Agent, type AgentTool, type Skill } from "@earendil-works/pi-agent-core";
1
+ import type { Agent, AgentTool, Skill } from "@earendil-works/pi-agent-core";
2
2
  import type { Api, Model } from "@earendil-works/pi-ai";
3
3
  import { type DatasourceAccessContextOptions } from "../datasource/access-context.js";
4
4
  import type { DatasourceIndexResult, DatasourceSkill } from "../datasource/types.js";
@@ -17,10 +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";
26
+ import { type AutoRAGPiInteractiveRuntime, type AutoRAGPiSession } from "./pi-session.js";
27
+ import { type QueryRoute } from "./query-routing.js";
24
28
  import { type RefreshProgressCounts, type RefreshProgressPhase } from "./refresh-progress.js";
25
29
  import { type SearchDocumentDiagnostic, type SearchDocumentsResponse, type SearchDocumentsStreamEvent } from "./search-documents.js";
26
30
  import { type WatcherFactory, type WatchRefreshHandle } from "./watch-refresh.js";
@@ -35,7 +39,7 @@ import { type WebSearchToolOptions } from "./web-search-tool.js";
35
39
  export interface AutoRAGRetrievalLimits {
36
40
  /** `search_all_documents` merge ceiling when the model omits `topK`. Default 500. */
37
41
  readonly mergedEvidenceCeiling?: number;
38
- /** `search_datasource_*` merge default when the model omits `topK`. Default 50. */
42
+ /** `search_datasource_*` merge default when the model omits `topK`. Default 20. */
39
43
  readonly singleDatasourceTopK?: number;
40
44
  /** MinSync semantic retrieval default `topK`. Default 50. */
41
45
  readonly minSyncTopK?: number;
@@ -159,12 +163,10 @@ export declare class RemoteSessionRejectedError extends Error {
159
163
  /** Thinking level applied per search phase. "off" requests no reasoning. */
160
164
  export type AutoRAGThinkingLevel = "off" | "minimal" | "low" | "medium" | "high" | "xhigh" | "max";
161
165
  /**
162
- * Two-phase progressive answers: the fast phase delivers an immediate first
163
- * answer with {@link AutoRAGThinkingOptions.fast} thinking (default "off"),
164
- * then the verification phase re-checks and finalizes with
165
- * {@link AutoRAGThinkingOptions.final} thinking (default "high"). Pass
166
- * `false` on {@link AutoRAGAgentOptions.thinking} to keep the legacy
167
- * 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").
168
170
  */
169
171
  export interface AutoRAGThinkingOptions {
170
172
  /** Thinking level for the immediate first answer. Default "off". */
@@ -232,6 +234,29 @@ export interface AutoRAGAgentOptions {
232
234
  autoRefresh?: AutoRefreshOptions;
233
235
  parserOptions?: DefaultParserRegistryOptions;
234
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
+ };
235
260
  excludeExactDuplicates?: boolean;
236
261
  excludePaths?: readonly string[];
237
262
  /**
@@ -255,8 +280,20 @@ export interface AutoRAGAgentOptions {
255
280
  peerQuery?: PeerQueryOptions | false;
256
281
  /** Restrict the agent to retrieval and result-emission tools for remote runs. */
257
282
  remoteSession?: boolean;
258
- /** Two-phase progressive answers with per-phase thinking control. Default enabled. */
259
- thinking?: AutoRAGThinkingOptions | false;
283
+ /** Per-phase thinking levels for the two-phase (fast → verification) search. */
284
+ thinking?: AutoRAGThinkingOptions;
285
+ /** pi agent directory for auth/models/extensions. Defaults to ~/.pi/agent. */
286
+ piAgentDir?: string;
287
+ /** Optional persistent pi session directory. */
288
+ piSessionDir?: string;
289
+ /** Persist one pi session transcript per AutoRAG search. Defaults true. */
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>;
260
297
  }
261
298
  /** Post-merge reranking options. Mirrors the CLI `RerankConfig` (secrets via env). */
262
299
  export interface RerankAgentOptions {
@@ -277,6 +314,7 @@ export interface RerankAgentOptions {
277
314
  }
278
315
  export interface AutoRAGSearchSession {
279
316
  readonly agent: Agent;
317
+ readonly piSession?: AutoRAGPiSession["session"];
280
318
  prompt(text: string): Promise<void>;
281
319
  abort(): Promise<void> | void;
282
320
  dispose(): void;
@@ -308,19 +346,15 @@ export declare class AutoRAGAgent {
308
346
  private readonly sessions;
309
347
  private activeRun;
310
348
  private resultCapture;
311
- /** This agent's model credential for model-native web search (per instance, never shared). */
349
+ private interactiveFastAnswerCallback;
312
350
  private modelNativeSearchAuth;
313
351
  private retrievalTrace;
314
352
  private preliminaryCallback;
315
- /** Per-phase thinking levels; undefined marks the legacy single-phase flow. */
353
+ /** Per-phase thinking levels of the two-phase search. */
316
354
  private readonly fastThinkingLevel;
317
355
  private readonly finalThinkingLevel;
318
356
  private autoRefreshTimer;
319
357
  private refreshing;
320
- private jikjiPrepareInFlight;
321
- private jikjiReady;
322
- private minSyncPrepareInFlight;
323
- private minSyncReady;
324
358
  private refreshState;
325
359
  private readonly searchPaths;
326
360
  private readonly configuredSearchPaths;
@@ -344,12 +378,26 @@ export declare class AutoRAGAgent {
344
378
  private readonly datasourceAgentSkills;
345
379
  private readonly parserOptions;
346
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;
347
390
  private readonly excludeExactDuplicates;
348
391
  private readonly excludePaths;
349
392
  private readonly baseSystemPromptConfig;
350
393
  private readonly droppedCallerToolNames;
351
394
  private readonly searchTimeoutMs;
352
395
  private readonly maxSearchToolCalls;
396
+ private readonly piAgentDir;
397
+ private readonly piSessionDir;
398
+ private readonly persistPiSessions;
399
+ private readonly updateNotice;
400
+ private boundPiRuntime;
353
401
  /** True when this agent was constructed for an untrusted remote peer. */
354
402
  readonly remoteSession: boolean;
355
403
  private activeRetrievalOptions;
@@ -364,6 +412,8 @@ export declare class AutoRAGAgent {
364
412
  private recordSearchToolEvent;
365
413
  private currentSystemPromptConfig;
366
414
  subscribe(listener: Parameters<Agent["subscribe"]>[0]): () => void;
415
+ createPiInteractiveRuntime(): Promise<AutoRAGPiInteractiveRuntime>;
416
+ private runInteractivePiQuery;
367
417
  abort(): void;
368
418
  /**
369
419
  * Periodically re-runs the incremental {@link refresh} so parsed mirrors and
@@ -402,6 +452,23 @@ export declare class AutoRAGAgent {
402
452
  * datasource skill; duplicate ids collapse to the first registration.
403
453
  */
404
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;
405
472
  /**
406
473
  * Resolve an authorized datasource agent skill by model-visible name for the
407
474
  * `load_datasource_skill` tool. Returns `undefined` for unknown or
@@ -411,20 +478,53 @@ export declare class AutoRAGAgent {
411
478
  private indexDatasources;
412
479
  /** Path-opaque component diagnostics for the search response. */
413
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
+ */
414
503
  private prefetchInitialRetrievalContext;
504
+ /** Baseline web evidence for the fast answer: one web search per query, all in parallel. */
505
+ private prefetchWebContext;
415
506
  /**
416
- * Prepare MinSync lazily without holding up the current search. Parsed
417
- * 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.
418
514
  */
419
- /** Prepare MinSync in the background; the returned promise is for tests. */
420
- scheduleMinSyncPrepareForTest(): Promise<MinSyncSyncResult | undefined> | undefined;
421
- private scheduleMinSyncPrepare;
515
+ private rerankPrefetchPool;
422
516
  /**
423
517
  * Fast-phase prompt for two-phase searches. The baseline retrieval context
424
518
  * is already gathered, so the model answers immediately with thinking off
425
519
  * via emit_fast_answer, without any further tool calls.
426
520
  */
427
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;
428
528
  /** Discovery-tool hint naming only the registered discovery tools; empty when none. */
429
529
  private discoveryHint;
430
530
  /**
@@ -433,7 +533,7 @@ export declare class AutoRAGAgent {
433
533
  * against it; the model then verifies with thinking on and finalizes with
434
534
  * emit_autorag_results exactly once, returning only the delta.
435
535
  */
436
- 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;
437
537
  buildSearchPrompt(query: string, options: RetrievalOptions, initialRetrievalContext?: string): string;
438
538
  refresh(force?: boolean, opts?: AutoRAGRefreshOptions): Promise<AutoRAGRefreshResult>;
439
539
  /**
@@ -490,13 +590,13 @@ export declare class AutoRAGAgent {
490
590
  */
491
591
  stopFsearch(): Promise<void>;
492
592
  prepareJikji(): Promise<readonly AutoRAGJikjiPrepareResult[] | undefined>;
493
- private executeJikjiPrepare;
494
593
  /**
495
- * Start Jikji preparation without delaying the current search turn. A
496
- * subsequent turn can use the prepared index, while the child process keeps
497
- * 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.
498
598
  */
499
- private scheduleJikjiPrepare;
599
+ private executeJikjiPrepare;
500
600
  private sanitizeJikjiPrepareResult;
501
601
  /**
502
602
  * Provider method for the jikji_find tool. Runs JikjiClient.find over all
@@ -513,6 +613,14 @@ export declare class AutoRAGAgent {
513
613
  * Merge per-root answer packs into one. Concatenates answer_paths/candidates
514
614
  * preserving per-root order; dedupes by normalized path. Does NOT cross-root
515
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.
516
624
  */
517
625
  private mergeAnswerPacks;
518
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;