@autorag/librarian 2.7.0 → 2.9.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 (98) hide show
  1. package/NOTICE +10 -4
  2. package/README.md +122 -38
  3. package/dist/agent/agent.d.ts +210 -53
  4. package/dist/agent/answer-guidelines.d.ts +19 -0
  5. package/dist/agent/citations.d.ts +43 -0
  6. package/dist/agent/datasource-skill.d.ts +30 -16
  7. package/dist/agent/emit-results-tool.d.ts +37 -2
  8. package/dist/agent/evidence-judgment.d.ts +58 -0
  9. package/dist/agent/evidence-ledger.d.ts +59 -0
  10. package/dist/agent/evidence-origins.d.ts +49 -0
  11. package/dist/agent/fast-answer-tool.d.ts +16 -6
  12. package/dist/agent/index.d.ts +2 -1
  13. package/dist/agent/jev-extension.d.ts +68 -0
  14. package/dist/agent/jikji-find-tool.d.ts +2 -1
  15. package/dist/agent/pi-session.d.ts +28 -1
  16. package/dist/agent/query-decomposition.d.ts +25 -0
  17. package/dist/agent/query-peer-tool.d.ts +3 -0
  18. package/dist/agent/query-routing.d.ts +115 -0
  19. package/dist/agent/search-all-tool.d.ts +5 -5
  20. package/dist/agent/search-documents.d.ts +3 -11
  21. package/dist/agent/search-minsync-tool.d.ts +5 -5
  22. package/dist/agent/search-single-datasource-tool.d.ts +9 -8
  23. package/dist/agent/self-config.d.ts +40 -0
  24. package/dist/agent/system-prompt.d.ts +3 -3
  25. package/dist/agent/web-fetch-tool.d.ts +2 -1
  26. package/dist/agent/web-search-tool.d.ts +2 -1
  27. package/dist/cli/commands/evidence.d.ts +22 -0
  28. package/dist/cli/commands/init.d.ts +2 -1
  29. package/dist/cli/commands/memory.d.ts +1 -1
  30. package/dist/cli/commands/report.d.ts +1 -1
  31. package/dist/cli/commands/update-check.d.ts +8 -0
  32. package/dist/cli/config.d.ts +80 -7
  33. package/dist/cli/index.d.ts +1 -1
  34. package/dist/cli/index.js +3844 -2291
  35. package/dist/cli/output.d.ts +2 -6
  36. package/dist/cli/update-check.d.ts +34 -0
  37. package/dist/cli/version.d.ts +5 -0
  38. package/dist/config/home.d.ts +6 -0
  39. package/dist/core.d.ts +30 -6
  40. package/dist/core.js +7742 -6225
  41. package/dist/datasource/chunk-store.d.ts +2 -6
  42. package/dist/datasource/connector-skill.d.ts +2 -3
  43. package/dist/datasource/index.d.ts +2 -4
  44. package/dist/datasource/registry.d.ts +11 -13
  45. package/dist/datasource/scope.d.ts +19 -0
  46. package/dist/datasource/skills/github-gist/index.d.ts +1 -1
  47. package/dist/datasource/skills/github-gist/semantic.d.ts +3 -44
  48. package/dist/datasource/skills/github-gist/skill.d.ts +3 -3
  49. package/dist/datasource/types.d.ts +14 -28
  50. package/dist/embedding-runtime/gateway-embedder.d.ts +41 -0
  51. package/dist/everything/bundle.d.ts +15 -3
  52. package/dist/everything/client.d.ts +22 -5
  53. package/dist/everything/index.d.ts +1 -1
  54. package/dist/filesystem/name-search.d.ts +57 -0
  55. package/dist/fsearch/client.d.ts +7 -1
  56. package/dist/index.d.ts +2 -1
  57. package/dist/index.js +9139 -6376
  58. package/dist/jikji/client.d.ts +6 -1
  59. package/dist/language.d.ts +2 -1
  60. package/dist/mcp/index.d.ts +2 -0
  61. package/dist/mcp/index.js +30542 -0
  62. package/dist/mcp/server.d.ts +9 -0
  63. package/dist/memory/check-memory-tool.d.ts +8 -4
  64. package/dist/memory/context.d.ts +51 -0
  65. package/dist/memory/index.d.ts +8 -1
  66. package/dist/memory/judged-evidence.d.ts +32 -0
  67. package/dist/memory/memory.d.ts +36 -120
  68. package/dist/memory/renderer.d.ts +16 -7
  69. package/dist/memory/similar-queries.d.ts +40 -0
  70. package/dist/minsync/errors.d.ts +14 -0
  71. package/dist/minsync/index.d.ts +1 -0
  72. package/dist/minsync/method.d.ts +8 -5
  73. package/dist/mirror/index.d.ts +1 -1
  74. package/dist/mirror/paths.d.ts +6 -0
  75. package/dist/mirror/sync.d.ts +5 -2
  76. package/dist/parser/defaults.d.ts +16 -5
  77. package/dist/parser/index.d.ts +1 -1
  78. package/dist/parser/kordoc.d.ts +8 -1
  79. package/dist/parser/ocr-engines.d.ts +19 -0
  80. package/dist/retrieval/bm25.d.ts +19 -0
  81. package/dist/retrieval/engine.d.ts +33 -43
  82. package/dist/retrieval/index.d.ts +3 -1
  83. package/dist/retrieval/merger.d.ts +6 -0
  84. package/dist/retrieval/rerank.d.ts +4 -2
  85. package/dist/retrieval/selection.d.ts +89 -0
  86. package/dist/retrieval/types.d.ts +1 -3
  87. package/dist/web/search/format.d.ts +5 -2
  88. package/dist/web/search/index.d.ts +7 -1
  89. package/package.json +11 -7
  90. package/skills/autorag/SKILL.md +43 -23
  91. package/skills/autorag-doctor/SKILL.md +40 -26
  92. package/skills/autorag-lite-setup/SKILL.md +123 -64
  93. package/skills/autorag-setup/SKILL.md +107 -22
  94. package/dist/cli/commands/feedback.d.ts +0 -8
  95. package/dist/datasource/access-context.d.ts +0 -43
  96. package/dist/datasource/result-filter.d.ts +0 -64
  97. package/dist/parser/ocr.d.ts +0 -31
  98. package/skills/autorag-lite-search/SKILL.md +0 -245
