Skip to main content

Overview

The NAVAI frontend package provides utilities for working with route definitions. These functions enable fuzzy route resolution and generate formatted route descriptions for agent instructions.

Import

import { 
  resolveNavaiRoute, 
  getNavaiRoutePromptLines,
  type NavaiRoute 
} from '@navai/voice-frontend';
type NavaiRoute = {
  name: string;        // Route identifier (e.g., "profile", "settings")
  path: string;        // Actual URL path (e.g., "/profile", "/settings")
  description: string; // Human-readable description
  synonyms?: string[]; // Alternative names (e.g., ["perfil", "account"])
};

Example

const route: NavaiRoute = {
  name: 'profile',
  path: '/user/profile',
  description: 'User profile page with account information',
  synonyms: ['perfil', 'account', 'my account', 'mi cuenta']
};

resolveNavaiRoute

Resolves a user input string to a route path using fuzzy matching.

Signature

function resolveNavaiRoute(
  input: string,
  routes?: NavaiRoute[]
): string | null

Parameters

input
string
required
User input to match against routes. Can be:
  • Route path: "/profile", "/settings"
  • Route name: "profile", "settings"
  • Synonym: "perfil", "account"
  • Partial match: "prof", "sett"
Input is normalized (lowercased, accents removed) before matching.
routes
NavaiRoute[]
Array of route definitions to search. Defaults to empty array.

Return Value

result
string | null
  • Returns the matched route’s path if found
  • Returns null if no match is found

Matching Strategy

The function uses a multi-level matching strategy:
  1. Exact path match: Input exactly matches a route’s path
  2. Exact name match: Input exactly matches a route’s name
  3. Exact synonym match: Input exactly matches any route synonym
  4. Partial name match: Input is contained in a route’s name
  5. Partial synonym match: Input is contained in any route synonym
Note: All comparisons are case-insensitive and accent-insensitive.

Examples

const routes: NavaiRoute[] = [
  {
    name: 'home',
    path: '/',
    description: 'Home page'
  },
  {
    name: 'profile',
    path: '/user/profile',
    description: 'User profile',
    synonyms: ['perfil', 'account', 'mi cuenta']
  },
  {
    name: 'settings',
    path: '/settings',
    description: 'Application settings',
    synonyms: ['config', 'preferences', 'ajustes']
  }
];

// Exact path match
resolveNavaiRoute('/settings', routes);
// => '/settings'

// Exact name match
resolveNavaiRoute('profile', routes);
// => '/user/profile'

// Exact synonym match
resolveNavaiRoute('perfil', routes);
// => '/user/profile'

resolveNavaiRoute('ajustes', routes);
// => '/settings'

// Partial name match
resolveNavaiRoute('prof', routes);
// => '/user/profile'

resolveNavaiRoute('sett', routes);
// => '/settings'

// Partial synonym match
resolveNavaiRoute('cuenta', routes);  // matches 'mi cuenta'
// => '/user/profile'

// Case insensitive
resolveNavaiRoute('PROFILE', routes);
// => '/user/profile'

resolveNavaiRoute('Perfil', routes);
// => '/user/profile'

// Accent insensitive
resolveNavaiRoute('configuración', routes);  // synonym is 'config'
// Note: This won't match 'config', accents are removed from input
resolveNavaiRoute('ajustes', routes);
// => '/settings'

// No match
resolveNavaiRoute('dashboard', routes);
// => null

resolveNavaiRoute('unknown', routes);
// => null

Usage in Navigation

function handleVoiceNavigation(userInput: string, routes: NavaiRoute[]) {
  const path = resolveNavaiRoute(userInput, routes);
  
  if (path) {
    router.push(path);
    return `Navigating to ${path}`;
  } else {
    return `Sorry, I couldn't find a route matching "${userInput}"`;
  }
}

// User says: "go to profile"
handleVoiceNavigation('profile', routes);
// Navigates to '/user/profile'

// User says: "abre ajustes" (Spanish)
handleVoiceNavigation('ajustes', routes);
// Navigates to '/settings'

getNavaiRoutePromptLines

Generates formatted route descriptions for agent instructions.

Signature

function getNavaiRoutePromptLines(
  routes?: NavaiRoute[]
): string[]

Parameters

routes
NavaiRoute[]
Array of route definitions to format. Defaults to empty array.

Return Value

result
string[]
Array of formatted route description strings, one per route.Format: "- {name} ({path})[, aliases: {synonyms}]"

Examples

const routes: NavaiRoute[] = [
  {
    name: 'home',
    path: '/',
    description: 'Home page'
  },
  {
    name: 'profile',
    path: '/user/profile',
    description: 'User profile',
    synonyms: ['perfil', 'account']
  },
  {
    name: 'settings',
    path: '/settings',
    description: 'Settings page',
    synonyms: ['config', 'preferences', 'ajustes']
  }
];

const lines = getNavaiRoutePromptLines(routes);

