OpenViSTAI · Agents · Blockchain · Crypto
Menu
OPENVIST RECIPES

Find case-insensitive collisions in tool names with JavaScript

JavaScript

Audit tool identifiers under an explicit local ASCII naming convention and report collisions after lowercase normalization.

JavaScript code excerpt: Find case-insensitive collisions in tool names with JavaScript. Version 0.1.0. Read the full recipe for code, sources and recorded test scope.

Audit a small JSON array of tool names using a local ASCII convention. Normalize accepted names to lowercase and report one-based positions for collisions. This does not execute tools or validate a provider-specific naming policy.

Before you start

  • Save as audit-tools.cjs and run with Node.js 22: node audit-tools.cjs. Supply one JSON array through stdin, then signal EOF. No CLI arguments or help option are accepted.
  • Uses only node:fs, solely for bounded, read-only reads from stdin. Reads at most 65537 bytes and rejects input exceeding 65536 bytes before JSON parsing.
  • Decodes strict UTF-8 with global TextDecoder and fatal:true. Native JSON.parse syntax rules apply, including rejection of a preserved leading BOM.
  • Accepts only strings of 1–64 ASCII characters: an initial letter followed by letters, digits, underscores or hyphens. An empty array is valid.
  • Successful output is one JSON object containing normalized names in original order and collisions sorted by ASCII name, with ascending one-based positions. Map-based counting safely handles constructor and prototype.
  • Valid input exits 0 without stderr. Invalid arguments, stdin errors or invalid input exit 2 with a generic diagnostic on stderr and no stdout, traceback or input values.

Build and check

  1. Use Node.js 22. Save the CommonJS example as audit-tools.cjs.
  2. Save a UTF-8 JSON array of names as names.json, at most 65536 bytes.
  3. Run: node audit-tools.cjs < names.json
  4. Inspect normalized names and collision positions. Resolve collisions before integrating the names with your own application.

Limits to understand

  • This is an audit under a local naming convention, not a guarantee of compatibility with any AI provider. It does not execute tools.
  • The entire parsed input and generated output are held in memory. Stdin can block until EOF.
  • Successful output contains names, which may be sensitive.
  • Output-write failures are outside the input-validation error guarantee.
  • Use the provider-specific documentation separately when integrating a real tool API.

Run it

node audit-tools.cjs < names.json

Example input

["Lookup","lookup","Send"]

Expected output

{"normalized":["lookup","lookup","send"],"collisions":[{"name":"lookup","positions":[1,2]}]}
INSPECT THE SCRIPT

Inspect, copy and run the documented checks.

This browser preview builds code locally. It does not contact an API or run the code.

Default example ready.

JavaScript example
'use strict';

const fs = require('node:fs');
let output;

try {
  if (process.argv.length !== 2) {
    throw new Error('Invalid input');
  }

  const limit = 65536;
  const buffer = Buffer.alloc(limit + 1);
  let used = 0;

  while (used < buffer.length) {
    const count = fs.readSync(0, buffer, used, buffer.length - used, null);
    if (count === 0) break;
    used += count;
    if (used > limit) {
      throw new Error('Invalid input');
    }
  }

  // Preserve a BOM so JSON.parse applies its native JSON syntax rules.
  const decoder = new TextDecoder('utf-8', {
    fatal: true,
    ignoreBOM: true
  });
  const input = JSON.parse(decoder.decode(buffer.subarray(0, used)));
  if (!Array.isArray(input)) {
    throw new Error('Invalid input');
  }

  const convention = /^[A-Za-z][A-Za-z0-9_-]{0,63}$/;
  const normalized = [];
  const positionsByName = new Map();

  for (let i = 0; i < input.length; i++) {
    const name = input[i];
    if (typeof name !== 'string') {
      throw new Error('Invalid input');
    }
    const match = convention.exec(name);
    // JavaScript's $ can match before a final newline; require a full match.
    if (match === null || match[0] !== name) {
      throw new Error('Invalid input');
    }

    const lower = name.toLowerCase();
    normalized.push(lower);
    if (!positionsByName.has(lower)) {
      positionsByName.set(lower, []);
    }
    positionsByName.get(lower).push(i + 1);
  }

  const collisions = [];
  for (const [name, positions] of positionsByName) {
    if (positions.length >= 2) {
      collisions.push({ name, positions });
    }
  }
  collisions.sort((a, b) => a.name < b.name ? -1 : a.name > b.name ? 1 : 0);
  output = JSON.stringify({ normalized, collisions }) + '\n';
} catch {
  process.stderr.write('error: invalid arguments, stdin, UTF-8, JSON, or tool names.\n');
  process.exit(2);
}

// Output failures are deliberately outside the input-validation handler.
process.stdout.write(output);
What to verify after running
  • For the supplied example, lookup collides at positions 1 and 2.
  • Inspect the naming convention and compare it with your application requirements.
  • Handle exit code 2 as invalid input or arguments. Successful output contains the names.

Request or format preview

Illustrative preview. No provider response, price or balance is fetched.

Change a setting to inspect the preview.

Official sources and related profiles

    Code license: MIT. Keep the license notice with your copy.

    Example version 0.1.0 · Documentation reviewed 2026-10-14.

    Six independent CLI fixtures and ten curated supplementary checks passed in pinned offline Node.js 22 Docker, including stdin read errors and leading-BOM rejection. These checks do not establish exhaustive correctness or compatibility with any tool provider.