@autorag/librarian 2.10.1 → 2.10.3

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 (73) hide show
  1. package/NOTICE +0 -3
  2. package/README.md +76 -33
  3. package/dist/agent/agent.d.ts +96 -18
  4. package/dist/agent/evidence-ledger.d.ts +54 -5
  5. package/dist/agent/evidence-persistence.d.ts +24 -0
  6. package/dist/agent/jev-extension.d.ts +5 -3
  7. package/dist/agent/search-documents.d.ts +1 -1
  8. package/dist/agent/system-prompt.d.ts +0 -2
  9. package/dist/agent/tool-burst-guard.d.ts +26 -0
  10. package/dist/cli/config.d.ts +37 -23
  11. package/dist/cli/index.js +2122 -1153
  12. package/dist/cloud/config.d.ts +16 -10
  13. package/dist/cloud/credential.d.ts +17 -0
  14. package/dist/cloud/errors.d.ts +6 -6
  15. package/dist/cloud/index.d.ts +5 -4
  16. package/dist/cloud/jev-backend.d.ts +15 -13
  17. package/dist/cloud/models.d.ts +4 -4
  18. package/dist/cloud/oauth-login.d.ts +3 -3
  19. package/dist/cloud/provider.d.ts +16 -11
  20. package/dist/cloud/token.d.ts +2 -2
  21. package/dist/core.d.ts +2 -1
  22. package/dist/core.js +2265 -1313
  23. package/dist/datasource/aliased-skill.d.ts +2 -2
  24. package/dist/datasource/connector-skill.d.ts +2 -2
  25. package/dist/datasource/crawler-skill.d.ts +2 -2
  26. package/dist/datasource/described-skill.d.ts +2 -2
  27. package/dist/datasource/index.d.ts +1 -1
  28. package/dist/datasource/retry.d.ts +49 -0
  29. package/dist/datasource/skills/clawgallery/skill.d.ts +4 -4
  30. package/dist/datasource/skills/discrawl/skill.d.ts +5 -5
  31. package/dist/datasource/skills/github-gist/skill.d.ts +2 -2
  32. package/dist/datasource/skills/lazykatok/skill.d.ts +5 -5
  33. package/dist/datasource/skills/mailcrawl/skill.d.ts +2 -2
  34. package/dist/datasource/skills/obsidian/skill.d.ts +5 -5
  35. package/dist/datasource/types.d.ts +13 -1
  36. package/dist/embedding-runtime/cache.d.ts +9 -0
  37. package/dist/index.d.ts +1 -2
  38. package/dist/index.js +2338 -1387
  39. package/dist/jikji/client.d.ts +13 -2
  40. package/dist/jikji/index.d.ts +1 -1
  41. package/dist/jikji/path-map.d.ts +9 -0
  42. package/dist/jikji/prepare-budget.d.ts +18 -0
  43. package/dist/jikji/serial-queue.d.ts +17 -0
  44. package/dist/jikji/types.d.ts +17 -0
  45. package/dist/mcp/index.js +2326 -1374
  46. package/dist/minsync/client.d.ts +3 -1
  47. package/dist/minsync/index.d.ts +1 -1
  48. package/dist/minsync/installer.d.ts +1 -1
  49. package/dist/minsync/method.d.ts +1 -1
  50. package/dist/minsync/types.d.ts +8 -1
  51. package/dist/mirror/atomic-write.d.ts +6 -0
  52. package/dist/mirror/index-store.d.ts +8 -1
  53. package/dist/mirror/index.d.ts +2 -2
  54. package/dist/mirror/sync.d.ts +57 -1
  55. package/dist/p2p/simplex-server.d.ts +0 -1
  56. package/dist/parser/defaults.d.ts +8 -0
  57. package/dist/parser/errors.d.ts +10 -0
  58. package/dist/parser/isolated.d.ts +77 -0
  59. package/dist/parser/kordoc.d.ts +1 -0
  60. package/dist/parser/parse-worker.d.ts +1 -0
  61. package/dist/parser/parse-worker.js +780 -0
  62. package/dist/parser/types.d.ts +5 -0
  63. package/dist/process/abort-reason.d.ts +2 -0
  64. package/dist/retrieval/index.d.ts +1 -1
  65. package/dist/retrieval/rerank.d.ts +16 -10
  66. package/package.json +5 -5
  67. package/skills/autorag/SKILL.md +2 -1
  68. package/skills/autorag-doctor/SKILL.md +7 -0
  69. package/skills/autorag-lite-setup/SKILL.md +2 -2
  70. package/skills/autorag-setup/SKILL.md +42 -17
  71. package/dist/manifest/index.d.ts +0 -2
  72. package/dist/manifest/loader.d.ts +0 -3
  73. package/dist/manifest/types.d.ts +0 -8
package/NOTICE CHANGED
@@ -63,9 +63,6 @@ License: Apache-2.0
63
63
  typebox@1.3.37
64
64
  License: MIT
65
65
 
66
- yaml@2.9.1
67
- License: ISC
68
-
69
66
  Embedding runtime and model notices:
70
67
  licenses/llama.cpp-MIT.txt
71
68
  licenses/qwen3-embedding-notice.txt
package/README.md CHANGED
@@ -136,7 +136,7 @@ does, and searches them right alongside your files:
136
136
  File contents are never sent to a remote embedder.
137
137
  - **Keys stay encrypted.** Sign-in tokens and API keys live in the system's
138
138
  encrypted store, never in a config file.