console.log(lines);
// [
//   "- home (/)",
//   "- profile (/user/profile), aliases: perfil, account",
//   "- settings (/settings), aliases: config, preferences, ajustes"
// ]

// Format as instructions
const instructions = [
  'Allowed routes:',
  ...lines
].join('\n');

console.log(instructions);
// Allowed routes:
// - home (/)
// - profile (/user/profile), aliases: perfil, account
// - settings (/settings), aliases: config, preferences, ajustes

Usage with buildNavaiAgent

import { buildNavaiAgent, getNavaiRoutePromptLines } from '@navai/voice-frontend';

const routes: NavaiRoute[] = [
  {
    name: 'dashboard',
    path: '/dashboard',
    description: 'Main dashboard',
    synonyms: ['home', 'inicio']
  },
  {
    name: 'analytics',
    path: '/analytics',
    description: 'Analytics and reports',
    synonyms: ['reports', 'stats', 'estadísticas']
  }
];

// The agent automatically uses getNavaiRoutePromptLines internally
const { agent } = await buildNavaiAgent({
  navigate: (path) => router.push(path),
  routes,
  functionModuleLoaders: {},
  baseInstructions: `
You are a helpful assistant.

Available routes:
${getNavaiRoutePromptLines(routes).join('\n')}
  `.trim()
});

Complete Example

import { 
  resolveNavaiRoute, 
  getNavaiRoutePromptLines,
  type NavaiRoute 
} from '@navai/voice-frontend';
import { useNavigate } from 'react-router-dom';

// Define routes with multilingual support
const routes: NavaiRoute[] = [
  {
    name: 'home',
    path: '/',
    description: 'Home page',
    synonyms: ['inicio', 'main', 'principal']
  },
  {
    name: 'profile',
    path: '/user/profile',
    description: 'User profile and account settings',
    synonyms: ['perfil', 'account', 'cuenta', 'my account', 'mi cuenta']
  },
  {
    name: 'messages',
    path: '/messages',
    description: 'Messages and chat',
    synonyms: ['chat', 'mensajes', 'inbox']
  },
  {
    name: 'settings',
    path: '/settings',
    description: 'Application settings and preferences',
    synonyms: ['config', 'configuration', 'ajustes', 'preferences', 'preferencias']
  },
  {
    name: 'help',
    path: '/help',
    description: 'Help and documentation',
    synonyms: ['ayuda', 'docs', 'documentation', 'support']
  }
];

function VoiceNavigationHandler() {
  const navigate = useNavigate();
  
  const handleVoiceCommand = (command: string) => {
    // Try to resolve the route
    const path = resolveNavaiRoute(command, routes);
    
    if (path) {
      console.log(`Navigating to ${path}`);
      navigate(path);
      return true;
    } else {
      console.warn(`No route found for: ${command}`);
      return false;
    }
  };
  
  // Test various commands
  handleVoiceCommand('profile');      // => '/user/profile'
  handleVoiceCommand('perfil');       // => '/user/profile'
  handleVoiceCommand('mi cuenta');    // => '/user/profile'
  handleVoiceCommand('settings');     // => '/settings'
  handleVoiceCommand('ajustes');      // => '/settings'
  handleVoiceCommand('help');         // => '/help'
  handleVoiceCommand('ayuda');        // => '/help'
  handleVoiceCommand('dashboard');    // => null (not found)
  
  return null;
}

// Generate instructions for agent
function generateAgentInstructions() {
  const routeLines = getNavaiRoutePromptLines(routes);
  
  return `
You are a voice assistant for a web application.

Available routes:
${routeLines.join('\n')}

When the user asks to navigate, use the navigate_to tool with one of these route names or paths.
  `.trim();
}

console.log(generateAgentInstructions());
// You are a voice assistant for a web application.
//
// Available routes:
// - home (/), aliases: inicio, main, principal
// - profile (/user/profile), aliases: perfil, account, cuenta, my account, mi cuenta
// - messages (/messages), aliases: chat, mensajes, inbox
// - settings (/settings), aliases: config, configuration, ajustes, preferences, preferencias
// - help (/help), aliases: ayuda, docs, documentation, support
//
// When the user asks to navigate, use the navigate_to tool with one of these route names or paths.

Normalization Details

Both functions use the same normalization for consistent matching:
function normalize(value: string): string {
  return value
    .normalize("NFD")                    // Decompose accented characters
    .replace(/[\u0300-\u036f]/g, "")    // Remove accent marks
    .trim()                              // Remove whitespace
    .toLowerCase();                      // Convert to lowercase
}
Examples:
  • "Profile""profile"
  • "Configuración""configuracion"
  • "Mi Cuenta""mi cuenta"
  • " Settings ""settings"

Source Reference

  • resolveNavaiRoute: packages/voice-frontend/src/routes.ts:16
  • getNavaiRoutePromptLines: packages/voice-frontend/src/routes.ts:35
  • NavaiRoute: packages/voice-frontend/src/routes.ts:1

Build docs developers (and LLMs) love