@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
55 lines (54 loc) • 2.66 kB
TypeScript
/**
* Shared string-distance helpers for "did you mean?" suggestions.
*
* Extracted from toolCallRepair.ts, which had the only implementation, so
* provider-name validation can reuse it rather than carry a second copy.
*/
/**
* Longest string the distance primitive will compare.
*
* Exported so every call site can apply the same limit *before* calling
* `levenshtein` — skipping an over-limit operand entirely, rather than
* comparing a truncated prefix of it. Truncating silently merged any two
* strings that happened to share their first `MAX_COMPARABLE_LENGTH`
* characters into distance 0, which let a direct MCP tool-name lookup
* (`resolveToolName`) resolve to the wrong tool for a long, colliding name.
*/
export declare const MAX_COMPARABLE_LENGTH = 128;
/**
* Compute Levenshtein edit distance between two strings.
* Uses the iterative matrix approach — O(m*n) time, O(min(m,n)) space.
*
* Throws rather than truncating when either input exceeds
* `MAX_COMPARABLE_LENGTH`: silently comparing truncated prefixes produces a
* *wrong* distance (two distinct strings sharing a long prefix collapse to
* distance 0) instead of no distance, which is worse than refusing outright.
* Callers that want fuzzy matching over long input must apply the length
* check themselves and skip the comparison — see `suggestClosest` below and
* `resolveToolName`/`rankToolNameCandidates` in toolCallRepair.ts.
*/
export declare function levenshtein(a: string, b: string): number;
/**
* Candidates within `maxDistance` edits of `input`, closest first.
*
* Ties break on the candidate's own order in `candidates`, so a caller that
* passes canonical names before aliases gets the canonical one suggested.
* Comparison is case-insensitive; the returned strings keep their original
* casing so they can be pasted back verbatim.
*
* `input` longer than `MAX_COMPARABLE_LENGTH` is rejected outright (no
* suggestions), and any individual candidate over the same limit is skipped
* rather than compared — never truncated. Truncating either side risks
* exactly the false distance-0 match `levenshtein`'s guard rejects: two
* distinct strings sharing a long-enough prefix would otherwise look
* identical and "suggest" the wrong one.
*
* @param input - The string the user actually typed
* @param candidates - Valid values, most-preferred first
* @param options.maxDistance - Edit budget (default 3)
* @param options.limit - Most suggestions to return (default 3)
*/
export declare function suggestClosest(input: string, candidates: readonly string[], options?: {
maxDistance?: number;
limit?: number;
}): string[];