139
- - **Bring your own model.** Use the [hosted AutoRAG plan](#hosted-autorag-plan),
139
+ - **Bring your own model.** Use the [hosted Dazzi Models plan](#hosted-dazzi-models-plan),
140
140
  or connect your own provider key and pay the provider directly.
141
141
 
142
142
  > [!TIP]
@@ -186,7 +186,7 @@ Three principles drive every design decision in AutoRAG Agent:
186
186
 
187
187
  1. **Never migrate your data to search it.** Traditional RAG systems force you to upload, ETL, and duplicate your files into a centralized vector database. AutoRAG Agent federates your data **in place**, querying CLI-native stores (`lazykatok`, `discrawl`, `slacrawl`, `mailcrawl`, `rclone`, `qmd`) where your data already lives. Results retain opaque, source-native identities (`/kakao/...`, `/slack/...`) that preserve local access control and privacy. *(See our [Competitive Landscape Study](docs/competitive-landscape-2026-09.md) on why in-place federation is the durable differentiator).*
188
188
 
189
- 2. **Just works — no RAG degree required.** No pipeline tuning, no vector-DB maintenance, and no remote embedding keys required. AutoRAG Agent automatically manages [MinSync](docs/minsync-setup.md) for incremental Change Data Capture (CDC) chunking and provides a local [embedding gateway](docs/embedding-runtime.md) out of the box with zero external telemetry. A [remote rerank model](docs/rerank.md) (OpenRouter, `voyageai/rerank-3-lite` by default) is an opt-in extra.
189
+ 2. **Just works — no RAG degree required.** No pipeline tuning, no vector-DB maintenance, and no remote embedding keys required. AutoRAG Agent automatically manages [MinSync](docs/minsync-setup.md) for incremental Change Data Capture (CDC) chunking and provides a local [embedding gateway](docs/embedding-runtime.md) out of the box with zero external telemetry. A [remote rerank model](docs/rerank.md) (the hosted Dazzi Models reranker when signed in, else OpenRouter `voyageai/rerank-3-lite`) is an opt-in extra.
190
190
 
191
191
  3. **Fast by design.** Rather than coordinating slow multi-agent hierarchies, a single configured model owns the entire retrieval, direct-read, and curation loop. Local CDC chunks (BM25, vector, and hybrid modes) deliver rapid, low-latency turnaround across multi-turn research queries.
192
192
 
@@ -304,6 +304,26 @@ Tesseract. Set `parserOptions.ocr.cachePath` to store the Tesseract models
304
304
  elsewhere, or `KORDOC_OFFLINE=1` to block the built-in model download. An
305
305
  explicit `parserOptions.kordoc.ocr` overrides the language-based choice.
306
306
 
307
+ ### Bounding and cancelling a parse
308
+
309
+ `kordoc` (PDF, HWP/HWPX, DOCX, XLSX/XLS, images), `.pptx` and `.eml` parse in a worker
310
+ thread during a refresh, so one corrupt or hostile file cannot hang or crash the run. A
311
+ `Promise.race` deadline cannot stop a synchronous parse; terminating the worker can.
312
+
313
+ | `parserOptions` key | Default | Effect |
314
+ |---|---|---|
315
+ | `fileTimeoutMs` | `120000` | Per-file deadline. A parse still running is killed with its worker. |
316
+ | `maxHeapMb` | Node's default | V8 old-generation limit for the worker. An out-of-memory parse is caught, not a host crash. |
317
+
318
+ A timeout, a heap overrun and a worker crash each become one `parser-failed` skip for that
319
+ file; the diagnostic message says which. The rest of the corpus is still indexed. Plain-text
320
+ files and parsers configured with a function (`parserOptions.kordoc.parse`, a custom OCR
321
+ provider) parse in-process.
322
+
323
+ ```json
324
+ { "parserOptions": { "fileTimeoutMs": 60000, "maxHeapMb": 2048 } }
325
+ ```
326
+
307
327
  Photos and videos are also reachable through two other paths that are not part
308
328
  of this switch: the `clawgallery` datasource (captions and visual search over its
309
329
  own folders) and Jikji's media index (`jikji.enableMediaIndex`, file facts such as
@@ -375,6 +395,32 @@ await run;
375
395
 
376
396
  `steer()` reaches the search's next model request (also between phases), cuts in-flight retrieval and the baseline prefetch short, and always runs verification, whose prompt restates the correction. It returns `false` when no search is running, the search was stopped, or it is past its last model request; ask the text as a new question then.
377
397
 
398
+ A refresh can be cancelled and observed from code:
399
+
400
+ ```typescript
401
+ const controller = new AbortController();
402
+ try {
403
+ await agent.refresh(false, {
404
+ signal: controller.signal, // controller.abort() stops it
405
+ onProgress: ({ phase, processed, total, currentVirtualPath }) => {
406
+ console.log(`${phase} ${processed}/${total}`, currentVirtualPath ?? "");
407
+ },
408
+ });
409
+ } catch (error) {
410
+ if (controller.signal.aborted) console.log("refresh cancelled");
411
+ else throw error;
412
+ }
413
+ ```
414
+
415
+ `signal` is checked between files and between phases, kills an in-flight parse worker, and
416
+ terminates the MinSync, Jikji and datasource child processes (and their descendants). The
417
+ refresh then rejects with the signal's reason and is recorded as `failed`; files already
418
+ mirrored are kept and not re-parsed on the next run. `onProgress` reports `parsed`
419
+ (`processed`/`total` are files, `currentVirtualPath` is the file about to be processed) and
420
+ `datasources` (`processed`/`total` are datasource skills). During the parse phase
421
+ `.autorag/refresh-progress.json` also carries the running `sourceFiles.total` and
422
+ `parsedCounts`. Without these options a refresh behaves as before.
423
+
378
424
  ---
379
425
 
380
426
  ## CLI Command Reference
@@ -504,7 +550,7 @@ Do not copy or retain the removed `autorag-lite-search` skill.
504
550
  ```
505
551
  4. **Safety Guidelines for Agents:**
506
552
  - **Never delete, move, or modify original user documents.**
507
- - AutoRAG writes index artifacts strictly into `<workspace>/.autorag/` and `.jikji/` caches.
553
+ - AutoRAG writes index artifacts into `<workspace>/.autorag/` and Jikji's central store (`<OS data dir>/jikji/`, override with `JIKJI_DATA_DIR`). Jikji also drops a `.jikji_agent_map.md` guide into each indexed root.
508
554
  - Never print or leak API keys, tokens, or credential values into stdout or logs.
509
555
 
510
556
  ---
@@ -536,73 +582,69 @@ For configuration syntax and connector details, see [docs/datasource-skills.md](
536
582
 
537
583
  ---
538
584
 
539
- ## Hosted AutoRAG Plan
585
+ ## Hosted Dazzi Models Plan
540
586
 
541
- AutoRAG can run on the hosted **AutoRAG** plan as a first-class model provider named
542
- `autorag`. The provider speaks the server's OpenAI Responses API surface (`<root>/v1`),
587
+ AutoRAG can run on the hosted **Dazzi Models** plan as a first-class model provider named
588
+ `dazzi`. The provider speaks the server's OpenAI Responses API surface (`<root>/v1`),
543
589
  so streaming, tool calls, and usage are handled by Pi's built-in `openai-responses`
544
590
  implementation, and the model catalog is discovered live from the server — no model id
545
591
  is baked into AutoRAG.
546
592
 
547
- Sign in from the interactive TUI:
593
+ Sign in from the interactive TUI. Login is the only way to authenticate; there is no API-key
594
+ environment variable:
548
595
 
549
596
  ```text
550
597
  autorag tui
551
- /login # choose "AutoRAG"; the browser completes a PKCE login
598
+ /login # choose "Dazzi Models"; the browser completes a PKCE login
552
599
  ```
553
600
 
554
- Headless (no browser) with a long-lived API key:
555
-
556
- ```bash
557
- export AUTORAG_API_KEY=dz_...
558
- ```
601
+ The provider, Jev, and rerank all use the credential `/login` stores. A login flow for
602
+ machines with no browser is not available yet and is tracked in [#1913](https://github.com/Marker-Inc-Korea/AutoRAG/issues/1913).
559
603
 
560
604
  On a fresh agent home, pin the model with an explicit endpoint so it resolves
561
- offline without a catalog snapshot — this is the headless configuration:
605
+ offline without a catalog snapshot:
562
606
 
563
607
  ```json
564
608
  {
565
609
  "model": {
566
- "provider": "autorag",
610
+ "provider": "dazzi",
567
611
  "id": "anthropic/claude-haiku-5.5",
568
612
  "baseUrl": "https://api.dazziapp.com/v1",
569
- "api": "openai-responses",
570
- "apiKeyEnv": "AUTORAG_API_KEY"
613
+ "api": "openai-responses"
571
614
  }
572
615
  }
573
616
  ```
574
617
 
575
- The `provider`/`id`-only shorthand (`{ "provider": "autorag", "id": "anthropic/claude-haiku-5.5" }`)
618
+ The `provider`/`id`-only shorthand (`{ "provider": "dazzi", "id": "anthropic/claude-haiku-5.5" }`)
576
619
  only resolves once a TUI `/login` or a model refresh has persisted the catalog
577
620
  snapshot; with no snapshot there is nothing to restore offline, and resolution
578
- fails with `Unknown configured model: autorag/<id>`.
621
+ fails with `Unknown configured model: dazzi/<id>`.
579
622
 
580
623
  | Variable | Default | Meaning |
581
624
  |---|---|---|
582
625
  | `AUTORAG_BASE_URL` | `https://api.dazziapp.com` | Server **root** (not the `/v1` path); the API base is `<root>/v1`. |
583
- | `AUTORAG_API_KEY` | – | Headless API key. A stored `/login` credential takes precedence. |
584
626
 
585
627
  The catalog is persisted after a `/login` (or any model refresh), so the
586
- `provider`/`id` shorthand `model: { provider: "autorag", id }`
628
+ `provider`/`id` shorthand `model: { provider: "dazzi", id }`
587
629
  keeps resolving offline. When you are not signed in the provider still registers — it appears under
588
630
  `/login`, contributes no models, and makes no network call. See
589
- [Hosted AutoRAG provider](docs/cloud-provider.md) for the full flow.
631
+ [Hosted Dazzi Models provider](docs/cloud-provider.md) for the full flow.
590
632
 
591
- The same plan can also serve the **Jev** judgment model and **rerank** stage, so
633
+ The same sign-in can also serve the **Jev** judgment model and **rerank** stage, so
592
634
  the whole librarian loop runs on the hosted account:
593
635
 
594
636
  ```json
595
637
  {
596
- "jev": { "backend": "autorag", "model": "jev-1.13" },
597
- "rerank": { "provider": "autorag", "model": "qwen/qwen3-reranker-8b" }
638
+ "jev": { "backend": "dazzi", "model": "jev-1.13" },
639
+ "rerank": { "provider": "dazzi", "model": "qwen/qwen3-reranker-8b" }
598
640
  }
599
641
  ```
600
642
 
601
- `jev.backend: "autorag"` posts Jev's native dialect to `<root>/v1/jev`
602
- (default model `jev-1.13`); `rerank.provider: "autorag"` reranks against
603
- `<root>/v1/rerank` (default model `qwen/qwen3-reranker-8b`). Both read the
604
- account key from `AUTORAG_API_KEY`, and an explicit `rerank.baseUrl`,
605
- `rerank.apiKeyEnv`, or `rerank.model` still overrides the defaults.
643
+ `jev.backend: "dazzi"` posts Jev's native dialect to `<root>/v1/jev`
644
+ (default model `jev-1.13`); `rerank.provider: "dazzi"` reranks against
645
+ `<root>/v1/rerank` (default model `qwen/qwen3-reranker-8b`). Both use the stored
646
+ `/login` credential, and an explicit `rerank.baseUrl` or `rerank.model` still overrides
647
+ the defaults.
606
648
 
607
649
  ---
608
650
 
@@ -612,9 +654,9 @@ Deep dive into AutoRAG Agent's architecture, security, and integration guides:
612
654
 
613
655
  - **[MinSync Setup & Embedding QA](docs/minsync-setup.md):** Automatic binary installation, CDC chunking, and local embedding verification.
614
656
  - **[Local Embedding Runtime & Gateway](docs/embedding-runtime.md):** AutoRAG-owned local gateway, model prefetching, and zero-egress semantic search. Model card: [`qwen3-embedding-0.6b`](docs/model-cards/qwen3-embedding-0.6b.md).
615
- - **[Hosted AutoRAG Provider](docs/cloud-provider.md):** The hosted `autorag` model provider — PKCE `/login`, `AUTORAG_API_KEY`, `AUTORAG_BASE_URL`, live model discovery, and offline catalog snapshots.
657
+ - **[Hosted Dazzi Models Provider](docs/cloud-provider.md):** The hosted `dazzi` model provider — PKCE `/login`, `AUTORAG_BASE_URL`, live model discovery, and offline catalog snapshots.
616
658
  - **[Datasource Skills Reference](docs/datasource-skills.md):** Full configuration contracts, connection aliases, and connector options.
617
- - **[Jev Decisions](docs/jev-decisions.md):** Jev query pipeline, **on by default** via OpenRouter: it routes each question to a direct answer (intrinsic knowledge) or local search (everything needing more information; web search is left to the agent after the fast answer), splits multi-part questions into up to five parallel searches (`openrouter/qwen/qwen3.7-flash`), picks which registered datasources to search before the fast answer, 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.
659
+ - **[Jev Decisions](docs/jev-decisions.md):** Jev query pipeline, **on by default** via Dazzi Models when signed in (OpenRouter otherwise): it routes each question to a direct answer (intrinsic knowledge) or local search (everything needing more information; web search is left to the agent after the fast answer), splits multi-part questions into up to five parallel searches (`dazzi/openai/gpt-6-luna` when signed in, else `openrouter/qwen/qwen3.7-flash`), picks which registered datasources to search before the fast answer, 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.
618
660
  - **[Manual QA & Datasource Test Harnesses](docs/manual-qa-datasources.md):** Real-world testing guides for Discord, KakaoTalk, Slack, Notion, and email.
619
661
  - **[P2P SimpleX Sharing & Path Standard](docs/p2p-path-standard.md):** Decentralized peer query sharing with SimpleX, PII redaction, and approval queues.
620
662
  - **[Supply Chain Security & License Audits](docs/supply-chain.md):** Software bill of materials (SBOM) and dependency gate policies.
@@ -684,8 +726,9 @@ Common failures and their fix:
684
726
  | A datasource errors during refresh | `datasource-index-failed` | run that CLI's own `doctor` |
685
727
  | MinSync binary missing (search and refresh fail with `MinSync is required ...`) | — | `cargo install minsync`, or leave `minSync.autoInstall` on and re-run refresh |
686
728
  | Jikji missing | `jikji-unavailable` | check the Rust toolchain, re-run refresh |
729
+ | Jikji prepare of a large root times out (`the Jikji prepare run timed out`) | `jikji-prepare-failed` | the refresh still finishes and the other roots are indexed. There is no fixed total wall: the per-root hang guard is `jikji.timeoutMs` (60 s base) plus `jikji.prepareTimeoutMsPerFile` ms per file under the root (default: `jikji.parseTimeout`, 5 s), uncapped, so a huge root is not cut by its size and only a run stuck beyond every file hitting its parse limit is killed. Set `prepareTimeoutMsPerFile: 0` for a flat `timeoutMs` wall. `jikji.parseTimeout` (seconds) is the per-file limit, forwarded to `jikji prepare --parse-timeout`; jikji skips a file that exceeds it. A timeout kills jikji's whole process group |
687
730
  | 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` |
688
- | 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) |
731
+ | Every search does a full local search and verification, even for small talk | `query-route-fallback` | sign in to Dazzi Models with `/login`, or set `OPENROUTER_API_KEY` (Jev routing and decomposition are on by default) |
689
732
 
690
733
  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`.
691
734
 
@@ -1,14 +1,15 @@
1
1
  import type { Agent, AgentTool } from "@earendil-works/pi-agent-core";
2
2
  import type { Api, ImageContent, Model } from "@earendil-works/pi-ai";
3
+ import { type DatasourceRetryOptions } from "../datasource/retry.js";
3
4
  import type { DatasourceIndexResult, DatasourceSkill } from "../datasource/types.js";
4
5
  import { type DupeyCliOptions } from "../dupey/index.js";
5
6
  import { type Embedder } from "../embedding-runtime/gateway-embedder.js";
6
7
  import { type EverythingClientOptions, type EverythingSearchRequest, type EverythingSearchResult } from "../everything/index.js";
7
8
  import { type FSearchClientOptions, type FSearchFailureReason, type FSearchSearchRequest, type FSearchSearchResult } from "../fsearch/index.js";
8
- import { type JikjiFailureReason, type JikjiOptions } from "../jikji/index.js";
9
+ import { type JikjiFailureReason, type JikjiOptions, type JikjiPrepareOptions } from "../jikji/index.js";
9
10
  import { type LanguageTag } from "../language.js";
10
11
  import { type MinSyncSyncResult, type MinSyncVectorMethodOptions } from "../minsync/index.js";
11
- import { type ParsedMirrorSyncResult } from "../mirror/sync.js";
12
+ import { type ParsedMirrorSyncOptions, type ParsedMirrorSyncResult } from "../mirror/sync.js";
12
13
  import type { PolicyResolver } from "../p2p/policy-filter.js";
13
14
  import type { SimplexQueryState } from "../p2p/simplex-query-store.js";
14
15
  import { type SimplexTransport } from "../p2p/simplex-transport.js";
@@ -26,9 +27,28 @@ import { type AutoRAGPiInteractiveRuntime, type AutoRAGPiSession } from "./pi-se
26
27
  import { type RefreshProgressCounts, type RefreshProgressPhase } from "./refresh-progress.js";
27
28
  import { type SearchDocumentDiagnostic, type SearchDocumentsResponse, type SearchDocumentsStreamEvent } from "./search-documents.js";
28
29
  import { type SelfConfigOptions } from "./self-config.js";
30
+ import { type ToolBurstGuardOptions } from "./tool-burst-guard.js";
29
31
  import { type WatcherFactory, type WatchRefreshHandle } from "./watch-refresh.js";
30
32
  import { type WebFetchToolOptions } from "./web-fetch-tool.js";
31
33
  import { type WebSearchToolOptions } from "./web-search-tool.js";
34
+ /**
35
+ * Safety limits for the parsed-mirror refresh. Every field is optional; an
36
+ * omitted field keeps the shipped default.
37
+ */
38
+ export interface AutoRAGRefreshLimits {
39
+ /**
40
+ * Largest share (0–1) of indexed documents one refresh may delete because
41
+ * their source disappeared; a bigger deletion above 100 documents is
42
+ * suppressed unless the refresh is forced. Default 0.3.
43
+ */
44
+ readonly maxDeleteRatio?: number;
45
+ /** Directory entries examined per search root before the walk stops. Default 2,000,000. */
46
+ readonly maxScannedEntries?: number;
47
+ /** Deepest directory level walked below a search root. Default 64. */
48
+ readonly maxDepth?: number;
49
+ /** Retries for a transient per-file I/O error (EMFILE/EBUSY/EIO/ETIMEDOUT) before the file is skipped. Default 3. */
50
+ readonly transientRetries?: number;
51
+ }
32
52
  /**
33
53
  * Hard caps on retrieval, baseline prefetch, and the candidate lists handed to
34
54
  * the model. Every field is optional: an omitted field keeps the shipped
@@ -64,9 +84,40 @@ export interface AutoRefreshOptions {
64
84
  }
65
85
  /** Methods that `refresh` can selectively run. Defaults to all when omitted. */
66
86
  export type RefreshMethod = "parsed" | "minsync" | "datasources" | "jikji" | "everything" | "fsearch";
87
+ /**
88
+ * Progress of a refresh phase that can count its work. `parsed` counts source files
89
+ * (`currentVirtualPath` is the opaque virtual path of the file about to be processed);
90
+ * `datasources` counts configured datasource skills. Other phases do not report counts.
91
+ */
92
+ export interface AutoRAGRefreshProgress {
93
+ readonly phase: "parsed" | "datasources";
94
+ /** Items finished so far. Advances by one per item and ends equal to `total`. */
95
+ readonly processed: number;
96
+ readonly total: number;
97
+ readonly currentVirtualPath?: string;
98
+ }
67
99
  export interface AutoRAGRefreshOptions {
68
100
  /** Restrict refresh to specific methods. Defaults to all when undefined. */
69
101
  readonly methods?: readonly RefreshMethod[];
102
+ /**
103
+ * Retry sources previously skipped as parser-failed or source-unreadable once, ignoring their
104
+ * skip records. Unlike `force`, healthy unchanged mirrors are not re-parsed.
105
+ */
106
+ readonly retrySkipped?: boolean;
107
+ /**
108
+ * Cancels the refresh. It is checked between files and between phases, and it kills an in-flight parse
109
+ * worker and the MinSync, Jikji and datasource child processes. `refresh` then rejects with the signal's
110
+ * reason and records the run as failed; mirror entries written before the abort are kept.
111
+ */
112
+ readonly signal?: AbortSignal;
113
+ /** Called while the parse and datasource phases run. A throwing callback is ignored; it never fails the refresh. */
114
+ readonly onProgress?: (progress: AutoRAGRefreshProgress) => void;
115
+ /**
116
+ * Per-root `jikji prepare` controls: a hard `timeoutMs` wall per root and a
117
+ * `parseTimeout` (seconds, forwarded to `--parse-timeout`). Unset values fall
118
+ * back to the `jikji` client options. Cancel through the refresh `signal`.
119
+ */
120
+ readonly jikjiPrepare?: Omit<JikjiPrepareOptions, "signal">;
70
121
  }
71
122
  export interface AutoRAGMinSyncRefreshResult {
72
123
  readonly ok: boolean;
@@ -185,7 +236,6 @@ export interface AutoRAGAgentOptions {
185
236
  providerApiKeys?: Readonly<Record<string, string>>;
186
237
  searchPaths: string[];
187
238
  languages?: readonly LanguageTag[];
188
- manifestDir?: string;
189
239
  memoryPath?: string;
190
240
  workspacePath?: string;
191
241
  tools?: AgentTool[];
@@ -278,13 +328,23 @@ export interface AutoRAGAgentOptions {
278
328
  * {@link AutoRAGRetrievalLimits}. Values must be positive integers.
279
329
  */
280
330
  limits?: AutoRAGRetrievalLimits;
331
+ /** Parsed-mirror refresh limits and retry tuning. See {@link AutoRAGRefreshLimits}. */
332
+ refresh?: AutoRAGRefreshLimits;
281
333
  datasourceSkills?: readonly DatasourceSkill[];
334
+ /**
335
+ * Retry/backoff for datasource `index()` during refresh: 2 retries with
336
+ * jittered exponential backoff by default, applied only to failures the
337
+ * skill marks retryable. `maxRetries: 0` disables retrying.
338
+ */
339
+ datasourceRetry?: DatasourceRetryOptions;
282
340
  /** Non-fatal diagnostics from config/agent construction (e.g. skipped unknown datasources). */
283
341
  startupDiagnostics?: readonly SearchDocumentDiagnostic[];
284
- /** Maximum time a model/tool search may run before it is aborted. */
285
- searchTimeoutMs?: number;
286
- /** Maximum number of retrieval/tool executions allowed in one search. */
287
- maxSearchToolCalls?: number;
342
+ /**
343
+ * Runaway-loop guard: the run is aborted when one tool is called `maxCalls`
344
+ * times within `windowMs` (default 60 calls in 60 s). `false` disables it.
345
+ * There is no limit on a run's duration or its total number of tool calls.
346
+ */
347
+ toolCallBurstGuard?: ToolBurstGuardOptions | false;
288
348
  /**
289
349
  * Outbound SimpleX queries to trusted peer AutoRAG agents. Remote sessions
290
350
  * never receive this tool.
@@ -313,9 +373,9 @@ export interface RerankAgentOptions {
313
373
  provider?: string;
314
374
  /** Wire model id. @default "voyageai/rerank-3-lite" */
315
375
  model?: string;
316
- /** API key. Prefer `apiKeyEnv`; this is a programmatic seam. */
376
+ /** API key. Prefer `apiKeyEnv`; this is a programmatic seam. Not used by the `dazzi` provider. */
317
377
  apiKey?: string;
318
- /** Environment variable holding the provider API key. */
378
+ /** Environment variable holding the provider API key. Not used by the `dazzi` provider, which uses the `/login` credential. */
319
379
  apiKeyEnv?: string;
320
380
  /** Override the provider base URL. */
321
381
  baseUrl?: string;
@@ -368,7 +428,11 @@ export declare class AutoRAGAgent {
368
428
  private activeRunAbort;
369
429
  private modelNativeSearchAuth;
370
430
  private retrievalTrace;
371
- /** Evidence every retrieval tool returned this run; the answer's inline `[eN]` citations resolve against it. */
431
+ /**
432
+ * Evidence the retrieval tools returned; the answer's inline `[eN]` citations resolve against it. A bound
433
+ * interactive session keeps it for the whole conversation and persists it with the transcript; any other
434
+ * run starts from an empty ledger.
435
+ */
372
436
  private readonly evidenceLedger;
373
437
  private preliminaryCallback;
374
438
  /** Per-phase thinking levels of the two-phase search. */
@@ -378,6 +442,8 @@ export declare class AutoRAGAgent {
378
442
  private refreshing;
379
443
  private refreshState;
380
444
  private readonly searchPaths;
445
+ /** Roots handed to Jikji: duplicates and roots nested in another root are dropped (see `outermostJikjiRoots`). */
446
+ private readonly jikjiRoots;
381
447
  private readonly configuredSearchPaths;
382
448
  readonly languages: readonly LanguageTag[];
383
449
  private retrievalScopeBindings;
@@ -393,6 +459,7 @@ export declare class AutoRAGAgent {
393
459
  private readonly everythingClient;
394
460
  private readonly fsearchClient;
395
461
  private readonly datasourceSkills;
462
+ private readonly datasourceRetry;
396
463
  private readonly startupDiagnostics;
397
464
  private readonly datasourceAgentSkills;
398
465
  private readonly parserOptions;
@@ -412,8 +479,6 @@ export declare class AutoRAGAgent {
412
479
  private readonly excludePaths;
413
480
  private readonly baseSystemPromptConfig;
414
481
  private readonly droppedCallerToolNames;
415
- private readonly searchTimeoutMs;
416
- private readonly maxSearchToolCalls;
417
482
  private readonly piAgentDir;
418
483
  private readonly piSessionDir;
419
484
  private readonly persistPiSessions;
@@ -433,8 +498,9 @@ export declare class AutoRAGAgent {
433
498
  /** True when this agent was constructed for an untrusted remote peer. */
434
499
  readonly remoteSession: boolean;
435
500
  private activeRetrievalOptions;
436
- private searchToolCallCount;
501
+ private readonly toolBurstGuard;
437
502
  private readonly limits;
503
+ private readonly refreshLimits;
438
504
  constructor(options: AutoRAGAgentOptions);
439
505
  scanDuplicateDocuments(): Promise<ScanDuplicateDocumentsDetails>;
440
506
  /**
@@ -646,6 +712,12 @@ export declare class AutoRAGAgent {
646
712
  * as plain text, without any further tool calls.
647
713
  */
648
714
  buildFastAnswerPrompt(query: string, options: RetrievalOptions, baseline: string): string;
715
+ /**
716
+ * True when the bound interactive session already holds an assistant turn:
717
+ * the query continues a conversation instead of opening one. Read from the
718
+ * transcript, so a fresh session (`/new`) starts over with the full pipeline.
719
+ */
720
+ private isConversationTurn;
649
721
  /**
650
722
  * Prompt for a question Jev routed to a direct answer: general knowledge or
651
723
  * small talk. No retrieval ran and no verification phase follows, so the
@@ -695,7 +767,7 @@ export declare class AutoRAGAgent {
695
767
  */
696
768
  startWatchRefresh(options?: AutoRAGWatchRefreshOptions): AutoRAGWatchRefreshHandle;
697
769
  private defaultWatcherFactory;
698
- syncParsedMirrors(force?: boolean): Promise<ParsedMirrorSyncResult>;
770
+ syncParsedMirrors(force?: boolean, options?: Pick<ParsedMirrorSyncOptions, "signal" | "onProgress" | "retrySkipped">): Promise<ParsedMirrorSyncResult>;
699
771
  /**
700
772
  * Lightweight stat-only staleness scan used when `refresh` is called with
701
773
  * methods that exclude parsed mirrors (e.g. only `datasources` or `jikji`).
@@ -704,7 +776,7 @@ export declare class AutoRAGAgent {
704
776
  */
705
777
  private scanMirrorStaleness;
706
778
  private exactDuplicateExclusions;
707
- syncMinSync(force?: boolean): Promise<MinSyncSyncResult>;
779
+ syncMinSync(force?: boolean, signal?: AbortSignal): Promise<MinSyncSyncResult>;
708
780
  /** Provider for the Windows-only everything_search tool. */
709
781
  searchEverything(request: EverythingSearchRequest): Promise<EverythingSearchResult>;
710
782
  /**
@@ -722,12 +794,18 @@ export declare class AutoRAGAgent {
722
794
  * macOS/Linux.
723
795
  */
724
796
  stopFsearch(): Promise<void>;
725
- prepareJikji(): Promise<readonly AutoRAGJikjiPrepareResult[] | undefined>;
797
+ prepareJikji(options?: JikjiPrepareOptions): Promise<readonly AutoRAGJikjiPrepareResult[] | undefined>;
726
798
  /**
727
799
  * Build or incrementally update every root's Jikji index. Called only by
728
800
  * refresh/watch (and the explicit `prepareJikji()` API), never by a query:
729
- * `jikji prepare` reuses unchanged documents, and roots run in parallel so
730
- * one slow root does not serialize the rest.
801
+ * `jikji prepare` reuses unchanged documents. Roots are submitted together
802
+ * but `JikjiClient` runs them one at a time, because every root shares one
803
+ * central SQLite file that fails with "database is locked" under concurrent
804
+ * writers. Nested and duplicate roots are skipped: upstream rejects
805
+ * overlapping roots and the outer root's index already covers them. A failed
806
+ * or timed-out root is a degraded result (reported as a diagnostic), never a
807
+ * rejection, so the refresh still finishes. `jikji.parseTimeout` /
808
+ * `jikji.timeoutMs` / `jikji.prepareTimeoutMsPerFile` apply to every root.
731
809
  */
732
810
  private executeJikjiPrepare;
733
811
  private sanitizeJikjiPrepareResult;
@@ -1,3 +1,4 @@
1
+ import { type Static, Type } from "typebox";
1
2
  import type { RetrievalResult } from "../retrieval/types.js";
2
3
  import type { AutoRAGEvidenceRef } from "./results.js";
3
4
  export interface LedgerEvidenceInput {
@@ -13,28 +14,65 @@ export interface LedgerEvidenceInput {
13
14
  readonly evidenceType?: string;
14
15
  readonly evidenceLocation?: string;
15
16
  }
17
+ /** Custom session entry type under which a conversation persists its evidence ledger. */
18
+ export declare const EVIDENCE_ENTRY_TYPE = "autorag.evidence";
19
+ declare const ledgerEntrySchema: Type.TObject<{
20
+ id: Type.TString;
21
+ /** Source plus a digest of the full chunk: the same chunk retrieved again keeps its id. */
22
+ key: Type.TString;
23
+ method: Type.TString;
24
+ source: Type.TString;
25
+ content: Type.TString;
26
+ retrieverMix: Type.TArray<Type.TString>;
27
+ retrievalResultId: Type.TOptional<Type.TString>;
28
+ chunkIndex: Type.TOptional<Type.TNumber>;
29
+ lineNumber: Type.TOptional<Type.TNumber>;
30
+ parserType: Type.TOptional<Type.TString>;
31
+ documentType: Type.TOptional<Type.TString>;
32
+ documentArea: Type.TOptional<Type.TString>;
33
+ evidenceType: Type.TOptional<Type.TString>;
34
+ evidenceLocation: Type.TOptional<Type.TString>;
35
+ }>;
36
+ /** One recorded piece of evidence: what a retrieval tool returned, under the id it printed. */
37
+ export type LedgerEntry = Static<typeof ledgerEntrySchema>;
38
+ /**
39
+ * Entries a session persisted under {@link EVIDENCE_ENTRY_TYPE}. A malformed
40
+ * entry is skipped: its id then resolves to nothing and the citation is
41
+ * dropped with a diagnostic, never mis-resolved.
42
+ */
43
+ export declare function parseLedgerEntries(data: unknown): LedgerEntry[];
44
+ /** Highest evidence id ordinal among `entries` (`e12` is 12); 0 when there are none. */
45
+ export declare function highestOrdinal(entries: readonly LedgerEntry[]): number;
16
46
  export interface LookupEvidenceOptions {
17
47
  /** False in remote sessions: only evidence a tool returned this run may be cited. */
18
48
  readonly allowLocalFiles: boolean;
19
49
  }
20
50
  export declare function isRegularFile(path: string): boolean;
21
51
  /**
22
- * Per-run record of every piece of evidence a retrieval tool returned.
52
+ * Record of every piece of evidence the retrieval tools returned in one
53
+ * conversation.
23
54
  *
24
55
  * Tools hand the model a short id (`e1`, `e2`, ...) next to each result. The
25
56
  * model cites evidence by id; the harness resolves the id back to the exact
26
57
  * source, method, content, and chunk metadata it recorded. The model never
27
58
  * retypes a path or a chunk, so it cannot misquote or invent one, and the
28
59
  * stable evidence id stored in memory is always derived from real evidence.
60
+ *
61
+ * Ids count up for as long as the process lives and are never reissued, so an
62
+ * id the model saw in any earlier turn keeps naming the chunk it named. The
63
+ * hosting session persists what {@link takeUnsaved} returns and rebuilds the
64
+ * ledger with {@link restore} when a conversation is resumed.
29
65
  */
30
66
  export declare class EvidenceLedger {
31
67
  private entries;
32
68
  private readonly byKey;
33
69
  private readonly byId;
70
+ /** Entries recorded or changed since the last {@link takeUnsaved}. */
71
+ private readonly unsaved;
34
72
  /**
35
- * Ordinal of the last issued id. Survives {@link clear}: a hosted (TUI)
36
- * conversation keeps earlier runs' tool output in context, so restarting at
37
- * e1 would let a stale id silently resolve to a different chunk.
73
+ * Ordinal of the last issued id. Survives {@link clear} and {@link restore}:
74
+ * a conversation keeps earlier turns' tool output in context, so restarting
75
+ * at e1 would let a stale id silently resolve to a different chunk.
38
76
  */
39
77
  private lastOrdinal;
40
78
  /** Record evidence and return its id. The same chunk always gets the same id. */
@@ -49,6 +87,17 @@ export declare class EvidenceLedger {
49
87
  * citation instead of failing the run.
50
88
  */
51
89
  lookup(raw: string, options: LookupEvidenceOptions): AutoRAGEvidenceRef[];
52
- /** Forget every recorded entry. Ids are never reissued, so a previous run's id stays unresolvable. */
90
+ /** Forget every recorded entry. Ids are never reissued, so a previous conversation's id stays unresolvable. */
53
91
  clear(): void;
92
+ /** Entries recorded or changed since the last call, for the hosting session to persist. */
93
+ takeUnsaved(): LedgerEntry[];
94
+ /**
95
+ * Rebuild the ledger from persisted entries, such as the ones on the resumed
96
+ * conversation branch; a later entry with the same id replaces an earlier
97
+ * one. Ids keep counting past every restored id and past `ordinalFloor`, the
98
+ * highest id issued anywhere in the conversation (other branches included),
99
+ * so a restored ledger never reissues an id a transcript may still show.
100
+ */
101
+ restore(entries: readonly LedgerEntry[], ordinalFloor?: number): void;
54
102
  }
103
+ export {};
@@ -0,0 +1,24 @@
1
+ import type { ExtensionFactory, SessionEntry } from "@earendil-works/pi-coding-agent";
2
+ import { type EvidenceLedger } from "./evidence-ledger.js";
3
+ /** The part of pi's session manager the ledger is rebuilt from. */
4
+ interface SessionEntries {
5
+ getBranch(): SessionEntry[];
6
+ getEntries(): SessionEntry[];
7
+ }
8
+ /**
9
+ * Rebuild `ledger` for the conversation branch `session` is on. Evidence from
10
+ * other branches stays out of reach (their transcripts are not in context), but
11
+ * its ids still count: new evidence never reuses an id issued anywhere in the
12
+ * conversation.
13
+ */
14
+ export declare function restoreEvidenceLedger(ledger: EvidenceLedger, session: SessionEntries): void;
15
+ /**
16
+ * pi extension that keeps the conversation's evidence ledger in the session
17
+ * file, next to the transcript that shows the model its `[eN]` ids. Evidence is
18
+ * appended as the tools return it; switching, resuming, forking, or navigating
19
+ * the session tree rebuilds the ledger from the branch now in view. An id the
20
+ * model saw therefore resolves, and is never reissued, whatever turns, tool
21
+ * calls, resumes, or restarts happened in between.
22
+ */
23
+ export declare function createEvidencePersistence(ledger: EvidenceLedger): ExtensionFactory;
24
+ export {};
@@ -4,10 +4,10 @@ import { type JevBackend, type Judgment, type Question, type State } from "jev-u
4
4
  export declare const JEV_TOOL_NAME = "jev";
5
5
  /**
6
6
  * Jev backends the `jev-use` engine resolves from the environment, in
7
- * auto-select order: TypeSafe -> OpenRouter -> Vercel AI Gateway. `autorag` is
8
- * the hosted AutoRAG (Dazzi) plan, built here rather than resolved by jev-use.
7
+ * auto-select order: TypeSafe -> OpenRouter -> Vercel AI Gateway. `dazzi` is
8
+ * the hosted Dazzi Models plan, built here rather than resolved by jev-use.
9
9
  */
10
- export type JevBackendName = "typesafe" | "openrouter" | "vercel" | "autorag";
10
+ export type JevBackendName = "typesafe" | "openrouter" | "vercel" | "dazzi";
11
11
  /**
12
12
  * OpenRouter's live Jev model id. `jev-use` 0.8.0 ships `typesafe/jev-latest`,
13
13
  * which OpenRouter rejects with HTTP 400 ("Model ... does not exist"), so the
@@ -40,6 +40,8 @@ export interface JevToolOptions {
40
40
  export interface JevJudgeOptions extends JevToolOptions {
41
41
  /** Environment consulted for the backend credential. Default `process.env`. */
42
42
  readonly env?: Record<string, string | undefined>;
43
+ /** Pi agent home whose `auth.json` holds the Dazzi `/login` credential. Default: Pi's agent dir. */
44
+ readonly agentDir?: string;
43
45
  }
44
46
  /**
45
47
  * One batched Jev judgment. Rejects only when no backend can be built (for
@@ -9,7 +9,7 @@ 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" | "no-verified-results" | "unknown-warning" | "caller-tool-dropped" | "minsync-staging-excluded" | "minsync-sync-failed" | "embedder-unavailable" | "embedding-identity-mismatch" | "parser-skipped" | "parser-failed" | "source-vanished" | "source-unreadable" | "parser-warning" | "duplicate-excluded" | "unsupported-file" | "stale-index" | "deleted-mirror" | "pdf-extract-thin" | "retrieval-method-failed" | "rerank-failed" | "jikji-unavailable" | "jikji-prepare-failed" | "jikji-find-failed" | "everything-index-failed" | "fsearch-index-failed" | "fsearch-binary-missing" | "refresh-failed" | "refresh-interrupted" | "watch-failed" | "watch-limited" | "unknown-datasource-skill" | "no-final-answer" | "model-request-failed" | "search-timeout" | "query-routed" | "query-route-fallback" | "query-decomposition-failed" | "follow-up-skipped" | "follow-up-check-fallback" | "datasources-selected" | "datasource-selection-fallback" | "citation-without-result" | "evidence-judged" | "evidence-judgment-fallback" | "memory-search-fallback" | "self-config-unavailable" | "self-config-rolled-back";
12
+ export type SearchDocumentDiagnosticCode = "empty-query" | "no-verified-results" | "unknown-warning" | "caller-tool-dropped" | "minsync-staging-excluded" | "minsync-file-skipped" | "minsync-sync-failed" | "minsync-lock-held" | "embedder-unavailable" | "embedding-identity-mismatch" | "parser-skipped" | "parser-failed" | "parser-crashed" | "source-vanished" | "source-unreadable" | "source-read-failed" | "mirror-write-failed" | "parser-warning" | "duplicate-excluded" | "unsupported-file" | "stale-index" | "deleted-mirror" | "search-root-unavailable" | "mass-delete-suppressed" | "walk-truncated" | "directory-unreadable" | "pdf-extract-thin" | "retrieval-method-failed" | "rerank-failed" | "jikji-unavailable" | "jikji-prepare-failed" | "jikji-find-failed" | "everything-index-failed" | "fsearch-index-failed" | "fsearch-binary-missing" | "refresh-failed" | "refresh-interrupted" | "watch-failed" | "watch-limited" | "unknown-datasource-skill" | "no-final-answer" | "model-request-failed" | "tool-call-burst" | "query-routed" | "query-route-fallback" | "query-decomposition-failed" | "follow-up-skipped" | "follow-up-check-fallback" | "datasources-selected" | "datasource-selection-fallback" | "citation-without-result" | "evidence-judged" | "evidence-judgment-fallback" | "memory-search-fallback" | "self-config-unavailable" | "self-config-rolled-back";
13
13
  export interface SearchDocumentDiagnostic {
14
14
  readonly code: SearchDocumentDiagnosticCode;
15
15
  readonly severity: SearchDocumentDiagnosticSeverity;
@@ -1,10 +1,8 @@
1
- import type { StoreManifest } from "../manifest/types.js";
2
1
  import type { DatasourceAgentSkill } from "./datasource-skill.js";
3
2
  export interface SystemPromptConfig {
4
3
  toolNames: string[];
5
4
  modelId?: string;
6
5
  memoryEntries?: readonly unknown[];
7
- manifests: StoreManifest[];
8
6
  jikjiIndexingEnabled?: boolean;
9
7
  datasourceSkills?: readonly DatasourceAgentSkill[];
10
8
  retrievedContentGuard?: boolean;