@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
@@ -0,0 +1,25 @@
1
+ import type { Api, Model } from "@earendil-works/pi-ai";
2
+ /** Hard cap on search queries one question may decompose into. */
3
+ export declare const MAX_DECOMPOSED_QUERIES = 5;
4
+ /** Prompt in, raw completion text out. The seam the decomposer calls. */
5
+ export type DecompositionCompleter = (prompt: string) => Promise<string>;
6
+ /** A pi-ai model plus the credential used only for decomposition calls. */
7
+ export interface DecompositionModel {
8
+ readonly model: Model<Api>;
9
+ readonly apiKey?: string;
10
+ }
11
+ export declare function buildDecompositionPrompt(query: string): string;
12
+ /**
13
+ * Parse the model's reply into at most {@link MAX_DECOMPOSED_QUERIES} unique,
14
+ * non-empty queries. Accepts `{"queries": [...]}`, a bare array (optionally
15
+ * fenced or wrapped in prose), or one query per line as a last resort.
16
+ */
17
+ export declare function parseDecomposedQueries(text: string): string[];
18
+ /**
19
+ * Decompose one question into up to {@link MAX_DECOMPOSED_QUERIES} search
20
+ * queries. A reply with no usable query falls back to the original question,
21
+ * so the caller always has something to search.
22
+ */
23
+ export declare function decomposeQuery(complete: DecompositionCompleter, query: string): Promise<string[]>;
24
+ /** Completer over a pi-ai model: one user turn, thinking off, short output. */
25
+ export declare function createModelDecompositionCompleter(target: DecompositionModel, signal?: AbortSignal): DecompositionCompleter;
@@ -0,0 +1,54 @@
1
+ import type { JevJudge } from "./jev-extension.js";
2
+ /**
3
+ * Where a user question is answered from:
4
+ * - `local`: information only the user can reach (their files, chats, mail).
5
+ * - `web`: public information one internet search would answer.
6
+ * - `direct`: general knowledge or small talk the model answers on its own.
7
+ */
8
+ export type QueryRoute = "local" | "web" | "direct";
9
+ /** Jev question id of the three-way branch. */
10
+ export declare const QUERY_ROUTE_QUESTION_ID = "route";
11
+ /** Jev question id of the "does this need decomposition?" check. */
12
+ export declare const DECOMPOSE_QUESTION_ID = "decompose";
13
+ /** Jev question id of the post-fast-answer "needs follow-up?" check. */
14
+ export declare const FOLLOW_UP_QUESTION_ID = "follow_up";
15
+ /** Route used whenever Jev gives no usable branch: today's local search. */
16
+ export declare const FALLBACK_QUERY_ROUTE: QueryRoute;
17
+ /** A `noul` probability at or above this asks for question decomposition. */
18
+ export declare const DECOMPOSE_PROBABILITY_THRESHOLD = 0.5;
19
+ /** A `noul` probability at or above this sends the fast answer on to verification. */
20
+ export declare const FOLLOW_UP_PROBABILITY_THRESHOLD = 0.5;
21
+ export interface FollowUpDecision {
22
+ /** True when the run continues into the verification phase. */
23
+ readonly followUp: boolean;
24
+ /** Jev's P(follow-up needed), when it answered. */
25
+ readonly probability?: number;
26
+ /** Why the check fell back to verifying instead of following Jev; absent when Jev decided. */
27
+ readonly fallbackReason?: string;
28
+ }
29
+ /**
30
+ * Ask Jev whether the fast answer needs correction, clarification, or further
31
+ * research. Never throws: a missing credential, an unreachable backend, or a
32
+ * verdict with no probability keeps verifying, because ending early on an
33
+ * unchecked answer is the costlier mistake.
34
+ */
35
+ export declare function needsFollowUp(judge: JevJudge, query: string, answer: string): Promise<FollowUpDecision>;
36
+ export interface QueryRouteDecision {
37
+ /** Most probable branch; {@link FALLBACK_QUERY_ROUTE} when Jev gave none. */
38
+ readonly route: QueryRoute;
39
+ /** True when Jev judged the question needs decomposition (never for `direct`). */
40
+ readonly decompose: boolean;
41
+ /** Probability Jev gave the chosen branch, when it reported a distribution. */
42
+ readonly routeProbability?: number;
43
+ /** Jev's P(decomposition needed), when it answered. */
44
+ readonly decomposeProbability?: number;
45
+ /** Why the decision fell back instead of following Jev; absent when Jev decided. */
46
+ readonly fallbackReason?: string;
47
+ }
48
+ /**
49
+ * Ask Jev, in one batched call about the user question, which branch answers
50
+ * it and whether it needs decomposition. Never throws: a missing credential,
51
+ * an unreachable backend, or an unusable verdict falls back to a single local
52
+ * search, with the reason recorded.
53
+ */
54
+ export declare function routeQuery(judge: JevJudge, query: string): Promise<QueryRouteDecision>;
@@ -10,7 +10,7 @@ export type SearchDocumentDiagnosticSeverity = "info" | "warning" | "error";
10
10
  * (#21/#22) does not require another source-breaking type change; codes not yet
11
11
  * emitted are still valid members.
12
12
  */
13
- export type SearchDocumentDiagnosticCode = "empty-query" | "no-verified-results" | "unknown-warning" | "caller-tool-dropped" | "minsync-unavailable" | "minsync-staging-excluded" | "minsync-sync-failed" | "embedder-unavailable" | "embedding-identity-mismatch" | "parser-skipped" | "parser-failed" | "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" | "missing-final-emit" | "model-request-failed";
13
+ export type SearchDocumentDiagnosticCode = "empty-query" | "no-verified-results" | "unknown-warning" | "caller-tool-dropped" | "minsync-unavailable" | "minsync-staging-excluded" | "minsync-sync-failed" | "embedder-unavailable" | "embedding-identity-mismatch" | "parser-skipped" | "parser-failed" | "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" | "missing-final-emit" | "model-request-failed" | "query-routed" | "query-route-fallback" | "query-decomposition-failed" | "follow-up-skipped" | "follow-up-check-fallback" | "citation-without-result";
14
14
  export interface SearchDocumentDiagnostic {
15
15
  readonly code: SearchDocumentDiagnosticCode;
16
16
  readonly severity: SearchDocumentDiagnosticSeverity;
@@ -107,5 +107,5 @@ export declare function createEmptySearchDocumentsResponse(sessionId: string, qu
107
107
  export declare function recordStructuredResultsSession(sessionId: string, query: string, details: AutoRAGResultsDetails, sessions: SearchSessions, memory: RetrievalMemory, componentDiagnostics?: readonly SearchDocumentDiagnostic[], options?: {
108
108
  readonly isolateMemory?: boolean;
109
109
  }): SearchDocumentsResponse;
110
- export declare function recordNumberedFeedback(sessions: ReadonlySearchSessions, memory: RetrievalMemory, sessionId: string, usefulNumbers: readonly number[], notUsefulNumbers: readonly number[]): void;
110
+ export declare function recordNumberedFeedback(sessions: ReadonlySearchSessions, memory: RetrievalMemory, sessionId: string, usefulNumbers: readonly number[], notUsefulNumbers: readonly number[]): boolean;
111
111
  export {};
@@ -9,5 +9,6 @@ export interface SystemPromptConfig {
9
9
  jikjiIndexingEnabled?: boolean;
10
10
  datasourceSkills?: readonly Skill[];
11
11
  retrievedContentGuard?: boolean;
12
+ remoteSession?: boolean;
12
13
  }
13
14
  export declare function buildSystemPrompt(config: SystemPromptConfig): string;
@@ -1,3 +1,25 @@
1
+ import type { MemorySchemaV4 } from "../../memory/memory.js";
1
2
  import type { CommandContext } from "./types.js";
3
+ interface EvidenceView {
4
+ readonly stableEvidenceId: string;
5
+ readonly method: string;
6
+ readonly source: string;
7
+ readonly excerpt?: string;
8
+ readonly content?: string;
9
+ readonly retrievalResultId?: string;
10
+ readonly chunkIndex?: number;
11
+ readonly lineNumber?: number;
12
+ readonly metadata?: Record<string, unknown>;
13
+ }
14
+ export declare function evidenceFor(schema: MemorySchemaV4, sessionId: string, resultNumber?: number): {
15
+ sessionId: string;
16
+ results: {
17
+ number: number;
18
+ title: string;
19
+ summary: string;
20
+ chunks: EvidenceView[];
21
+ }[];
22
+ };
2
23
  /** Show the persisted source/chunk evidence attached to a search session. */
3
24
  export declare function runEvidence(ctx: CommandContext): Promise<number>;
25
+ export {};
@@ -4,6 +4,7 @@ import type { CommandContext } from "./types.js";
4
4
  * Model flags are folded into the generated config. A legacy
5
5
  * `autorag.config.json` in the current working directory may be migrated
6
6
  * non-destructively. An existing home config is not overwritten without
7
- * `--force`.
7
+ * `--force`, and `--force` only replaces an existing config when the caller
8
+ * selected the path explicitly (`--config` or `AUTORAG_CONFIG`).
8
9
  */
9
10
  export declare function runInit(ctx: CommandContext): Promise<number>;
@@ -0,0 +1,8 @@
1
+ import { type AutoRAGUpdateResult } from "../update-check.js";
2
+ import type { CommandContext } from "./types.js";
3
+ export interface UpdateCheckDeps {
4
+ readonly currentVersion?: string;
5
+ readonly check?: (currentVersion: string) => Promise<AutoRAGUpdateResult>;
6
+ }
7
+ /** `autorag update-check`: compare the running package against the npm registry. */
8
+ export declare function runUpdateCheck(ctx: CommandContext, deps?: UpdateCheckDeps): Promise<number>;
@@ -1,7 +1,9 @@
1
1
  import type { Api, Model } from "@earendil-works/pi-ai";
2
2
  import { ModelRuntime } from "@earendil-works/pi-coding-agent";
3
3
  import type { AutoRAGAgentOptions, AutoRAGRetrievalLimits } from "../agent/agent.js";
4
+ import type { JevBackendName } from "../agent/jev-extension.js";
4
5
  import { type LoadLocalAutoRAGModelOptions } from "../agent/local-model.js";
6
+ import type { DecompositionModel } from "../agent/query-decomposition.js";
5
7
  import type { DatasourceAccessContextOptions } from "../datasource/access-context.js";
6
8
  import { type DatasourcesConfig } from "../datasource/skills/factory.js";
7
9
  import type { EnsureMinSyncBinaryOptions, MinSyncEmbedderConfig } from "../minsync/index.js";
@@ -51,6 +53,26 @@ export interface WebSearchCliConfig {
51
53
  timeoutSeconds?: number;
52
54
  } | false;
53
55
  }
56
+ /**
57
+ * Jev decision-tool config. Absent disables the tool; `enabled: false` disables
58
+ * it explicitly. Secrets never appear here: the `jev-use` engine reads the
59
+ * backend credential from its own environment variable (`TYPESAFE_API_KEY`,
60
+ * `OPENROUTER_API_KEY`, or `AI_GATEWAY_API_KEY`).
61
+ */
62
+ export interface JevCliConfig {
63
+ enabled?: boolean;
64
+ /** Force one backend; omit to let the first credential present win. */
65
+ backend?: JevBackendName;
66
+ /** Model id sent with every call, e.g. `jev-latest`. */
67
+ model?: string;
68
+ /** Escalate verdicts below this confidence (0-1). Default: per-source thresholds. */
69
+ confidenceThreshold?: number;
70
+ }
71
+ /** Question-decomposition config. Secrets stay in env/pi auth like the main model. */
72
+ export interface QueryDecompositionConfig {
73
+ /** Dedicated decomposition model; same shape and auth rules as the top-level `model`. */
74
+ model?: AgentModelConfig;
75
+ }
54
76
  /**
55
77
  * Post-merge reranking config. Routes merged evidence through a dedicated
56
78
  * rerank model. `provider` is `openrouter` today; `model` is the OpenRouter
@@ -68,7 +90,7 @@ export interface RerankConfig {
68
90
  apiKeyEnv?: string;
69
91
  /** Override the provider base URL (e.g. a gateway). */
70
92
  baseUrl?: string;
71
- /** Return only the top N merged results. Omitted ⇒ all distinct results are reordered. */
93
+ /** Return only the top N merged results. @default 25 (DEFAULT_RERANK_TOP_N) */
72
94
  topN?: number;
73
95
  /** Per-request timeout in milliseconds. */
74
96
  timeoutMs?: number;
@@ -145,6 +167,21 @@ export interface CliConfig {
145
167
  watch?: boolean;
146
168
  } | false;
147
169
  webSearch?: WebSearchCliConfig;
170
+ /**
171
+ * Jev query routing (local / web / direct), the decomposition check, the
172
+ * post-fast-answer follow-up check, and the `jev` tool. On by default with
173
+ * the OpenRouter backend; `false` or `enabled: false` disables it. Secrets
174
+ * never appear here: `jev-use` reads the backend key from its own
175
+ * environment variable.
176
+ */
177
+ jev?: JevCliConfig | false;
178
+ /**
179
+ * Question decomposition for the Jev query pipeline. `model` names the LLM
180
+ * that splits one question into at most five search queries; absent or `{}`
181
+ * uses {@link DEFAULT_QUERY_DECOMPOSITION_MODEL}, and `false` lets the
182
+ * agent's own model decompose.
183
+ */
184
+ queryDecomposition?: QueryDecompositionConfig | false;
148
185
  /** Post-merge reranking. Absent ⇒ reranking disabled. `false` disables it. */
149
186
  rerank?: RerankConfig | false;
150
187
  parserOptions?: Record<string, unknown>;
@@ -205,6 +242,19 @@ export declare function resolveConfig(input: ResolveConfigInput): CliConfig;
205
242
  * would resolve them but never copied into `~/.autorag/config.json`.
206
243
  */
207
244
  export declare function resolveConfigReadOnly(input: ResolveConfigInput): CliConfig;
245
+ /** Validate and normalize the `jev` config section. */
246
+ export declare function normalizeJevConfig(raw: unknown): JevCliConfig;
247
+ /** Jev backend used when the config names none (absent section or `{}`). */
248
+ export declare const DEFAULT_JEV_BACKEND: JevBackendName;
249
+ /**
250
+ * Question-decomposition model used when the config names none. Picked from a
251
+ * live OpenRouter bench (6 questions incl. Korean, 2 runs each): 12/12 valid,
252
+ * covering, language-preserving decompositions at ~0.9s p50, about 3.5x
253
+ * cheaper per call than google/gemini-2.5-flash-lite at equal quality.
254
+ */
255
+ export declare const DEFAULT_QUERY_DECOMPOSITION_MODEL: AgentModelConfig;
256
+ /** Validate the `queryDecomposition` config section (`false` = decompose with the session model). */
257
+ export declare function normalizeQueryDecompositionConfig(raw: unknown): QueryDecompositionConfig | false;
208
258
  /** Normalize and validate the `rerank` config section, filling in defaults. */
209
259
  export declare function normalizeRerankConfig(raw: unknown, path: string): RerankConfig | false;
210
260
  export declare function buildAgentOptions(config: CliConfig): Omit<AutoRAGAgentOptions, "model">;
@@ -253,6 +303,13 @@ export interface ResolvedAgentModelDetailed {
253
303
  readonly role: ResolvedAgentModelRole;
254
304
  }
255
305
  export declare function resolveAgentModel(config: CliConfig, options?: ResolveAgentModelOptions): Promise<ResolvedAgentModel>;
306
+ /**
307
+ * Resolve the question-decomposition model and its credential through the same
308
+ * chain as the agent model. An absent section or `{}` uses
309
+ * {@link DEFAULT_QUERY_DECOMPOSITION_MODEL}; `queryDecomposition: false`
310
+ * returns undefined so the agent's own model decomposes.
311
+ */
312
+ export declare function resolveQueryDecompositionModel(config: CliConfig, options?: ResolveAgentModelOptions): Promise<DecompositionModel | undefined>;
256
313
  export declare function resolveAgentModelDetailed(config: CliConfig, options?: ResolveAgentModelOptions): Promise<ResolvedAgentModelDetailed>;
257
314
  export declare function readRawConfigObject(path: string): Record<string, unknown>;
258
315
  /** Atomically replace a config file, preserving the caller's JSON object. */
@@ -262,4 +319,12 @@ export declare function writeDefaultConfig(path: string, partial: Partial<CliCon
262
319
  atomicCreate?: boolean;
263
320
  cwd?: string;
264
321
  env?: NodeJS.ProcessEnv;
322
+ /**
323
+ * Whether the target path was selected explicitly by the caller
324
+ * (`--config` / `AUTORAG_CONFIG`). When `false`, `force` refuses to
325
+ * replace an existing file: an implicit home config may only be
326
+ * replaced through an explicit config path. `undefined` (callers that
327
+ * do not distinguish) keeps the historical force semantics.
328
+ */
329
+ explicit?: boolean;
265
330
  }): void;
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- declare const COMMANDS: readonly ["init", "setup", "refresh", "status", "search", "feedback", "evidence", "memory", "index", "watch", "health", "duplicates", "tui", "serve", "p2p", "lite", "models", "gateway"];
2
+ declare const COMMANDS: readonly ["init", "setup", "refresh", "status", "search", "feedback", "evidence", "memory", "index", "watch", "health", "duplicates", "tui", "serve", "p2p", "lite", "models", "gateway", "update-check"];
3
3
  type CommandName = (typeof COMMANDS)[number];
4
4
  export type { CommandName };
5
5
  interface ParsedArgs {