{"id":47748560,"url":"https://github.com/aeryflux/xenova-bridge","last_synced_at":"2026-04-03T02:07:16.638Z","repository":{"id":342222556,"uuid":"1171998395","full_name":"aeryflux/xenova-bridge","owner":"aeryflux","description":"Natural language interface bridge between users and AeryFlux components","archived":false,"fork":false,"pushed_at":"2026-03-22T03:56:24.000Z","size":57,"stargazers_count":1,"open_issues_count":1,"forks_count":0,"subscribers_count":0,"default_branch":"main","last_synced_at":"2026-03-22T18:56:02.459Z","etag":null,"topics":["entity-extraction","intent-classification","nlp","transformers","typescript","xenova"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/@aeryflux/xenova-bridge","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/aeryflux.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2026-03-03T20:54:28.000Z","updated_at":"2026-03-22T03:56:27.000Z","dependencies_parsed_at":null,"dependency_job_id":null,"html_url":"https://github.com/aeryflux/xenova-bridge","commit_stats":null,"previous_names":["aeryflux/xenova-bridge"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/aeryflux/xenova-bridge","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aeryflux%2Fxenova-bridge","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aeryflux%2Fxenova-bridge/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aeryflux%2Fxenova-bridge/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aeryflux%2Fxenova-bridge/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/aeryflux","download_url":"https://codeload.github.com/aeryflux/xenova-bridge/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/aeryflux%2Fxenova-bridge/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":31327053,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-03T01:42:14.489Z","status":"online","status_checked_at":"2026-04-03T02:00:06.642Z","response_time":107,"last_error":null,"robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":true,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["entity-extraction","intent-classification","nlp","transformers","typescript","xenova"],"created_at":"2026-04-03T02:07:11.742Z","updated_at":"2026-04-03T02:07:16.633Z","avatar_url":"https://github.com/aeryflux.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# @aeryflux/xenova-bridge\n\n[![npm version](https://img.shields.io/npm/v/@aeryflux/xenova-bridge.svg)](https://www.npmjs.com/package/@aeryflux/xenova-bridge)\n[![npm downloads](https://img.shields.io/npm/dm/@aeryflux/xenova-bridge.svg)](https://www.npmjs.com/package/@aeryflux/xenova-bridge)\n![License](https://img.shields.io/badge/license-MIT-green.svg)\n\nNatural language interface bridge between users and AeryFlux components.\n\n## Overview\n\nXenova Bridge provides intent classification, entity extraction, and action dispatching for natural language commands in AeryFlux applications. It acts as the \"passerelle\" (bridge) between user input and the functional components (globe, modes, music, challenges).\n\n## Features\n\n- **Intent Classification**: Classifies user input into categories (navigation, search, playback, configure, challenge, info)\n- **Entity Extraction**: Extracts structured entities (countries, modes, genres, themes, languages)\n- **Action Dispatching**: Translates intents and entities into executable component actions\n- **Multilingual Support**: English, French, Spanish, German\n- **Context-Aware**: Boosts classification confidence based on current app state\n- **Zero External API**: Runs entirely locally using pattern matching and embeddings\n\n## Architecture\n\n```\n┌─────────────────────────────────────────────────────────────────┐\n│                      User Input                                 │\n│            \"show weather in Japan\" / \"joue du jazz\"            │\n└─────────────────────────┬───────────────────────────────────────┘\n                          │\n                          ▼\n┌─────────────────────────────────────────────────────────────────┐\n│                    IntentEngine                                 │\n│  - Pattern matching (multilingual)                              │\n│  - Embedding similarity (optional)                              │\n│  - Context boosting                                             │\n│  → Output: ClassifiedIntent { category, confidence, subIntent } │\n└─────────────────────────┬───────────────────────────────────────┘\n                          │\n                          ▼\n┌─────────────────────────────────────────────────────────────────┐\n│                   EntityExtractor                               │\n│  - Country detection (ISO codes)                                │\n│  - Mode detection (news, music, weather, wiki, challenge)       │\n│  - Genre detection (rock, jazz, electronic...)                  │\n│  - Theme detection (dark, green, white)                         │\n│  → Output: ExtractedEntity[]                                    │\n└─────────────────────────┬───────────────────────────────────────┘\n                          │\n                          ▼\n┌─────────────────────────────────────────────────────────────────┐\n│                   ActionDispatcher                              │\n│  - Maps intent + entities to actions                            │\n│  - Generates globe:rotate, mode:switch, music:play, etc.        │\n│  - Priority-based ordering                                      │\n│  → Output: BridgeAction[]                                       │\n└─────────────────────────┬───────────────────────────────────────┘\n                          │\n                          ▼\n┌─────────────────────────────────────────────────────────────────┐\n│                   CommandResult                                 │\n│  { success, intent, entities, actions, feedback, suggestions } │\n└─────────────────────────────────────────────────────────────────┘\n```\n\n## Installation\n\n```bash\nnpm install @aeryflux/xenova-bridge\n```\n\nPeer dependency (optional):\n```bash\nnpm install @xenova/transformers\n```\n\n## Usage\n\n### Basic Usage\n\n```typescript\nimport { XenovaBridge, processCommand } from '@aeryflux/xenova-bridge';\n\n// Using the singleton (recommended)\nconst result = await processCommand('show weather in Japan', {\n  currentMode: 'news',\n  currentTheme: 'dark',\n  language: 'en',\n});\n\nconsole.log(result.intent.category);  // 'navigation'\nconsole.log(result.entities);          // [{ type: 'country', normalizedValue: 'JP' }, ...]\nconsole.log(result.actions);           // [{ type: 'mode:switch', payload: { mode: 'weather' } }, ...]\n```\n\n### Custom Instance\n\n```typescript\nimport { XenovaBridge } from '@aeryflux/xenova-bridge';\n\nconst bridge = new XenovaBridge({\n  debug: true,\n  intentThreshold: 0.7,\n  entityThreshold: 0.6,\n  apiBaseUrl: 'http://localhost:3000',\n});\n\nconst result = await bridge.process('play jazz music from France', context);\n```\n\n### Intent Classification Only\n\n```typescript\nimport { IntentEngine } from '@aeryflux/xenova-bridge';\n\nconst engine = new IntentEngine();\nconst intent = await engine.classify('go to Japan');\n\nconsole.log(intent.category);    // 'navigation'\nconsole.log(intent.confidence);  // 0.85\n```\n\n### Entity Extraction Only\n\n```typescript\nimport { EntityExtractor } from '@aeryflux/xenova-bridge';\n\nconst extractor = new EntityExtractor();\nconst entities = extractor.extract('play rock music in Germany');\n\n// Returns: [\n//   { type: 'genre', value: 'rock', normalizedValue: 'rock' },\n//   { type: 'country', value: 'Germany', normalizedValue: 'DE' }\n// ]\n```\n\n## API Reference\n\n### Types\n\n#### `IntentCategory`\n```typescript\ntype IntentCategory =\n  | 'navigation'  // \"go to\", \"show\", \"open\"\n  | 'search'      // \"find\", \"search\", \"where is\"\n  | 'playback'    // \"play\", \"pause\", \"next\"\n  | 'configure'   // \"set theme\", \"change language\"\n  | 'challenge'   // \"start quiz\", \"harder\"\n  | 'info'        // \"what is\", \"tell me about\"\n  | 'unknown';\n```\n\n#### `EntityType`\n```typescript\ntype EntityType =\n  | 'country'     // ISO 3166-1 alpha-2 code\n  | 'mode'        // ModeId (news, music, weather, wiki, challenge)\n  | 'genre'       // Music genre\n  | 'theme'       // ThemeId (dark, green, white)\n  | 'language'    // LanguageId (en, fr, es, de)\n  | 'direction'   // Navigation (left, right, zoom in/out)\n  | 'quantity';   // Numbers\n```\n\n#### `ActionType`\n```typescript\ntype ActionType =\n  // Globe\n  | 'globe:rotate'\n  | 'globe:zoom'\n  | 'globe:select-country'\n  | 'globe:reset'\n  // Mode\n  | 'mode:switch'\n  | 'mode:refresh'\n  // Drawer\n  | 'drawer:open-left'\n  | 'drawer:open-right'\n  | 'drawer:close'\n  // Music\n  | 'music:play'\n  | 'music:pause'\n  | 'music:next'\n  | 'music:filter-genre'\n  // Config\n  | 'config:set-theme'\n  | 'config:set-language'\n  // Challenge\n  | 'challenge:start'\n  // Search\n  | 'search:execute';\n```\n\n### Classes\n\n#### `XenovaBridge`\nMain orchestrator class.\n\n| Method | Description |\n|--------|-------------|\n| `process(input, context)` | Full pipeline: classify → extract → dispatch |\n| `quickCheck(input)` | Intent classification only |\n| `extractEntities(input)` | Entity extraction only |\n| `updateConfig(config)` | Update configuration |\n| `clearCaches()` | Clear embedding cache |\n\n#### `IntentEngine`\nIntent classification.\n\n| Method | Description |\n|--------|-------------|\n| `classify(input, context?)` | Classify intent with optional context |\n| `clearCache()` | Clear embedding cache |\n| `updateConfig(config)` | Update configuration |\n\n#### `EntityExtractor`\nEntity extraction.\n\n| Method | Description |\n|--------|-------------|\n| `extract(input)` | Extract all entities |\n| `extractByType(input, type)` | Extract entities of specific type |\n| `extractFirst(input, type)` | Get first entity of type |\n| `hasEntity(input, type)` | Check if entity type exists |\n\n## Multilingual Examples\n\n| Language | Command | Intent | Entities |\n|----------|---------|--------|----------|\n| EN | \"show weather in Japan\" | navigation | mode:weather, country:JP |\n| FR | \"montre la météo au Japon\" | navigation | mode:weather, country:JP |\n| ES | \"muestra el tiempo en Japón\" | navigation | mode:weather, country:JP |\n| DE | \"zeige Wetter in Japan\" | navigation | mode:weather, country:JP |\n| EN | \"play jazz music\" | playback | genre:jazz |\n| FR | \"joue du rock\" | playback | genre:rock |\n| EN | \"dark mode\" | configure | theme:dark |\n| FR | \"mode sombre\" | configure | theme:dark |\n\n## Contributing\n\nSee [CONTRIBUTING.md](./CONTRIBUTING.md) for development setup, PR guidelines,\nand areas where help is welcome.\n\n## Changelog\n\nSee [CHANGELOG.md](./CHANGELOG.md) for a detailed history of changes.\n\n## Testing\n\n```bash\nnpm test\n```\n\n## Configuration\n\n| Option | Type | Default | Description |\n|--------|------|---------|-------------|\n| `intentThreshold` | number | 0.6 | Minimum confidence for intent classification |\n| `entityThreshold` | number | 0.5 | Minimum confidence for entity extraction |\n| `useLocalEmbeddings` | boolean | true | Use Pythagoras embeddings API for ambiguous cases |\n| `apiBaseUrl` | string | 'http://localhost:3000' | Pythagoras API URL |\n| `debug` | boolean | false | Enable debug logging |\n\n## Extending\n\n### Adding Custom Patterns\n\n```typescript\nimport { INTENT_PATTERNS, MODE_PATTERNS } from '@aeryflux/xenova-bridge';\n\n// Add custom intent keywords\nINTENT_PATTERNS.navigation.push('aller vers', 'navigate to');\n\n// Add custom mode patterns\nMODE_PATTERNS.music.push('playlist', 'audio');\n```\n\n### Adding Custom Countries\n\n```typescript\nimport { COUNTRY_MAPPINGS } from '@aeryflux/xenova-bridge';\n\n// Add country variations\nCOUNTRY_MAPPINGS['nippon'] = 'JP';\nCOUNTRY_MAPPINGS['helvetia'] = 'CH';\n```\n\n## License\n\nMIT - AeryFlux. See [LICENSE](./LICENSE) for full text.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faeryflux%2Fxenova-bridge","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Faeryflux%2Fxenova-bridge","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Faeryflux%2Fxenova-bridge/lists"}