@juspay/neurolink
Version:
The pipe layer of an AI nervous system: one interface connecting provider neurons to your application, across three inference types — generate, stream and decide. `decide` returns typed, calibrated judgements from a non-generative model (~400ms, ~$0.00002
70 lines (69 loc) • 3.71 kB
TypeScript
/**
* Artifact reading primitives shared by every backend and every reader.
*
* Two readers exist — the model's `retrieve_context({ artifactId })` and the
* host's `readArtifact()` — and two shipped backends. Everything they agree
* on lives here so it is agreed on exactly once:
*
* - `readArtifactWindow` is THE paged read. It asks a backend for a window
* when the backend can produce one (`retrieveRange`), and otherwise reads
* the whole payload and slices. A reader never has to know which.
* - `searchArtifactContent` is the literal search over an artifact. It
* returns bounded snippets with character offsets, never whole lines:
* an MCP artifact is usually one compact JSON line, so "the matching line"
* would be the payload the search was meant to avoid reading.
* - `isSafeArtifactId` is the shape check every backend applies before an
* id reaches a path or a key. Ids arrive from the model.
*
* @module artifacts/artifactReader
*/
import type { ArtifactPageRequest, ArtifactSearchResult, ArtifactStore, ArtifactWindow } from "../types/index.js";
/** Characters used for the quick preview embedded in surrogate results. */
export declare const DEFAULT_PREVIEW_CHARS = 500;
/** Matches returned by one artifact search; the rest are counted, not sent. */
export declare const MAX_ARTIFACT_SEARCH_MATCHES = 50;
/** Longest search pattern accepted — bounds the work per call. */
export declare const MAX_SEARCH_PATTERN_CHARS = 200;
/** True when `id` is shaped like something a backend may look up. */
export declare function isSafeArtifactId(id: string): boolean;
/** Head slice of a payload for surrogate headers, ellipsised when cut. */
export declare function generateArtifactPreview(payload: string, chars?: number): string;
/** Cut one window out of a payload already in memory. */
export declare function sliceArtifactWindow(content: string, page?: ArtifactPageRequest): ArtifactWindow;
/**
* Read one window of an artifact through whatever the backend supports.
*
* With a `page` and a backend that implements `retrieveRange`, only the
* window crosses the wire. Otherwise the whole payload is fetched and cut
* here. Without a `page` the whole payload is always fetched — a caller that
* omits the window is asking for the artifact.
*
* Returns `null` when the id is unknown, unsafe, or expired.
*/
export declare function readArtifactWindow(store: ArtifactStore, id: string, page?: ArtifactPageRequest): Promise<ArtifactWindow | null>;
/**
* Why a search pattern cannot be used, or `undefined` when it can.
*
* Empty would match at every position; over-long bounds the scan. Both are
* reported to the model rather than silently ignored — the whole point of
* the artifact search is that "search did not happen" is never invisible.
*/
export declare function validateSearchPattern(pattern: string): string | undefined;
/**
* Literal, case-insensitive search over an artifact.
*
* Regex metacharacters in `pattern` are matched literally — the model's
* input is never compiled as a regex, so it cannot be made catastrophic.
* Each hit carries the character `offset` of the match (what to pass back as
* `offset` for a targeted read), its 1-based line, and a bounded snippet.
*
* Scanning starts at `from`, so a caller can walk a long payload by passing
* `nextSearchOffset` back in. Every match after `from` is counted in
* `totalMatches`; only the first `maxMatches` are returned.
*
* `pattern` must already have passed {@link validateSearchPattern}.
*/
export declare function searchArtifactContent(content: string, pattern: string, options?: {
from?: number;
maxMatches?: number;
}): ArtifactSearchResult;