@autorag/librarian 2.10.0 → 2.10.1

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/LICENSE +195 -21
  2. package/NOTICE +17 -21
  3. package/README.md +335 -161
  4. package/dist/agent/agent.d.ts +67 -2
  5. package/dist/agent/context-token-guard.d.ts +23 -0
  6. package/dist/agent/jev-extension.d.ts +5 -4
  7. package/dist/agent/jikji-find-tool.d.ts +1 -0
  8. package/dist/agent/pi-session.d.ts +35 -2
  9. package/dist/agent/request-limits.d.ts +20 -0
  10. package/dist/agent/search-all-tool.d.ts +1 -0
  11. package/dist/agent/search-single-datasource-tool.d.ts +1 -0
  12. package/dist/cli/config.d.ts +13 -11
  13. package/dist/cli/index.js +2573 -800
  14. package/dist/cloud/config.d.ts +18 -0
  15. package/dist/cloud/jev-backend.d.ts +90 -0
  16. package/dist/core.js +2185 -418
  17. package/dist/datasource/crawler-skill.d.ts +17 -0
  18. package/dist/datasource/sidecar/config.d.ts +26 -0
  19. package/dist/datasource/sidecar/descriptors.d.ts +67 -0
  20. package/dist/datasource/sidecar/fusion.d.ts +25 -0
  21. package/dist/datasource/sidecar/index.d.ts +131 -0
  22. package/dist/datasource/sidecar/methods.d.ts +27 -0
  23. package/dist/datasource/types.d.ts +3 -1
  24. package/dist/embedding-runtime/index.d.ts +6 -6
  25. package/dist/embedding-runtime/manifest.d.ts +0 -12
  26. package/dist/embedding-runtime/types.d.ts +1 -1
  27. package/dist/index.js +2210 -439
  28. package/dist/mcp/index.js +2205 -438
  29. package/dist/minsync/client.d.ts +3 -3
  30. package/dist/minsync/installer.d.ts +1 -1
  31. package/dist/minsync/process.d.ts +1 -0
  32. package/dist/minsync/types.d.ts +1 -1
  33. package/dist/parser/defaults.d.ts +6 -4
  34. package/dist/parser/ocr-engines.d.ts +6 -0
  35. package/dist/retrieval/index.d.ts +1 -1
  36. package/dist/retrieval/rerank.d.ts +20 -3
  37. package/licenses/embedding-assets.json +0 -35
  38. package/package.json +24 -27
  39. package/skills/autorag/SKILL.md +1 -1
  40. package/skills/autorag-doctor/SKILL.md +1 -1
  41. package/skills/autorag-lite-setup/SKILL.md +2 -2
  42. package/skills/autorag-setup/SKILL.md +2 -2
  43. package/licenses/gemma-notice.txt +0 -24
  44. package/licenses/gemma-section-3.2-flow-down.txt +0 -9
  45. package/licenses/gemma-terms-of-use.html +0 -4750
  46. package/licenses/gemma-terms-of-use.txt +0 -158
@@ -1,5 +1,5 @@
1
1
  import type { Agent, AgentTool } from "@earendil-works/pi-agent-core";
2
- import type { Api, Model } from "@earendil-works/pi-ai";
2
+ import type { Api, ImageContent, Model } from "@earendil-works/pi-ai";
3
3
  import type { DatasourceIndexResult, DatasourceSkill } from "../datasource/types.js";
4
4
  import { type DupeyCliOptions } from "../dupey/index.js";
5
5
  import { type Embedder } from "../embedding-runtime/gateway-embedder.js";