@@ -0,0 +1,58 @@
1
+ import type { JevJudge } from "./jev-extension.js";
2
+ /**
3
+ * Retrieval memory stores only evidence that really supports the answer, so
4
+ * every cited piece is put back to Jev: does this evidence support the
5
+ * sentence it backs, and is answering the user's question impossible to trust
6
+ * without it? One batched call covers all of a run's evidence at once.
7
+ *
8
+ * The judgment is scoped per evidence and never merges units: a run can cite
9
+ * one result with several evidence pieces, each backing a different sentence,
10
+ * and only some of them needed.
11
+ */
12
+ /** One evidence a final answer cites. */
13
+ export interface EvidenceJudgmentUnit {
14
+ /** Unique within one call, e.g. `${resultNumber}:${stableEvidenceId}`. */
15
+ readonly id: string;
16
+ /** The cited result [n] this evidence backs. */
17
+ readonly resultNumber: number;
18
+ /** That result's title. */
19
+ readonly title: string;
20
+ /** That result's summary. */
21
+ readonly summary: string;
22
+ /** The query that surfaced the evidence. */
23
+ readonly searchQuery: string;
24
+ /** Retrieval method that surfaced it. */
25
+ readonly method: string;
26
+ /** The evidence text. */
27
+ readonly excerpt: string;
28
+ }
29
+ export interface EvidenceJudgmentInput {
30
+ readonly question: string;
31
+ readonly answer: string;
32
+ readonly units: readonly EvidenceJudgmentUnit[];
33
+ }
34
+ export interface EvidenceJudgment {
35
+ /** Jev's P(evidence supports the question), per unit id, for every unit Jev answered. */
36
+ readonly probabilities: Readonly<Record<string, number>>;
37
+ /** Unit ids with probability >= {@link EVIDENCE_SUPPORT_THRESHOLD}, in input order. */
38
+ readonly kept: readonly string[];
39
+ /** Set when Jev gave no usable verdict for ANY unit (judge threw, or no numeric verdicts); verbatim error / hint text. Absent when Jev decided. */
40
+ readonly fallbackReason?: string;
41
+ }
42
+ /** Jev question id of one evidence support check. */
43
+ export declare const EVIDENCE_QUESTION_ID_PREFIX = "evidence:";
44
+ /** Jev question id of the support check for one evidence unit. */
45
+ export declare function evidenceQuestionId(unitId: string): string;
46
+ /**
47
+ * The sentences/lines of `answer` that cite result `number` with a bracketed
48
+ * `[number]` marker (not a markdown link `[n](...)`). Splits on sentence
49
+ * terminators followed by whitespace or end, so Korean and English bullet
50
+ * lists both survive, and dedupes so one sentence backs a result once.
51
+ */
52
+ export declare function answerSentencesCiting(answer: string, number: number): string[];
53
+ /**
54
+ * Ask Jev, in one batched call, whether each cited evidence supports its backed
55
+ * sentence. Never throws: a rejecting judge keeps nothing and reports why, and
56
+ * a unit Jev left unanswered is simply absent from `probabilities`.
57
+ */
58
+ export declare function judgeEvidence(judge: JevJudge, input: EvidenceJudgmentInput): Promise<EvidenceJudgment>;
@@ -0,0 +1,59 @@
1
+ import type { RetrievalResult } from "../retrieval/types.js";
2
+ import type { AutoRAGEvidenceRef } from "./emit-results-tool.js";
3
+ export interface LedgerEvidenceInput {
4
+ readonly method: string;
5
+ readonly source: string;
6
+ readonly content: string;
7
+ readonly retrievalResultId?: string;
8
+ readonly chunkIndex?: number;
9
+ readonly lineNumber?: number;
10
+ readonly parserType?: string;
11
+ readonly documentType?: string;
12
+ readonly documentArea?: string;
13
+ readonly evidenceType?: string;
14
+ readonly evidenceLocation?: string;
15
+ }
16
+ export interface ResolveEvidenceOptions {
17
+ /** Tool name used to prefix corrective errors. */
18
+ readonly label: string;
19
+ /** Result number the refs belong to; named in corrective errors. */
20
+ readonly number: number;
21
+ /** Excerpt recorded for a local file the model opened itself (no search returned it). */
22
+ readonly fallbackContent: string;
23
+ /** False in remote sessions: only evidence a tool returned this run may be cited. */
24
+ readonly allowLocalFiles: boolean;
25
+ }
26
+ /**
27
+ * Per-run record of every piece of evidence a retrieval tool returned.
28
+ *
29
+ * Tools hand the model a short id (`e1`, `e2`, ...) next to each result. The
30
+ * model cites evidence by id; the harness resolves the id back to the exact
31
+ * source, method, content, and chunk metadata it recorded. The model never
32
+ * retypes a path or a chunk, so it cannot misquote or invent one, and the
33
+ * stable evidence id stored in memory is always derived from real evidence.
34
+ */
35
+ export declare class EvidenceLedger {
36
+ private entries;
37
+ private readonly byKey;
38
+ private readonly byId;
39
+ /**
40
+ * Ordinal of the last issued id. Survives {@link clear}: a hosted (TUI)
41
+ * conversation keeps earlier runs' tool output in context, so restarting at
42
+ * e1 would let a stale id silently resolve to a different chunk.
43
+ */
44
+ private lastOrdinal;
45
+ /** Record evidence and return its id. The same chunk always gets the same id. */
46
+ register(input: LedgerEvidenceInput): string;
47
+ /** Record one retrieval result as returned by `tool`; backend metadata is carried over. */
48
+ registerResult(tool: string, result: RetrievalResult): string;
49
+ /**
50
+ * Resolve model-supplied refs to recorded evidence. A ref is an evidence id
51
+ * (`e3` or `[e3]`), the exact source a tool returned (a URL, a datasource
52
+ * id, a path), or the absolute path of a real local file the model opened
53
+ * itself. Anything else throws a corrective error naming the result.
54
+ */
55
+ resolve(refs: readonly string[], options: ResolveEvidenceOptions): AutoRAGEvidenceRef[];
56
+ /** Forget every recorded entry. Ids are never reissued, so a previous run's id stays unresolvable. */
57
+ clear(): void;
58
+ private unresolvedMessage;
59
+ }
@@ -0,0 +1,49 @@
1
+ /**
2
+ * Remembers which search query and retrieval method surfaced each retrieval
3
+ * result during a run, so a final answer's evidence refs (which carry only a
4
+ * source, method, and text) can be mapped back to the query that found them.
5
+ * Retrieval memory needs both to store an evidence record; the refs alone do
6
+ * not know their query.
7
+ */
8
+ /** The query, retrieval method, and source of a remembered result. */
9
+ export interface EvidenceOrigin {
10
+ readonly query: string;
11
+ readonly method: string;
12
+ readonly source: string;
13
+ }
14
+ /** One retrieval result the agent saw, together with the query that produced it. */
15
+ export interface EvidenceOriginCandidate extends EvidenceOrigin {
16
+ readonly content: string;
17
+ }
18
+ /** The parts of a cited evidence ref that identify its origin. */
19
+ export interface EvidenceRefLike {
20
+ readonly source: string;
21
+ readonly method: string;
22
+ readonly excerpt?: string;
23
+ readonly content?: string;
24
+ }
25
+ /**
26
+ * Insertion-ordered index of retrieval results keyed by their source. Matching
27
+ * is deliberately text-based: a final answer's ref text is the same excerpt the
28
+ * retrieval returned, so it shares the candidate's content even when the ref
29
+ * carries a different method.
30
+ */
31
+ export declare class EvidenceOriginIndex {
32
+ private readonly candidates;
33
+ /** Sources already remembered, to the normalized contents seen for each. */
34
+ private readonly seen;
35
+ /**
36
+ * Remember one retrieval result and the query/method that produced it.
37
+ * First write wins for an identical (source, normalized content) pair.
38
+ */
39
+ add(candidate: EvidenceOriginCandidate): void;
40
+ /** Where `ref` came from, or undefined when no remembered result matches. */
41
+ resolve(ref: EvidenceRefLike): EvidenceOrigin | undefined;
42
+ /**
43
+ * Match a ref that carries no source (its text is the evidence text the
44
+ * answering model cited, possibly several excerpts joined by newlines)
45
+ * against every remembered candidate by text alone.
46
+ */
47
+ private resolveSourceless;
48
+ clear(): void;
49
+ }
@@ -1,5 +1,7 @@
1
1
  import type { AgentTool } from "@earendil-works/pi-agent-core";
