@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
56 lines (55 loc) • 3.09 kB
TypeScript
/**
* Pure index-filtering + prompt-index formatting helpers.
*
* Matching semantics are ported from curator's battle-tested
* `searchSkillsFromIndex`: case-insensitive substring match on
* name/displayName/description, optional tag filter on top, scope filter
* that always admits global skills, and active-only visibility.
*/
import type { SkillDefinition, SkillIndexItem, SkillSearchQuery } from "../types/index.js";
/** Strip instructions from a full definition to form an index entry. */
export declare function toSkillIndexItem(skill: SkillDefinition): SkillIndexItem;
/**
* Sort index entries by name (byte order, locale-independent) so every
* listing renders byte-identically across calls and store backends.
* Store enumeration order (Redis SCAN, fs.readdir, S3 listings) is not
* stable — an unsorted listing would shuffle between calls and invalidate
* provider prompt caches. Returns a new array.
*/
export declare function sortSkillIndex(items: SkillIndexItem[]): SkillIndexItem[];
/** Filter index entries by query/tag/scope. Active skills only. */
export declare function filterSkillIndex(items: SkillIndexItem[], query: SkillSearchQuery): SkillIndexItem[];
/**
* Reject resource paths that could escape a skill's namespace: absolute
* paths, traversal segments, and empty segments. The manager validates
* before reaching any store — this is defense in depth for stores whose
* keys are built by concatenation (S3, Redis) or path joining.
*/
export declare function isSafeSkillResourcePath(resourcePath: string): boolean;
/**
* Whether a skill is visible from the calling scope. Fails closed, matching
* `filterSkillIndex`: a scoped skill is hidden unless the caller supplies a
* `scopeId` that the skill explicitly lists. Omitting `scopeId` therefore
* yields global skills only — it must never expose a scoped skill by name
* through `use_skill` / `read_skill_resource` (#1139).
*/
export declare function isSkillVisibleInScope(skill: Pick<SkillDefinition, "scope" | "scopeIds">, scopeId?: string): boolean;
/**
* Render the `<available_skills>` block embedded in the use_skill tool
* description ("tool" discovery mode). One line per skill — name,
* description, tags — instructions never appear here.
*
* Budget handling is uniform and stateless: over budget, every
* description drops to its first sentence, then to a hard 80-char cap.
* The render is a pure function of the (sorted) index, so the tool
* description stays byte-identical across calls — a prerequisite for
* provider prompt caching. Names are never dropped.
*/
export declare function renderSkillListing(items: SkillIndexItem[], budgetChars: number): string | null;
/**
* Render the compact skills index appended to the system prompt
* ("system-prompt" discovery mode). Names + descriptions only —
* instructions are never included; the model loads them via use_skill.
* Returns null when nothing is visible so callers can skip injection.
*/
export declare function formatSkillsPromptIndex(items: SkillIndexItem[], maxItems: number): string | null;