@@ -356,6 +356,16 @@ export declare class AutoRAGAgent {
356
356
  private lastQuery;
357
357
  private lastSessionId;
358
358
  private activeRun;
359
+ /**
360
+ * Steering state of the running search. A TUI query runs detached from pi's
361
+ * input loop (pi reads the next input only after its input handler returns),
362
+ * so input typed meanwhile steers this run (Enter) or waits behind it
363
+ * (Alt+Enter), the way pi steers its own turns. {@link steer} feeds the same
364
+ * state for `searchDocuments()` / `searchDocumentsStream()` callers.
365
+ */
366
+ private readonly interactive;
367
+ /** Aborted by {@link abort} and by the run's timeout: gates publishing and the run's own requests. */
368
+ private activeRunAbort;
359
369
  private modelNativeSearchAuth;
360
370
  private retrievalTrace;
361
371
  /** Evidence every retrieval tool returned this run; the answer's inline `[eN]` citations resolve against it. */
@@ -470,8 +480,36 @@ export declare class AutoRAGAgent {
470
480
  private currentSystemPromptConfig;
471
481
  subscribe(listener: Parameters<Agent["subscribe"]>[0]): () => void;
472
482
  createPiInteractiveRuntime(): Promise<AutoRAGPiInteractiveRuntime>;
483
+ /**
484
+ * The session's custom tools, with retrieval and web reads interruptible by a
485
+ * steer: stopping them loses no side effect. bash and the file tools are pi
486
+ * built-ins and never pass through here.
487
+ */
488
+ private steerableTools;
489
+ /**
490
+ * Lets a steer cut a retrieval tool short, like an interruptible wait in pi:
491
+ * the tool's signal also aborts on the steer, and the call resolves at once
492
+ * with a skipped result telling the model to retry if the search still
493
+ * matters, so the steer reaches the model before the next request.
494
+ */
495
+ private interruptibleBySteer;
473
496
  /** Resolve the model's inline `[eN]` citations against this run's evidence and derive the structured results. */
474
497
  private deriveAnswer;
498
+ /**
499
+ * Routes one TUI input the way pi routes typed input for its own turns. With
500
+ * no search running it starts one. During a search, Enter steers it (the
501
+ * user is correcting a search that is going wrong) and Alt+Enter queues a
502
+ * follow-up question that runs once this search answers.
503
+ */
504
+ private routeInteractiveInput;
505
+ /**
506
+ * Esc and Alt+Enter during a search. pi handles both itself while a turn
507
+ * streams (abort, queue follow-up); between phases it ignores Esc and submits
508
+ * Alt+Enter like Enter, so AutoRAG acts on them there.
509
+ */
510
+ private handleInteractiveKey;
511
+ /** Runs one TUI query detached from pi's input loop, then any follow-ups queued behind it. */
512
+ private startInteractiveQuery;
475
513
  /**
476
514
  * Drives one TUI query through the two-phase search. The model's own
477
515
  * assistant messages (progress notes before a tool call, the fast answer,
@@ -480,7 +518,31 @@ export declare class AutoRAGAgent {
480
518
  * twice and put it in the model's context twice.
481
519
  */
482
520
  private runInteractivePiQuery;
521
+ /** Resolves once the TUI search and every follow-up queued behind it finished. */
522
+ waitForIdle(): Promise<void>;
523
+ /**
524
+ * Steers the running `searchDocuments()` / `searchDocumentsStream()` search,
525
+ * the way Enter steers a TUI search: `text` is a correction of the search in
526
+ * progress, not a new question. It reaches the search's next model request
527
+ * (also between phases, where no turn streams), cuts in-flight retrieval and
528
+ * the baseline prefetch short so it lands promptly, and forces the
529
+ * verification phase, whose prompt restates it. A steer that lands after
530
+ * verification's last request gets one more verification turn in the same
531
+ * search. The final answer stays the answer to the original question.
532
+ *
533
+ * Returns false, and does nothing, when no search is running, the search was
534
+ * stopped, or it is past its last model request; the caller should then ask
535
+ * the text as a new question.
536
+ */
537
+ steer(text: string, images?: readonly ImageContent[]): boolean;
538
+ /**
539
+ * Stops the running search as a whole: the streaming model turn, the
540
+ * baseline prefetch, in-flight retrieval, and every later phase. The search
541
+ * then resolves without a verified answer.
542
+ */
483
543
  abort(): void;
544
+ /** The next model request took the queued steers into the transcript; later retrieval runs uninterrupted until the next steer. */
545
+ private steersReachedModel;
484
546
  /**
485
547
  * Periodically re-runs the incremental {@link refresh} so parsed mirrors and
486
548
  * indexes stay current. Re-parsing is incremental (mtime/size) via the
@@ -604,7 +666,7 @@ export declare class AutoRAGAgent {
604
666
  * against it; the model then verifies with thinking on and ends with the
605
667
  * final answer as a plain reply, returning only the delta.
606
668
  */
607
- buildRefinementPrompt(query: string, options: RetrievalOptions, fastAnswer: string | undefined, fastAnswerDelivered: boolean): string;
669
+ buildRefinementPrompt(query: string, options: RetrievalOptions, fastAnswer: string | undefined, fastAnswerDelivered: boolean, steers?: readonly string[]): string;
608
670
  buildSearchPrompt(query: string, options: RetrievalOptions, initialRetrievalContext?: string): string;
609
671
  refresh(force?: boolean, opts?: AutoRAGRefreshOptions): Promise<AutoRAGRefreshResult>;
610
672
  /**
@@ -679,6 +741,7 @@ export declare class AutoRAGAgent {
679
741
  findJikji(query: string, opts?: {
680
742
  readonly topK?: number;
681
743
  readonly first?: boolean;
744
+ readonly signal?: AbortSignal;
682
745
  }): Promise<JikjiFindProviderResult>;
683
746
  /**
684
747
  * Merge per-root answer packs into one. Concatenates answer_paths/candidates
@@ -723,6 +786,7 @@ export declare class AutoRAGAgent {
723
786
  searchAllDocuments(query: string, options?: {
724
787
  readonly topK?: number;
725
788
  readonly scope?: string;
789
+ readonly signal?: AbortSignal;
726
790
  }): Promise<{
727
791
  results: RetrievalResult[];
728
792
  diagnostics: RetrievalDiagnostic[];
@@ -740,6 +804,7 @@ export declare class AutoRAGAgent {
740
804
  searchSingleDatasourceDocuments(datasourceId: string, query: string, options?: {
741
805
  readonly topK?: number;
742
806
  readonly scope?: string;
807
+ readonly signal?: AbortSignal;
743
808
  }): Promise<{
744
809
  results: RetrievalResult[];
745
810
  diagnostics: RetrievalDiagnostic[];
@@ -0,0 +1,23 @@
1
+ import type { AgentMessage } from "@earendil-works/pi-agent-core";
2
+ import type { Model } from "@earendil-works/pi-ai";
3
+ type ContextTokenGuardModel = Model<any> | (() => Model<any> | undefined) | undefined;
4
+ /**
5
+ * Compose an optional context transform with the aggregate token guard. The
6
+ * guard runs on the final transcript immediately before each provider request,
7
+ * so it sees the system prompt, tool declarations, user query, memory context,
8
+ * and every prior tool result.
9
+ */
10
+ export declare function createContextTokenGuardedTransform(model: ContextTokenGuardModel, base?: (messages: AgentMessage[]) => Promise<AgentMessage[]>, fixedOverheadTokens?: () => number): (messages: AgentMessage[]) => Promise<AgentMessage[]>;
11
+ /**
12
+ * Keep complete retrieval candidates while the assembled request fits the
13
+ * model budget. Removing a per-chunk cut is only safe because this drops whole
14
+ * lower-ranked candidates (with an explicit marker) instead of hiding text.
15
+ */
16
+ export declare function guardAgentContextMessages(model: Model<any> | undefined, messages: AgentMessage[], useReportedUsage?: boolean, fixedOverheadTokens?: number): AgentMessage[];
17
+ /**
18
+ * Estimate the current transcript with pi-coding-agent's conservative chars/4
19
+ * counter. `useReportedUsage` adds the last assistant turn's provider-reported
20
+ * usage for the settled prefix; pass false when the messages were just edited.
21
+ */
22
+ export declare function estimateContextMessageTokens(messages: readonly AgentMessage[], useReportedUsage?: boolean): number;
23
+ export {};
@@ -4,9 +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.
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.
8
9
  */
9
- export type JevBackendName = "typesafe" | "openrouter" | "vercel";
10
+ export type JevBackendName = "typesafe" | "openrouter" | "vercel" | "autorag";
10
11
  /**
11
12
  * OpenRouter's live Jev model id. `jev-use` 0.8.0 ships `typesafe/jev-latest`,
12
13
  * which OpenRouter rejects with HTTP 400 ("Model ... does not exist"), so the
@@ -51,8 +52,8 @@ export type JevJudge = (state: State, questions: Question[], options?: {
51
52
  /**
52
53
  * Builds the Jev judge shared by the `jev` tool and the query router. The
53
54
  * `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.
55
+ * resolves at construction time, and the per-backend model default (the
56
+ * OpenRouter pin, or `jev-1.13` on the hosted plan) applies to every caller.
56
57
  */
57
58
  export declare function createJevJudge(options?: JevJudgeOptions): JevJudge;
58
59
  /**
@@ -44,6 +44,7 @@ export interface JikjiFindProvider {
44
44
  findJikji(query: string, opts?: {
45
45
  readonly topK?: number;
46
46
  readonly first?: boolean;
47
+ readonly signal?: AbortSignal;
47
48
  }): Promise<JikjiFindProviderResult>;
48
49
  }
49
50
  export interface JikjiFindDetails {
@@ -1,5 +1,5 @@
1
1
  import type { AgentMessage, AgentTool } from "@earendil-works/pi-agent-core";
2
- import type { Api, Model } from "@earendil-works/pi-ai";
2
+ import type { Api, ImageContent, Model } from "@earendil-works/pi-ai";
3
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
5
  /**
@@ -34,10 +34,43 @@ export interface AutoRAGPiSessionOptions {
34
34
  readonly remoteSession?: boolean;
35
35
  readonly contextTransform?: (messages: AgentMessage[]) => Promise<AgentMessage[]>;
36
36
  }
37
+ /**
38
+ * How AutoRAG takes one interactive input. `steer` while a pi turn streams
39
+ * returns the text pi should queue as steering (pi delivers it before the
40
+ * turn's next model request); every other outcome is fully handled by AutoRAG.
41
+ */
42
+ export type AutoRAGInputDisposition = {
43
+ readonly kind: "handled";
44
+ } | {
45
+ readonly kind: "steer";
46
+ readonly text: string;
47
+ };
48
+ export interface AutoRAGInteractiveInput {
49
+ readonly text: string;
50
+ readonly images: readonly ImageContent[] | undefined;
51
+ /** pi's delivery for input typed while a turn streams; undefined when no turn streams. */
52
+ readonly streamingBehavior: "steer" | "followUp" | undefined;
53
+ }
54
+ /** A TUI key AutoRAG acts on itself while a search runs, even when no pi turn streams. */
55
+ export type AutoRAGInteractiveKey = "interrupt" | "followUp";
37
56
  export interface AutoRAGPiInteractiveRuntimeOptions extends Omit<AutoRAGPiSessionOptions, "model"> {
38
57
  readonly model?: Model<Api>;
39
58
  readonly inactiveToolNames?: readonly string[];
40
- readonly onQuery: (query: string, pi: ExtensionAPI) => void | Promise<void>;
59
+ /**
60
+ * Routes one interactive input: a new query, a steer of the running search,
61
+ * or a follow-up queued behind it. Must not wait for a search to finish:
62
+ * pi's TUI reads the next input only after this returns.
63
+ */
64
+ readonly onInput: (input: AutoRAGInteractiveInput, pi: ExtensionAPI) => AutoRAGInputDisposition;
65
+ /** Whether a search is running: while it is, every interactive input belongs to it. */
66
+ readonly isSearchRunning?: () => boolean;
67
+ /**
68
+ * Called for pi's interrupt (Esc) and follow-up (Alt+Enter) keys while a
69
+ * search runs. pi acts on them only while a turn streams, but a search also
70
+ * spends time between turns (routing, prefetch, checks). Return true to
71
+ * consume the key; pi then never sees it.
72
+ */
73
+ readonly onKey?: (key: AutoRAGInteractiveKey) => boolean;
41
74
  /**
42
75
  * Optional best-effort provider for a startup update notice. Resolves to the
43
76
  * notice text, or `undefined` when there is nothing to announce. Called once
@@ -0,0 +1,20 @@
1
+ import type { AgentMessage } from "@earendil-works/pi-agent-core";
2
+ import type { ModelInputLimits } from "@earendil-works/pi-ai";
3
+ /** Stands in for an image dropped from a model request by {@link fitRequestLimits}. */
4
+ export declare const IMAGE_OMITTED_NOTE = "[Image omitted from this request to stay within the model provider's request limits. Read the file again if you still need to see it.]";
5
+ /**
6
+ * Fits a model request into the provider's declared `inputLimits`.
7
+ *
8
+ * pi keeps every image a tool returned in the transcript and resends all of
9
+ * them on each later turn, but it never enforces `maxRequestBytes` or
10
+ * `images.maxPerRequest`. A search that reads a handful of photos therefore
11
+ * grows past a provider's body limit and the request fails outright (the hosted
12
+ * AutoRAG API answers HTTP 413). Images are what grows the body, so the oldest
13
+ * ones are replaced with {@link IMAGE_OMITTED_NOTE} until the request fits; the
14
+ * newest images, which the model is looking at, go last. Text is never touched.
15
+ *
16
+ * The size is the serialized transcript, a close lower bound of the provider
17
+ * body, so `maxRequestBytes` should keep headroom below the hard limit.
18
+ * Returns undefined when the request already fits; never mutates `messages`.
19
+ */
20
+ export declare function fitRequestLimits(messages: readonly AgentMessage[], limits: ModelInputLimits | undefined): AgentMessage[] | undefined;
@@ -18,6 +18,7 @@ export interface SearchAllDocumentsProvider {
18
18
  searchAllDocuments(query: string, options?: {
19
19
  readonly topK?: number;
20
20
  readonly scope?: string;
21
+ readonly signal?: AbortSignal;
21
22
  }): Promise<SearchAllDocumentsResult>;
22
23
  }
23
24
  export interface SearchAllDocumentsDetails {
@@ -39,6 +39,7 @@ export interface SingleDatasourceSearchProvider {
39
39
  searchSingleDatasourceDocuments(datasourceId: string, query: string, options?: {
40
40
  readonly topK?: number;
41
41
  readonly scope?: string;
42
+ readonly signal?: AbortSignal;
42
43
  }): Promise<{
43
44
  readonly results: readonly RetrievalResult[];
44
45
  readonly diagnostics: readonly RetrievalDiagnostic[];
@@ -55,13 +55,14 @@ export interface WebSearchCliConfig {
55
55
  }
56
56
  /**
57
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`).
58
+ * it explicitly. Secrets never appear here: `jev-use` reads the backend
59
+ * credential from its own environment variable (`TYPESAFE_API_KEY`,
60
+ * `OPENROUTER_API_KEY`, or `AI_GATEWAY_API_KEY`), and the hosted AutoRAG
61
+ * `autorag` backend reads `AUTORAG_API_KEY`.
61
62
  */
62
63
  export interface JevCliConfig {
63
64
  enabled?: boolean;
64
- /** Force one backend; omit to let the first credential present win. */
65
+ /** Force one backend (`openrouter`, `typesafe`, `vercel`, or `autorag`); omit to let the first credential present win. */
65
66
  backend?: JevBackendName;
66
67
  /** Model id sent with every call, e.g. `jev-latest`. */
67
68
  model?: string;
@@ -75,20 +76,21 @@ export interface QueryDecompositionConfig {
75
76
  }
76
77
  /**
77
78
  * Post-merge reranking config. Routes merged evidence through a dedicated
78
- * rerank model. `provider` is `openrouter` today; `model` is the OpenRouter
79
- * wire id (default `voyageai/rerank-3-lite`). Secrets never appear here — only
80
- * the environment-variable name that holds the provider API key.
79
+ * rerank model. `provider` is `openrouter` (default) or the hosted AutoRAG
80
+ * plan (`autorag`); each provider supplies its own default `model` and
81
+ * `apiKeyEnv`. Secrets never appear here — only the environment-variable name
82
+ * that holds the provider API key.
81
83
  */
82
84
  export interface RerankConfig {
83
85
  /** `false` disables reranking. Missing means enabled when the block is present. */
84
86
  enabled?: boolean;
85
- /** Provider id. @default "openrouter" */
87
+ /** Provider id (`openrouter` or `autorag`). @default "openrouter" */
86
88
  provider?: string;
87
- /** Wire model id. @default "voyageai/rerank-3-lite" */
89
+ /** Wire model id. @default "voyageai/rerank-3-lite" (`openrouter`) / "qwen/qwen3-reranker-8b" (`autorag`) */
88
90
  model?: string;
89
- /** Environment variable holding the provider API key. @default "OPENROUTER_API_KEY" */
91
+ /** Environment variable holding the provider API key. @default "OPENROUTER_API_KEY" (`openrouter`) / "AUTORAG_API_KEY" (`autorag`) */
90
92
  apiKeyEnv?: string;
91
- /** Override the provider base URL (e.g. a gateway). */
93
+ /** Override the provider base URL (e.g. a gateway); for `autorag`, the API base including `/v1`. */
92
94
  baseUrl?: string;
93
95
  /** Return only the top N merged results. @default 25 (DEFAULT_RERANK_TOP_N) */
94
96
  topN?: number;