2
2
  import { Type } from "typebox";
3
+ import type { AutoRAGEvidenceRef } from "./emit-results-tool.js";
4
+ import type { EvidenceLedger } from "./evidence-ledger.js";
3
5
  export declare const EMIT_FAST_ANSWER_TOOL_NAME = "emit_fast_answer";
4
6
  declare const fastAnswerSchema: Type.TObject<{
5
7
  answer: Type.TString;
@@ -12,11 +14,8 @@ declare const fastAnswerSchema: Type.TObject<{
12
14
  lineNumber: Type.TOptional<Type.TInteger>;
13
15
  }>>>;
14
16
  confidence: Type.TOptional<Type.TNumber>;
17
+ refs: Type.TOptional<Type.TArray<Type.TString>>;
15
18
  }>>;
16
- sources: Type.TOptional<Type.TArray<Type.TObject<{
17
- number: Type.TInteger;
18
- source: Type.TString;
19
- }>>>;
20
19
  }>;
21
20
  export interface AutoRAGFastAnswerResult {
22
21
  readonly number: number;
@@ -31,16 +30,27 @@ export interface AutoRAGFastAnswerResult {
31
30
  export interface AutoRAGFastAnswerDetails {
32
31
  readonly answer: string;
33
32
  readonly results: readonly AutoRAGFastAnswerResult[];
33
+ /** Number -> primary source, derived from `evidenceRefs`. */
34
34
  readonly sources: readonly {
35
35
  readonly number: number;
36
36
  readonly source: string;
37
37
  }[];
38
+ /** Harness-recorded evidence each result cited; never model-written text. */
39
+ readonly evidenceRefs: readonly {
40
+ readonly number: number;
41
+ readonly refs: readonly AutoRAGEvidenceRef[];
42
+ }[];
43
+ }
44
+ export interface EmitFastAnswerToolOptions {
45
+ /** Evidence the baseline retrieval produced; `refs` resolve against it. */
46
+ readonly ledger: EvidenceLedger;
38
47
  }
39
48
  /**
40
49
  * Builds the non-terminating fast-answer tool used by the two-phase search
41
50
  * flow. The model calls this exactly once during the thinking-off fast phase
42
51
  * to deliver an immediate, complete first answer; the run then continues into
43
- * the verification phase, which ends with emit_autorag_results.
52
+ * the verification phase, which ends with emit_autorag_results. Sources are
53
+ * derived from the evidence ids the model cites, never typed by the model.
44
54
  */
45
- export declare function createEmitFastAnswerTool(capture: (details: AutoRAGFastAnswerDetails) => void): AgentTool<typeof fastAnswerSchema, AutoRAGFastAnswerDetails>;
55
+ export declare function createEmitFastAnswerTool(capture: (details: AutoRAGFastAnswerDetails) => void, options: EmitFastAnswerToolOptions): AgentTool<typeof fastAnswerSchema, AutoRAGFastAnswerDetails>;
46
56
  export {};
@@ -3,7 +3,8 @@ export { AutoRAGAgent } from "./agent.js";
3
3
  export { buildDatasourceSkillsPrompt, createLoadDatasourceSkillTool, type DatasourceSkillProvider, datasourceSkillLocation, formatDatasourceSkillInvocation, LOAD_DATASOURCE_SKILL_TOOL_NAME, type LoadDatasourceSkillDetails, toDatasourceAgentSkill, } from "./datasource-skill.js";
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
- export { createEmitResultsTool, EMIT_AUTORAG_RESULTS_TOOL_NAME, emitResultsSchema, } from "./emit-results-tool.js";
6
+ export { createEmitResultsTool, EMIT_AUTORAG_RESULTS_TOOL_NAME, emitResultsSchema, reportSchema, } from "./emit-results-tool.js";
7
+ export { createJevExtension, JEV_TOOL_NAME, type JevBackendName, type JevToolOptions, } from "./jev-extension.js";
7
8
  export { createJikjiFindTool, JIKJI_FIND_TOOL_NAME, type JikjiFindDetails, type JikjiFindPerRootPolicy, type JikjiFindProvider, type JikjiFindProviderResult, type MergedJikjiPolicy, } from "./jikji-find-tool.js";
8
9
  export { createQueryPeerAgentTool, QUERY_PEER_AGENT_TOOL_NAME, type QueryPeerAgentDetails, type QueryPeerAgentResult, type QueryPeerAgentToolOptions, } from "./query-peer-tool.js";
9
10
  export { createSearchAllDocumentsTool, SEARCH_ALL_DOCUMENTS_TOOL_NAME, type SearchAllDocumentsDetails, type SearchAllDocumentsProvider, type SearchAllDocumentsResult, } from "./search-all-tool.js";
@@ -0,0 +1,68 @@
1
+ import type { ExtensionFactory } from "@earendil-works/pi-coding-agent";
2
+ import { type JevBackend, type Judgment, type Question, type State } from "jev-use";
3
+ /** `jev` tool name, kept in AutoRAG's reserved set and system prompt. */
4
+ export declare const JEV_TOOL_NAME = "jev";
5
+ /**
6
+ * Jev backends the `jev-use` engine resolves from the environment, in
7
+ * auto-select order: TypeSafe -> OpenRouter -> Vercel AI Gateway.
8
+ */
9
+ export type JevBackendName = "typesafe" | "openrouter" | "vercel";
10
+ /**
11
+ * OpenRouter's live Jev model id. `jev-use` 0.8.0 ships `typesafe/jev-latest`,
12
+ * which OpenRouter rejects with HTTP 400 ("Model ... does not exist"), so the
13
+ * OpenRouter path is pinned here.
14
+ */
15
+ export declare const OPENROUTER_DEFAULT_MODEL = "typesafe/jev-1.13";
16
+ /**
17
+ * Options for the `jev` decision tool. Secrets never appear here: `jev-use`
18
+ * reads the backend credential from its own environment variable
19
+ * (`TYPESAFE_API_KEY`, `OPENROUTER_API_KEY`, or `AI_GATEWAY_API_KEY`).
20
+ */
21
+ export interface JevToolOptions {
22
+ /**
23
+ * Force one backend by name; omit to let the first credential present win.
24
+ * A ready-made `jev-use` backend instance is a programmatic seam (tests,
25
+ * custom transports); config only accepts names.
26
+ */
27
+ readonly backend?: JevBackendName | JevBackend;
28
+ /**
29
+ * Wire model id sent with every call. Omit for the backend default;
30
+ * OpenRouter is pinned to {@link OPENROUTER_DEFAULT_MODEL} because
31
+ * `jev-use` 0.8.0's own default (`typesafe/jev-latest`) is not a live
32
+ * OpenRouter model id.
33
+ */
34
+ readonly model?: string;
35
+ /** Escalate verdicts below this confidence. Default: per-source thresholds. */
36
+ readonly confidenceThreshold?: number;
37
+ }
38
+ /** {@link JevToolOptions} plus the environment `jev-use` resolves credentials from. */
39
+ export interface JevJudgeOptions extends JevToolOptions {
40
+ /** Environment consulted for the backend credential. Default `process.env`. */
41
+ readonly env?: Record<string, string | undefined>;
42
+ }
43
+ /**
44
+ * One batched Jev judgment. Rejects only when no backend can be built (for
45
+ * example a missing credential); an unreachable backend resolves with
46
+ * `escalate: true` verdicts, per `jev-use`'s contract.
47
+ */
48
+ export type JevJudge = (state: State, questions: Question[], options?: {
49
+ readonly confidenceThreshold?: number;
50
+ }) => Promise<Judgment>;
51
+ /**
52
+ * Builds the Jev judge shared by the `jev` tool and the query router. The
53
+ * `jev-use` client is created lazily on the first call, so no credential
54
+ * resolves at construction time, and the OpenRouter model pin applies to
55
+ * every caller.
56
+ */
57
+ export declare function createJevJudge(options?: JevJudgeOptions): JevJudge;
58
+ /**
59
+ * Builds the pi extension that registers the `jev` decision tool on top of the
60
+ * [`jev-use`](https://www.npmjs.com/package/jev-use) engine.
61
+ *
62
+ * Jev is TypeSafe's judgment model: typed questions about a state in, calibrated
63
+ * probabilities out — no generated text. `jev-use` owns backend auto-selection,
64
+ * request screening, and response validation; this extension only adapts the
65
+ * pi tool surface over {@link createJevJudge}. Pass the agent's shared judge
66
+ * so the tool and the query router reuse one lazily built client.
67
+ */
68
+ export declare function createJevExtension(judgeOrOptions?: JevJudge | JevToolOptions): ExtensionFactory;
@@ -1,6 +1,7 @@
1
1
  import type { AgentTool } from "@earendil-works/pi-agent-core";
2
2
  import { Type } from "typebox";
3
3
  import type { JikjiAnswerPack, JikjiCandidate, JikjiDiagnostic, JikjiEvidence, JikjiHandoffAction } from "../jikji/index.js";
4
+ import { EvidenceLedger } from "./evidence-ledger.js";
4
5
  export declare const JIKJI_FIND_TOOL_NAME = "jikji_find";
5
6
  /**
6
7
  * Run-scoped merged policy assembled from per-root Jikji answer packs using
@@ -71,5 +72,5 @@ declare const jikjiFindSchema: Type.TObject<{
71
72
  * Jikji is unavailable or all roots failed, the tool returns a short fallback
72
73
  * message so the agent falls back to bash, and no policy is set.
73
74
  */
74
- export declare function createJikjiFindTool(provider: JikjiFindProvider): AgentTool<typeof jikjiFindSchema, JikjiFindDetails>;
75
+ export declare function createJikjiFindTool(provider: JikjiFindProvider, ledger?: EvidenceLedger): AgentTool<typeof jikjiFindSchema, JikjiFindDetails>;
75
76
  export {};
@@ -1,7 +1,14 @@
1
1
  import type { AgentMessage, AgentTool } from "@earendil-works/pi-agent-core";
2
2
  import type { Api, Model } from "@earendil-works/pi-ai";
3
- import { type AgentSession, type AgentSessionRuntime, type ExtensionAPI } from "@earendil-works/pi-coding-agent";
3
+ import { type AgentSession, type AgentSessionRuntime, type ExtensionAPI, type ExtensionFactory, SettingsManager, type ToolDefinition, type TuiMode } from "@earendil-works/pi-coding-agent";
4
4
  export declare const PI_BUILTIN_TOOL_NAMES: readonly ["read", "bash", "edit", "write", "grep", "find", "ls"];
5
+ /**
6
+ * Terminal UI mode for AutoRAG's interactive session. pi 1.0 switched its own default to
7
+ * fullscreen; AutoRAG shipped on pi's scrollback UI, so that stays the default. A `tuiMode` the
8
+ * user saved in pi's global or project settings still wins, and `InteractiveMode` accepts the
9
+ * result directly (its constructor otherwise falls back to pi's fullscreen default).
10
+ */
11
+ export declare function resolveInteractiveTuiMode(settingsManager: SettingsManager): TuiMode;
5
12
  export interface AutoRAGPiSessionOptions {
6
13
  readonly cwd: string;
7
14
  readonly agentDir?: string;
@@ -13,6 +20,17 @@ export interface AutoRAGPiSessionOptions {
13
20
  readonly providerApiKeys?: Readonly<Record<string, string>>;
14
21
  readonly getSystemPrompt: () => string;
15
22
  readonly customTools: readonly AgentTool[];
23
+ /**
24
+ * Extra pi extensions to load alongside AutoRAG's own prompt/context
25
+ * extension. Each factory registers its tools, commands, and events with pi.
26
+ */
27
+ readonly extensionFactories?: readonly ExtensionFactory[];
28
+ /**
29
+ * Tool names registered by {@link extensionFactories}. pi's `tools`
30
+ * allow-list keeps only named tools active, so every extension tool that
31
+ * should be callable must appear here too.
32
+ */
33
+ readonly extensionToolNames?: readonly string[];
16
34
  readonly remoteSession?: boolean;
17
35
  readonly contextTransform?: (messages: AgentMessage[]) => Promise<AgentMessage[]>;
18
36
  }
@@ -20,12 +38,21 @@ export interface AutoRAGPiInteractiveRuntimeOptions extends Omit<AutoRAGPiSessio
20
38
  readonly model?: Model<Api>;
21
39
  readonly inactiveToolNames?: readonly string[];
22
40
  readonly onQuery: (query: string, pi: ExtensionAPI) => void | Promise<void>;
41
+ /**
42
+ * Optional best-effort provider for a startup update notice. Resolves to the
43
+ * notice text, or `undefined` when there is nothing to announce. Called once
44
+ * per session; failures are swallowed so the check never blocks or fails a
45
+ * launch.
46
+ */
47
+ readonly updateNotice?: () => Promise<string | undefined>;
23
48
  }
24
49
  export interface AutoRAGPiSession {
25
50
  readonly session: AgentSession;
26
51
  readonly baseToolNames: readonly string[];
27
52
  readonly sessionFile: string | undefined;
28
53
  }
54
+ /** Adapts a pi-agent-core {@link AgentTool} to pi's extension {@link ToolDefinition}. */
55
+ export declare function toToolDefinition(tool: AgentTool): ToolDefinition;
29
56
  /** Creates a pi session with AutoRAG's tools and prompt. */
30
57
  export declare function createAutoRAGPiSession(options: AutoRAGPiSessionOptions): Promise<AutoRAGPiSession>;
31
58
  export interface AutoRAGPiInteractiveRuntime {
@@ -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;
@@ -3,6 +3,7 @@ import { Type } from "typebox";
3
3
  import { type SimplexQueryState } from "../p2p/simplex-query-store.js";
4
4
  import type { SimplexTransport } from "../p2p/simplex-transport.js";
5
5
  import type { PeerQueryResponse } from "../p2p/wire.js";
6
+ import { EvidenceLedger } from "./evidence-ledger.js";
6
7
  export declare const QUERY_PEER_AGENT_TOOL_NAME = "query_peer_agent";
7
8
  declare const queryPeerAgentSchema: Type.TObject<{
8
9
  alias: Type.TString;
@@ -39,6 +40,8 @@ export interface QueryPeerAgentToolOptions {
39
40
  readonly sessionId?: () => string | undefined;
40
41
  readonly onResponse?: (state: SimplexQueryState, response: PeerQueryResponse) => void;
41
42
  readonly onExpired?: (state: SimplexQueryState) => void;
43
+ /** Run evidence ledger; each peer result is registered so the final emit can cite it by id. */
44
+ readonly ledger?: EvidenceLedger;
42
45
  }
43
46
  export interface QueryPeerAgentTool extends AgentTool<typeof queryPeerAgentSchema, QueryPeerAgentDetails> {
44
47
  readonly ready: Promise<void>;
@@ -0,0 +1,115 @@
1
+ import type { JevJudge } from "./jev-extension.js";
2
+ /**
3
+ * Where a user question is answered from:
4
+ * - `local`: anything needing information beyond the model's own knowledge —
5
+ * the user's files, chats, mail, or any fact the model cannot reliably recall.
6
+ * Local retrieval runs first; web search is left to the agent after the fast
7
+ * answer, when local evidence falls short.
8
+ * - `direct`: intrinsic knowledge or small talk the model answers on its own.
9
+ * - `config`: the user wants to inspect or change AutoRAG's own settings
10
+ * (model, providers, datasources). Offered only when the host enables
11
+ * agent self-configuration.
12
+ */
13
+ export type QueryRoute = "local" | "direct" | "config";
14
+ /** Jev question id of the intrinsic-knowledge / local branch. */
15
+ export declare const QUERY_ROUTE_QUESTION_ID = "route";
16
+ /** Jev question id of the "does this need decomposition?" check. */
17
+ export declare const DECOMPOSE_QUESTION_ID = "decompose";
18
+ /** Jev question id of the post-fast-answer "needs follow-up?" check. */
19
+ export declare const FOLLOW_UP_QUESTION_ID = "follow_up";
20
+ /** Route used whenever Jev gives no usable branch: today's local search. */
21
+ export declare const FALLBACK_QUERY_ROUTE: QueryRoute;
22
+ /** A `noul` probability at or above this asks for question decomposition. */
23
+ export declare const DECOMPOSE_PROBABILITY_THRESHOLD = 0.5;
24
+ /** A `noul` probability at or above this sends the fast answer on to verification. */
25
+ export declare const FOLLOW_UP_PROBABILITY_THRESHOLD = 0.5;
26
+ /**
27
+ * Minimum Jev branch probability required to leave local search. A `direct`
28
+ * branch at or below this floor — or one Jev reported without a probability —
29
+ * keeps the run on local search, the corpus-grounded default.
30
+ * Without the floor a weakly-favored `direct` verdict (observed at p 0.57-0.63
31
+ * on personal-corpus questions) skips retrieval entirely and answers from
32
+ * general knowledge, so the caller loses the evidence the question depends on.
33
+ */
34
+ export declare const NON_LOCAL_ROUTE_PROBABILITY_THRESHOLD = 0.75;
35
+ /** A `noul` probability at or above this searches that datasource before the fast answer. */
36
+ export declare const DATASOURCE_PROBABILITY_THRESHOLD = 0.5;
37
+ /** Jev question id of the "search this datasource?" check for one datasource. */
38
+ export declare function datasourceQuestionId(datasourceId: string): string;
39
+ export interface FollowUpDecision {
40
+ /** True when the run continues into the verification phase. */
41
+ readonly followUp: boolean;
42
+ /** Jev's P(follow-up needed), when it answered. */
43
+ readonly probability?: number;
44
+ /** Why the check fell back to verifying instead of following Jev; absent when Jev decided. */
45
+ readonly fallbackReason?: string;
46
+ }
47
+ /**
48
+ * Ask Jev whether the fast answer needs correction, clarification, or further
49
+ * research. Never throws: a missing credential, an unreachable backend, or a
50
+ * verdict with no probability keeps verifying, because ending early on an
51
+ * unchecked answer is the costlier mistake.
52
+ */
53
+ export declare function needsFollowUp(judge: JevJudge, query: string, answer: string): Promise<FollowUpDecision>;
54
+ export interface QueryRouteDecision {
55
+ /** Most probable branch; {@link FALLBACK_QUERY_ROUTE} when Jev gave none or its non-local branch missed {@link NON_LOCAL_ROUTE_PROBABILITY_THRESHOLD}. */
56
+ readonly route: QueryRoute;
57
+ /** True when Jev judged the question needs decomposition (never for `direct`). */
58
+ readonly decompose: boolean;
59
+ /** Probability Jev gave the winning branch, including a rejected non-local branch whose floor moved the route to local. */
60
+ readonly routeProbability?: number;
61
+ /** Jev's P(decomposition needed), when it answered. */
62
+ readonly decomposeProbability?: number;
63
+ /** Why the decision fell back instead of following Jev; absent when Jev decided. */
64
+ readonly fallbackReason?: string;
65
+ }
66
+ export interface RouteQueryOptions {
67
+ /** Offer the `config` branch: the agent may change its own settings. */
68
+ readonly selfConfig?: boolean;
69
+ }
70
+ /**
71
+ * Ask Jev, in one batched call about the user question, which branch answers
72
+ * it and whether it needs decomposition. Never throws: a missing credential,
73
+ * an unreachable backend, an unusable verdict, or a `direct` branch that does
74
+ * not clear {@link NON_LOCAL_ROUTE_PROBABILITY_THRESHOLD} falls back to a
75
+ * single local search, with the reason recorded.
76
+ */
77
+ export declare function routeQuery(judge: JevJudge, query: string, options?: RouteQueryOptions): Promise<QueryRouteDecision>;
78
+ /** One configured datasource Jev may send the question to. */
79
+ export interface DatasourceCandidate {
80
+ readonly datasourceId: string;
81
+ /** Content kind, e.g. `chat`, `mail`, `docs`. */
82
+ readonly type: string;
83
+ /** Operator- or connector-authored description of what the datasource holds. */
84
+ readonly description: string;
85
+ }
86
+ export interface DatasourceSelection {
87
+ /** Datasource ids to search, in registration order. */
88
+ readonly selected: readonly string[];
89
+ /** Jev's P(search needed) per datasource id, for every datasource it answered. */
90
+ readonly probabilities: Readonly<Record<string, number>>;
91
+ /** Why no datasource is searched instead of following Jev; absent when Jev decided. */
92
+ readonly fallbackReason?: string;
93
+ }
94
+ /** A similar question asked before, its results, and where each was found. */
95
+ export interface PastSearchHint {
96
+ readonly query: string;
97
+ /**
98
+ * Results it returned. `foundIn` names registered datasource ids, `local
99
+ * files`, or `web`; a title can also record that nothing was found there.
100
+ */
101
+ readonly results: readonly {
102
+ readonly title: string;
103
+ readonly foundIn: readonly string[];
104
+ }[];
105
+ }
106
+ /**
107
+ * Ask Jev, in one batched call, one `noul` per registered datasource: does
108
+ * answering the question need that datasource searched? The state describes
109
+ * every datasource (descriptions are flagged as non-exhaustive summaries), so
110
+ * Jev judges each one against the others, plus where similar past questions
111
+ * were answered, when retrieval memory has any. Never throws: a missing
112
+ * credential or an unreachable backend searches no datasource, which is the
113
+ * behavior without Jev.
114
+ */
115
+ export declare function selectDatasources(judge: JevJudge, query: string, datasources: readonly DatasourceCandidate[], pastSearches?: readonly PastSearchHint[]): Promise<DatasourceSelection>;
@@ -1,6 +1,7 @@
1
1
  import type { AgentTool } from "@earendil-works/pi-agent-core";
2
2
  import { Type } from "typebox";
3
3
  import type { RetrievalDiagnostic, RetrievalResult } from "../retrieval/types.js";
4
+ import { EvidenceLedger } from "./evidence-ledger.js";
4
5
  import { type SearchDocumentRetrievalTraceResult } from "./search-documents.js";
5
6
  export declare const SEARCH_ALL_DOCUMENTS_TOOL_NAME = "search_all_documents";
6
7
  declare const searchAllSchema: Type.TObject<{
@@ -30,10 +31,9 @@ export interface SearchAllDocumentsDetails {
30
31
  }
31
32
  /**
32
33
  * LLM-facing wrapper around multi-method merged retrieval. The
33
- * schema accepts only `{ query, topK?, scope? }`; datasource trust fields such
34
- * as `allowedTags`/`allowedScopes` are not part of the schema and are never
35
- * forwarded to the provider — only `query`, `topK`, and `scope` are passed
36
- * through, so model-provided extra properties cannot widen datasource access.
34
+ * schema accepts only `{ query, topK?, scope? }`; extra model-provided
35
+ * properties are not part of the schema and are never forwarded to the
36
+ * provider — only `query`, `topK`, and `scope` are passed through.
37
37
  */
38
- export declare function createSearchAllDocumentsTool(provider: SearchAllDocumentsProvider): AgentTool<typeof searchAllSchema, SearchAllDocumentsDetails>;
38
+ export declare function createSearchAllDocumentsTool(provider: SearchAllDocumentsProvider, ledger?: EvidenceLedger): AgentTool<typeof searchAllSchema, SearchAllDocumentsDetails>;
39
39
  export {};
@@ -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-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" | "missing-final-emit" | "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";
14
14
  export interface SearchDocumentDiagnostic {
15
15
  readonly code: SearchDocumentDiagnosticCode;
16
16
  readonly severity: SearchDocumentDiagnosticSeverity;
@@ -28,7 +28,6 @@ export interface SearchDocumentResult {
28
28
  readonly summary: string;
29
29
  readonly evidence: readonly SearchDocumentEvidence[];
30
30
  readonly confidence: number;
31
- readonly feedbackId: string;
32
31
  readonly source?: string;
33
32
  }
34
33
  /** One retrieval candidate captured in a run's retrieval trace. */
@@ -88,24 +87,17 @@ export type SearchDocumentsStreamEvent = {
88
87
  type SearchSession = {
89
88
  query: string;
90
89
  registry: Map<number, CuratedResult>;
91
- transient?: boolean;
92
90
  };
93
91
  type SearchSessions = Map<string, SearchSession>;
94
- type ReadonlySearchSessions = ReadonlyMap<string, {
95
- query: string;
96
- registry: ReadonlyMap<number, CuratedResult>;
97
- transient?: boolean;
98
- }>;
99
92
  /**
100
93
  * Build the preliminary (fast-phase) search response. Unlike
101
94
  * {@link recordStructuredResultsSession} this NEVER touches memory or the
102
- * feedback session registry — the final response owns those. Feedback ids are
103
- * namespaced with `:preliminary:` so they can never collide with final ids.
95
+ * session registry — the final response owns those.
104
96
  */
105
97
  export declare function createPreliminarySearchDocumentsResponse(sessionId: string, query: string, details: AutoRAGFastAnswerDetails, diagnostics?: readonly SearchDocumentDiagnostic[]): SearchDocumentsResponse;
106
98
  export declare function createEmptySearchDocumentsResponse(sessionId: string, query: string, sessions: SearchSessions, diagnostics?: readonly SearchDocumentDiagnostic[]): SearchDocumentsResponse;
107
99
  export declare function recordStructuredResultsSession(sessionId: string, query: string, details: AutoRAGResultsDetails, sessions: SearchSessions, memory: RetrievalMemory, componentDiagnostics?: readonly SearchDocumentDiagnostic[], options?: {
100
+ /** Record the session registry only, skipping the retrieval-memory write. */
108
101
  readonly isolateMemory?: boolean;
109
102
  }): SearchDocumentsResponse;
110
- export declare function recordNumberedFeedback(sessions: ReadonlySearchSessions, memory: RetrievalMemory, sessionId: string, usefulNumbers: readonly number[], notUsefulNumbers: readonly number[]): void;
111
103
  export {};
@@ -1,6 +1,7 @@
1
1
  import type { AgentTool } from "@earendil-works/pi-agent-core";
2
2
  import { Type } from "typebox";
3
3
  import type { MinSyncVectorMethod } from "../minsync/method.js";
4
+ import { EvidenceLedger } from "./evidence-ledger.js";
4
5
  import { type SearchDocumentRetrievalTraceResult } from "./search-documents.js";
5
6
  export declare const SEARCH_MINSYNC_DOCUMENTS_TOOL_NAME = "semantic_search_local_docs";
6
7
  declare const searchMinSyncSchema: Type.TObject<{
@@ -12,16 +13,15 @@ export interface SearchMinSyncDocumentsDetails {
12
13
  readonly method: "semantic_search_local_docs";
13
14
  readonly resultCount: number;
14
15
  readonly sources: readonly string[];
15
- readonly available: boolean;
16
16
  /** Top candidates in traceable shape (additive; used for the run's retrieval trace). */
17
17
  readonly results?: readonly SearchDocumentRetrievalTraceResult[];
18
18
  }
19
19
  /**
20
20
  * LLM-facing wrapper around the {@link MinSyncVectorMethod} vector
21
21
  * retrieval. The model can only supply `query`, `topK`, and an opaque `scope`.
22
- * When the method is missing, the binary is missing, or retrieval errors, the
23
- * tool returns a path-free unavailable message with `available: false` and a
24
- * zero result count — never a real binary or workspace path.
22
+ * MinSync is required, so a missing binary or a failed query is not turned
23
+ * into an "unavailable" result: the error propagates with its own message and
24
+ * the harness reports it as a failed tool call.
25
25
  */
26
- export declare function createSearchMinSyncDocumentsTool(getMethod: () => MinSyncVectorMethod | undefined, resolveScope?: (scope: string | undefined) => string | undefined): AgentTool<typeof searchMinSyncSchema, SearchMinSyncDocumentsDetails>;
26
+ export declare function createSearchMinSyncDocumentsTool(getMethod: () => MinSyncVectorMethod, resolveScope?: (scope: string | undefined) => string | undefined, ledger?: EvidenceLedger): AgentTool<typeof searchMinSyncSchema, SearchMinSyncDocumentsDetails>;
27
27
  export {};