/** * Options controlling {@link tokenizeWithOptions}. All default off except * `camelCase`. * * - `distinct` - drop duplicate tokens (first occurrence wins). * - `lowerCase` - lowercase every token. * - `capitalize` - upper-case each token's first letter (then * {@link TOKENIZE_OVERRIDES} fix up `ai` -> `AI`, `fs` -> `FS`, and * `v2` -> `V2`). * - `omitUriScheme` - strip a leading `scheme://` before tokenizing. * - `omitEmailDomain` - keep only the local part of an email. * - `camelCase` - split on camelCase boundaries / digit runs / acronyms * (default `true`); when `false`, split only on non-alphanumerics. */ export type TokenizeOptions = { distinct?: boolean; lowerCase?: boolean; capitalize?: boolean; omitUriScheme?: boolean; omitEmailDomain?: boolean; camelCase?: boolean; }; /** * Tokenization and overflow controls for lowercase keys and slugs. The default * length is unlimited; overflow uses a six-character hash unless overridden. */ export type KeyOptions = Omit & { maxLength?: number; truncateStrategy?: "hash" | "trim" | "empty"; truncateHashLength?: number; }; /** {@link KeyOptions} plus the token delimiter used by identifier generation. */ export type IdentifierOptions = KeyOptions & { delimiter?: string; }; /** Leading and trailing blank-line handling for {@link dedent}. */ export type DedentOptions = { /** Remove leading blank lines after indentation normalization. Defaults to `true`. */ trimStart?: boolean; /** * Remove trailing blank lines after indentation normalization. Defaults to `true`. */ trimEnd?: boolean; /** Remove spaces and tabs from each line end. Defaults to `true`. */ trimLineEnd?: boolean; }; /** Yield normalized tokens using explicit casing, URI, email, and deduplication rules. */ export declare function tokenizeWithOptions(options: TokenizeOptions, ...values: unknown[]): Generator; /** Yield normalized tokens using the default tokenization rules. */ export declare function tokenize(...values: unknown[]): Generator; /** * Join tokenized values with `delimiter`. When the next token would push the * result over `maxLength`: `trim` stops adding; `empty` returns `""`; `hash` * appends a digest of accepted tokens plus the overflow token if the result * still fits, otherwise `""`. */ export declare function toIdentifierWithOptions(options: IdentifierOptions, ...values: unknown[]): string; /** Convert arbitrary values into a normalized camel-case identifier. */ export declare function toIdentifier(...values: unknown[]): string; /** * Slugified identifier: same rules as {@link toIdentifierWithOptions} with the * delimiter forced to `-`. Accepts {@link KeyOptions} so callers cannot * override the delimiter. */ export declare function toSlugWithOptions(options: KeyOptions, ...values: unknown[]): string; /** Convert arbitrary values into a normalized hyphen-delimited slug. */ export declare function toSlug(...values: unknown[]): string; /** * Trim `value` and return `null` for non-strings, `undefined`, or * strings that are empty after trimming. Lets call sites collapse the * common * * ```ts * typeof v === "string" && v.trim() ? v.trim() : null * ``` * * dance into a single helper. Useful for HTTP header / query / form * extractors where downstream code wants `string | null` to drive a * cheap `??` / `if (x)` cascade. */ export declare function trimToNull(value: unknown): string | null; /** Trim `value` and return `undefined` when no non-empty string remains. */ export declare function trimToUndefined(value: unknown): string | undefined; /** * Normalize a config list that may arrive as an array or as a single * comma/whitespace-separated string: split, apply `transform`, drop empties, * and de-duplicate (first occurrence wins). * * This is the shape every allow-list / fallback-order setting in this repo * takes, because the same value can come from typed config (`string[]`) or from * an environment variable (`"a, b c"`). Pass `transform` to normalize entries * as they are read; it defaults to trimming. * * @example * parseList("docs.example.com, *.databricks.com"); * parseList(process.env.MODEL_FALLBACKS); * parseList(raw, normalizeUrlPattern); */ export declare function parseList(raw: string | readonly string[] | undefined | null, transform?: (entry: string) => string): string[]; /** * {@link trimToNull} with an empty-string miss instead of `null`, for callers * that build a string unconditionally and treat "absent" as "". * * Reading loosely-typed JSON is the motivating case: a field that should be a * string may be missing or the wrong type, and the caller wants `""` rather * than a null check at every access. * * @example * const title = trimToEmpty(record.title); // always a string */ export declare function trimToEmpty(value: unknown): string; /** * Trim the first usable string out of `value`. Returns `null` when * `value` is `undefined`, `null`, an empty string, or an array whose * first string member is empty. Mirrors how Express / Node header * accessors expose single vs. repeated headers - the first * non-empty entry wins, everything else is ignored. */ export declare function firstNonEmpty(value: unknown): string | null; /** * Escape the five characters significant in HTML text and * double-quoted attribute values (`&`, `<`, `>`, `"`, `'`) so an * untrusted string can be interpolated into markup without breaking * out of its context. `&` is replaced first so ampersands introduced * by the later replacements aren't double-escaped. */ export declare function escapeHtml(value: string): string; /** * Slugify `value` (using the standard {@link toIdentifierWithOptions} * tokenizer + delimiter rules) and **always** suffix a short * deterministic hash. Use when you need a stable, slugified id that * is guaranteed to be unique across descriptions sharing the same * leading tokens (tool ids, cache keys, etc.). * * Behaviour differs from `toIdentifierWithOptions({ maxLength, * truncateStrategy: "hash" })`: that helper only appends a hash when * the slug *overflows* `maxLength`. This helper appends a hash * unconditionally so the result is collision-resistant even for * short inputs. The hash is computed over the raw `value` so two * descriptions producing the same slug still get different ids. * * @param value - Source string (typically a tool/agent description). * @param options.delimiter - Token separator (default `"_"`). * @param options.slugMaxLength - Cap on the slug portion (the part * before the hash). Default 32. * @param options.hashLength - Length of the suffix produced by * {@link fnvHashWithOptions} (Crockford-style base-32 alphabet, max 7 * chars). Default 6. * @param options.fallbackPrefix - Prefix used when the slug is empty * (e.g. punctuation-only input). Default `"id"`. */ export declare function toUniqueSlug(value: string, options?: { delimiter?: string; slugMaxLength?: number; hashLength?: number; fallbackPrefix?: string; }): string; /** * A node in the description tree consumed by {@link toDescription}. * * - `string` - a text paragraph. * - `Description[]` - a sequence of stacked blocks at the same level * (no list markers). Plain text adjacent to a list (either direction) * flushes together so the prose reads as a lead-in or trailing * summary. Two text paragraphs, two adjacent lists, and anything * touching a map get a blank-line break. * - `{ bullets: [...] }` / `{ numbered: [...] }` - explicit list. A * list of one bare string drops its marker (`-` / `1.`); a list of * one item with nested children keeps its marker as the visual anchor * for the indented children. * - any other object - headers map: each key becomes a `Header:` line * followed by a blank line and the rendered value. */ export type Description = string | readonly Description[] | { readonly [key: string]: Description; }; /** * Format a nested description tree as a Markdown-ish string suitable * for an LLM system prompt, Zod `.describe()` block, Mastra tool * description, or any other long-form text destination. * * Every string section is dedented (common leading whitespace stripped), * right-trimmed line by line, and freed of leading / trailing blank * lines, so callers can write multi-line template literals indented * naturally in source without leaking that indentation into the * consumer-facing output. Plain-string inputs flow through unchanged * apart from the same normalization pass, so a single multi-line * template literal works directly: * * ```ts * toDescription(` * Ask the Genie space "${alias}" a question. * Pass the answer through as-is. * `); * // Ask the Genie space "default" a question. * // Pass the answer through as-is. * * toDescription([ * ` * Ask the Genie space a question. * Phrase it from the user's perspective. * `, * { bullets: [ * ["Pass the answer through as-is", { numbered: ["item", "item"] }], * ]}, * { Instructions: "Reply with the SQL only." }, * ]); * // Ask the Genie space a question. * // Phrase it from the user's perspective. * // - Pass the answer through as-is * // 1. item * // 2. item * // * // Instructions: * // * // Reply with the SQL only. * ``` * * See {@link Description} for the node grammar. */ export declare function toDescription(node: Description): string; /** * Right-strip every line, remove common indentation, and optionally trim * leading and trailing blank lines. Whitespace-only lines normalize to empty * lines, matching common dedent implementations. */ export declare function dedentLines(text: string, options?: DedentOptions): string[]; /** Join {@link dedentLines}, trimming leading and trailing blank lines by default. */ export declare function dedent(text: string, options?: DedentOptions): string; /** * Format a count with its noun, pluralizing (naive `+s`) unless the count is 1: * `pluralize(1, "barrel")` -> `"1 barrel"`, `pluralize(3, "barrel")` -> * `"3 barrels"`. Collapses the `${n} noun${n === 1 ? "" : "s"}` idiom. */ export declare function pluralize(count: number, noun: string): string; /** * Title-case a snake / kebab / camel identifier into a human-readable label: * tokenize (lowercased, capitalized), then join with spaces. Falls back to * the raw `value` when it yields no tokens (e.g. punctuation-only input). * `bge_large_en` -> `"Bge Large En"`, `promptId` -> `"Prompt Id"`. * * The single source of truth for the "humanize a column / field name" idiom - * reused by the chat data-grid headers and the export renderer. Extra * {@link TokenizeOptions} (e.g. `camelCase: false`) merge over the defaults. */ export declare function toLabel(value: string, options?: TokenizeOptions): string; /** * Upper-case the first character of `value`, leaving the rest untouched. * `"working"` -> `"Working"`. Collapses the * `s.charAt(0).toUpperCase() + s.slice(1)` idiom. */ export declare function capitalize(value: string): string;