Full Code of leon-ai/leon for AI

develop 877bea14777c cached
1078 files
18.2 MB
1.9M tokens
3816 symbols
1 requests
Download .txt
Showing preview only (7,554K chars total). Download the full file or copy to clipboard to get everything.
Repository: leon-ai/leon
Branch: develop
Commit: 877bea14777c
Files: 1078
Total size: 18.2 MB

Directory structure:
gitextract_onovndeo/

├── .changelogrc
├── .editorconfig
├── .env.sample
├── .github/
│   ├── CODE_OF_CONDUCT.md
│   ├── CONTRIBUTING.md
│   ├── FUNDING.yml
│   ├── ISSUE_TEMPLATE/
│   │   ├── BUG.md
│   │   ├── DOCS.md
│   │   ├── FEATURE_REQUEST.md
│   │   ├── IMPROVEMENT.md
│   │   └── QUESTION.md
│   ├── PULL_REQUEST_TEMPLATE.md
│   └── workflows/
│       ├── build.yml
│       ├── lint.yml
│       ├── pre-release-nodejs-bridge.yml
│       ├── pre-release-python-bridge.yml
│       ├── pre-release-tcp-server.yml
│       └── tests.yml
├── .gitignore
├── .gitpod.yml
├── .husky/
│   ├── commit-msg
│   └── pre-commit
├── .lintstagedrc
├── .npmrc
├── .nvmrc
├── CHANGELOG.md
├── LICENSE.md
├── README.md
├── app/
│   ├── src/
│   │   ├── css/
│   │   │   ├── style.scss
│   │   │   └── voice-energy/
│   │   │       ├── base.scss
│   │   │       ├── idle.scss
│   │   │       ├── listening.scss
│   │   │       ├── main.scss
│   │   │       ├── processing.scss
│   │   │       └── talking.scss
│   │   ├── custom-aurora-components/
│   │   │   ├── index.ts
│   │   │   └── timer/
│   │   │       ├── index.ts
│   │   │       └── timer.tsx
│   │   ├── index.html
│   │   └── js/
│   │       ├── chatbot.js
│   │       ├── client.js
│   │       ├── constants.js
│   │       ├── init.jsx
│   │       ├── listener.js
│   │       ├── main.js
│   │       ├── onkeydown.js
│   │       ├── recorder.js
│   │       ├── render-aurora-component.js
│   │       ├── suggestion-handler.js
│   │       ├── tool-ui-handler.js
│   │       └── voice-energy.js
│   └── vite.config.js
├── bin/
│   ├── cmake/
│   │   └── versions.json
│   ├── llama.cpp/
│   │   └── versions.json
│   ├── ninja/
│   │   └── versions.json
│   └── pytorch/
│       └── versions.json
├── bridges/
│   ├── nodejs/
│   │   ├── .npmrc
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── constants.ts
│   │   │   ├── main.ts
│   │   │   ├── sdk/
│   │   │   │   ├── aurora/
│   │   │   │   │   ├── button.ts
│   │   │   │   │   ├── card.ts
│   │   │   │   │   ├── checkbox.ts
│   │   │   │   │   ├── circular-progress.ts
│   │   │   │   │   ├── flexbox.ts
│   │   │   │   │   ├── form.ts
│   │   │   │   │   ├── icon-button.ts
│   │   │   │   │   ├── icon.ts
│   │   │   │   │   ├── image.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── input.ts
│   │   │   │   │   ├── link.ts
│   │   │   │   │   ├── list-header.ts
│   │   │   │   │   ├── list-item.ts
│   │   │   │   │   ├── list.ts
│   │   │   │   │   ├── loader.ts
│   │   │   │   │   ├── progress.ts
│   │   │   │   │   ├── radio-group.ts
│   │   │   │   │   ├── radio.ts
│   │   │   │   │   ├── range-slider.ts
│   │   │   │   │   ├── scroll-container.ts
│   │   │   │   │   ├── select-option.ts
│   │   │   │   │   ├── select.ts
│   │   │   │   │   ├── status.ts
│   │   │   │   │   ├── switch.ts
│   │   │   │   │   ├── tab-content.ts
│   │   │   │   │   ├── tab-group.ts
│   │   │   │   │   ├── tab-list.ts
│   │   │   │   │   ├── tab.ts
│   │   │   │   │   ├── text.ts
│   │   │   │   │   └── widget-wrapper.ts
│   │   │   │   ├── base-tool.ts
│   │   │   │   ├── leon.ts
│   │   │   │   ├── memory.ts
│   │   │   │   ├── network.ts
│   │   │   │   ├── packages/
│   │   │   │   │   └── lodash.ts
│   │   │   │   ├── params-helper.ts
│   │   │   │   ├── settings.ts
│   │   │   │   ├── tool-manager.ts
│   │   │   │   ├── tool-reporter.ts
│   │   │   │   ├── toolkit-config.ts
│   │   │   │   ├── tools/
│   │   │   │   │   ├── assemblyai_audio/
│   │   │   │   │   │   ├── assemblyai_audio-tool.ts
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   └── lib/
│   │   │   │   │   │       └── .gitkeep
│   │   │   │   │   ├── bash/
│   │   │   │   │   │   ├── bash-tool.ts
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   └── lib/
│   │   │   │   │   │       └── .gitkeep
│   │   │   │   │   ├── cerebras/
│   │   │   │   │   │   ├── cerebras-tool.ts
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   └── lib/
│   │   │   │   │   │       └── .gitkeep
│   │   │   │   │   ├── chatterbox_onnx/
│   │   │   │   │   │   ├── chatterbox_onnx-tool.ts
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   └── lib/
│   │   │   │   │   │       └── .gitkeep
│   │   │   │   │   ├── context/
│   │   │   │   │   │   ├── context-tool.ts
│   │   │   │   │   │   └── index.ts
│   │   │   │   │   ├── ecapa/
│   │   │   │   │   │   ├── ecapa-tool.ts
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   └── lib/
│   │   │   │   │   │       └── .gitkeep
│   │   │   │   │   ├── elevenlabs_audio/
│   │   │   │   │   │   ├── elevenlabs_audio-tool.ts
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   └── lib/
│   │   │   │   │   │       └── .gitkeep
│   │   │   │   │   ├── faster_whisper/
│   │   │   │   │   │   ├── faster_whisper-tool.ts
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   └── lib/
│   │   │   │   │   │       └── .gitkeep
│   │   │   │   │   ├── ffmpeg/
│   │   │   │   │   │   ├── ffmpeg-tool.ts
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   └── lib/
│   │   │   │   │   │       └── .gitkeep
│   │   │   │   │   ├── ffprobe/
│   │   │   │   │   │   ├── ffprobe-tool.ts
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   └── lib/
│   │   │   │   │   │       └── .gitkeep
│   │   │   │   │   ├── grok/
│   │   │   │   │   │   ├── grok-tool.ts
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   └── lib/
│   │   │   │   │   │       └── .gitkeep
│   │   │   │   │   ├── memory/
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   ├── memory-tool.ts
│   │   │   │   │   │   ├── qmd-embed-worker.mjs
│   │   │   │   │   │   ├── qmd-retrieval.ts
│   │   │   │   │   │   └── qmd-store.ts
│   │   │   │   │   ├── open-meteo/
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   ├── lib/
│   │   │   │   │   │   │   └── .gitkeep
│   │   │   │   │   │   └── open-meteo-tool.ts
│   │   │   │   │   ├── openai_audio/
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   ├── lib/
│   │   │   │   │   │   │   └── .gitkeep
│   │   │   │   │   │   └── openai_audio-tool.ts
│   │   │   │   │   ├── opencode/
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   ├── lib/
│   │   │   │   │   │   │   ├── .gitkeep
│   │   │   │   │   │   │   └── prompt.md
│   │   │   │   │   │   └── opencode-tool.ts
│   │   │   │   │   ├── openrouter/
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   ├── lib/
│   │   │   │   │   │   │   └── .gitkeep
│   │   │   │   │   │   └── openrouter-tool.ts
│   │   │   │   │   ├── qwen3_asr/
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   ├── lib/
│   │   │   │   │   │   │   └── .gitkeep
│   │   │   │   │   │   └── qwen3_asr-tool.ts
│   │   │   │   │   ├── qwen3_tts/
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   ├── lib/
│   │   │   │   │   │   │   └── .gitkeep
│   │   │   │   │   │   └── qwen3_tts-tool.ts
│   │   │   │   │   ├── transcription-schema.ts
│   │   │   │   │   ├── ultimate_vocal_remover_onnx/
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   ├── lib/
│   │   │   │   │   │   │   └── .gitkeep
│   │   │   │   │   │   └── ultimate_vocal_remover_onnx-tool.ts
│   │   │   │   │   └── ytdlp/
│   │   │   │   │       ├── index.ts
│   │   │   │   │       ├── lib/
│   │   │   │   │       │   └── .gitkeep
│   │   │   │   │       ├── yt-dlp.conf
│   │   │   │   │       └── ytdlp-tool.ts
│   │   │   │   ├── types.ts
│   │   │   │   ├── utils.ts
│   │   │   │   ├── widget-component.ts
│   │   │   │   └── widget.ts
│   │   │   ├── tool-runtime.ts
│   │   │   └── version.ts
│   │   └── tsconfig.json
│   ├── python/
│   │   ├── dist/
│   │   │   └── .gitkeep
│   │   └── src/
│   │       ├── Pipfile
│   │       ├── constants.py
│   │       ├── main.py
│   │       ├── sdk/
│   │       │   ├── aurora/
│   │       │   │   ├── button.py
│   │       │   │   ├── card.py
│   │       │   │   ├── checkbox.py
│   │       │   │   ├── circular_progress.py
│   │       │   │   ├── flexbox.py
│   │       │   │   ├── form.py
│   │       │   │   ├── icon.py
│   │       │   │   ├── icon_button.py
│   │       │   │   ├── image.py
│   │       │   │   ├── input.py
│   │       │   │   ├── link.py
│   │       │   │   ├── list.py
│   │       │   │   ├── list_header.py
│   │       │   │   ├── list_item.py
│   │       │   │   ├── loader.py
│   │       │   │   ├── progress.py
│   │       │   │   ├── radio.py
│   │       │   │   ├── radio_group.py
│   │       │   │   ├── range_slider.py
│   │       │   │   ├── scroll_container.py
│   │       │   │   ├── select.py
│   │       │   │   ├── select_option.py
│   │       │   │   ├── status.py
│   │       │   │   ├── switch.py
│   │       │   │   ├── tab.py
│   │       │   │   ├── tab_content.py
│   │       │   │   ├── tab_group.py
│   │       │   │   ├── tab_list.py
│   │       │   │   ├── text.py
│   │       │   │   └── widget_wrapper.py
│   │       │   ├── base_tool.py
│   │       │   ├── leon.py
│   │       │   ├── memory.py
│   │       │   ├── network.py
│   │       │   ├── params_helper.py
│   │       │   ├── settings.py
│   │       │   ├── tool_manager.py
│   │       │   ├── toolkit_config.py
│   │       │   ├── tools/
│   │       │   │   ├── assemblyai_audio/
│   │       │   │   │   ├── __init__.py
│   │       │   │   │   ├── assemblyai_audio_tool.py
│   │       │   │   │   └── lib/
│   │       │   │   │       └── .gitkeep
│   │       │   │   ├── bash/
│   │       │   │   │   ├── __init__.py
│   │       │   │   │   ├── bash_tool.py
│   │       │   │   │   └── lib/
│   │       │   │   │       └── .gitkeep
│   │       │   │   ├── cerebras/
│   │       │   │   │   ├── __init__.py
│   │       │   │   │   ├── cerebras_tool.py
│   │       │   │   │   └── lib/
│   │       │   │   │       └── .gitkeep
│   │       │   │   ├── chatterbox_onnx/
│   │       │   │   │   ├── __init__.py
│   │       │   │   │   ├── chatterbox_onnx_tool.py
│   │       │   │   │   └── lib/
│   │       │   │   │       └── .gitkeep
│   │       │   │   ├── ecapa/
│   │       │   │   │   ├── __init__.py
│   │       │   │   │   ├── ecapa_tool.py
│   │       │   │   │   └── lib/
│   │       │   │   │       └── .gitkeep
│   │       │   │   ├── elevenlabs_audio/
│   │       │   │   │   ├── __init__.py
│   │       │   │   │   ├── elevenlabs_audio_tool.py
│   │       │   │   │   └── lib/
│   │       │   │   │       └── .gitkeep
│   │       │   │   ├── faster_whisper/
│   │       │   │   │   ├── __init__.py
│   │       │   │   │   ├── faster_whisper_tool.py
│   │       │   │   │   └── lib/
│   │       │   │   │       └── .gitkeep
│   │       │   │   ├── ffmpeg/
│   │       │   │   │   ├── __init__.py
│   │       │   │   │   ├── ffmpeg_tool.py
│   │       │   │   │   └── lib/
│   │       │   │   │       └── .gitkeep
│   │       │   │   ├── ffprobe/
│   │       │   │   │   ├── __init__.py
│   │       │   │   │   ├── ffprobe_tool.py
│   │       │   │   │   └── lib/
│   │       │   │   │       └── .gitkeep
│   │       │   │   ├── grok/
│   │       │   │   │   ├── __init__.py
│   │       │   │   │   ├── grok_tool.py
│   │       │   │   │   └── lib/
│   │       │   │   │       └── .gitkeep
│   │       │   │   ├── open_meteo/
│   │       │   │   │   ├── __init__.py
│   │       │   │   │   ├── lib/
│   │       │   │   │   │   └── .gitkeep
│   │       │   │   │   └── open_meteo_tool.py
│   │       │   │   ├── openai_audio/
│   │       │   │   │   ├── __init__.py
│   │       │   │   │   ├── lib/
│   │       │   │   │   │   └── .gitkeep
│   │       │   │   │   └── openai_audio_tool.py
│   │       │   │   ├── opencode/
│   │       │   │   │   ├── __init__.py
│   │       │   │   │   ├── lib/
│   │       │   │   │   │   ├── .gitkeep
│   │       │   │   │   │   └── prompt.md
│   │       │   │   │   └── opencode_tool.py
│   │       │   │   ├── openrouter/
│   │       │   │   │   ├── __init__.py
│   │       │   │   │   ├── lib/
│   │       │   │   │   │   └── .gitkeep
│   │       │   │   │   └── openrouter_tool.py
│   │       │   │   ├── qwen3_asr/
│   │       │   │   │   ├── __init__.py
│   │       │   │   │   ├── lib/
│   │       │   │   │   │   └── .gitkeep
│   │       │   │   │   └── qwen3_asr_tool.py
│   │       │   │   ├── qwen3_tts/
│   │       │   │   │   ├── __init__.py
│   │       │   │   │   ├── lib/
│   │       │   │   │   │   └── .gitkeep
│   │       │   │   │   └── qwen3_tts_tool.py
│   │       │   │   ├── transcription_schema.py
│   │       │   │   ├── ultimate_vocal_remover_onnx/
│   │       │   │   │   ├── __init__.py
│   │       │   │   │   ├── lib/
│   │       │   │   │   │   └── .gitkeep
│   │       │   │   │   └── ultimate_vocal_remover_onnx_tool.py
│   │       │   │   └── ytdlp/
│   │       │   │       ├── __init__.py
│   │       │   │       ├── lib/
│   │       │   │       │   └── .gitkeep
│   │       │   │       ├── yt-dlp.conf
│   │       │   │       └── ytdlp_tool.py
│   │       │   ├── types.py
│   │       │   ├── utils.py
│   │       │   ├── widget.py
│   │       │   └── widget_component.py
│   │       ├── setup.py
│   │       └── version.py
│   └── toolkits/
│       ├── business_finance/
│       │   ├── settings/
│       │   │   └── .gitkeep
│       │   └── toolkit.json
│       ├── calendar_scheduling/
│       │   ├── settings/
│       │   │   └── .gitkeep
│       │   └── toolkit.json
│       ├── coding_development/
│       │   ├── settings/
│       │   │   └── .gitkeep
│       │   ├── toolkit.json
│       │   └── tools/
│       │       └── opencode.tool.json
│       ├── communication/
│       │   ├── settings/
│       │   │   └── .gitkeep
│       │   ├── toolkit.json
│       │   └── tools/
│       │       ├── cerebras.tool.json
│       │       └── openrouter.tool.json
│       ├── dialog/
│       │   ├── settings/
│       │   │   └── .gitkeep
│       │   └── toolkit.json
│       ├── file_system/
│       │   ├── settings/
│       │   │   └── .gitkeep
│       │   └── toolkit.json
│       ├── food_drink/
│       │   ├── settings/
│       │   │   └── .gitkeep
│       │   └── toolkit.json
│       ├── games/
│       │   ├── settings/
│       │   │   └── .gitkeep
│       │   └── toolkit.json
│       ├── health_fitness/
│       │   ├── settings/
│       │   │   └── .gitkeep
│       │   └── toolkit.json
│       ├── media_generation/
│       │   ├── settings/
│       │   │   └── .gitkeep
│       │   └── toolkit.json
│       ├── movies_tv/
│       │   ├── settings/
│       │   │   └── .gitkeep
│       │   └── toolkit.json
│       ├── music_audio/
│       │   ├── settings/
│       │   │   └── .gitkeep
│       │   ├── toolkit.json
│       │   └── tools/
│       │       ├── assemblyai_audio.tool.json
│       │       ├── chatterbox_onnx.tool.json
│       │       ├── ecapa.tool.json
│       │       ├── elevenlabs_audio.tool.json
│       │       ├── faster_whisper.tool.json
│       │       ├── openai_audio.tool.json
│       │       ├── qwen3_asr.tool.json
│       │       ├── qwen3_tts.tool.json
│       │       └── ultimate_vocal_remover_onnx.tool.json
│       ├── news/
│       │   ├── settings/
│       │   │   └── .gitkeep
│       │   └── toolkit.json
│       ├── operating_system_control/
│       │   ├── settings/
│       │   │   └── .gitkeep
│       │   ├── toolkit.json
│       │   └── tools/
│       │       └── bash.tool.json
│       ├── productivity_collaboration/
│       │   ├── settings/
│       │   │   └── .gitkeep
│       │   └── toolkit.json
│       ├── search_web/
│       │   ├── settings/
│       │   │   └── .gitkeep
│       │   ├── toolkit.json
│       │   └── tools/
│       │       └── grok.tool.json
│       ├── shopping/
│       │   ├── settings/
│       │   │   └── .gitkeep
│       │   └── toolkit.json
│       ├── smart_home/
│       │   ├── settings/
│       │   │   └── .gitkeep
│       │   └── toolkit.json
│       ├── social_media/
│       │   ├── settings/
│       │   │   └── .gitkeep
│       │   └── toolkit.json
│       ├── sport/
│       │   ├── settings/
│       │   │   └── .gitkeep
│       │   └── toolkit.json
│       ├── structured_knowledge/
│       │   ├── settings/
│       │   │   └── .gitkeep
│       │   ├── toolkit.json
│       │   └── tools/
│       │       ├── context.tool.json
│       │       └── memory.tool.json
│       ├── system_utilities/
│       │   ├── settings/
│       │   │   └── .gitkeep
│       │   └── toolkit.json
│       ├── travel_transportation/
│       │   ├── settings/
│       │   │   └── .gitkeep
│       │   └── toolkit.json
│       ├── video_streaming/
│       │   ├── settings/
│       │   │   └── .gitkeep
│       │   ├── toolkit.json
│       │   └── tools/
│       │       ├── ffmpeg.tool.json
│       │       ├── ffprobe.tool.json
│       │       └── ytdlp.tool.json
│       └── weather/
│           ├── settings/
│           │   └── .gitkeep
│           ├── toolkit.json
│           └── tools/
│               └── openmeteo.tool.json
├── core/
│   ├── config/
│   │   ├── synchronizer/
│   │   │   └── google-drive.sample.json
│   │   └── voice/
│   │       ├── amazon.sample.json
│   │       ├── google-cloud.sample.json
│   │       ├── watson-stt.sample.json
│   │       └── watson-tts.sample.json
│   ├── context/
│   │   ├── .gitkeep
│   │   ├── ARCHITECTURE.md
│   │   └── LEON.md
│   ├── data/
│   │   ├── en/
│   │   │   ├── answers.json
│   │   │   ├── global-entities/
│   │   │   │   ├── color.json
│   │   │   │   ├── handsign.json
│   │   │   │   ├── language.json
│   │   │   │   └── level.json
│   │   │   └── global-resolvers/
│   │   │       └── affirmation_denial.json
│   │   ├── fr/
│   │   │   ├── answers.json
│   │   │   ├── global-entities/
│   │   │   │   ├── color.json
│   │   │   │   └── level.json
│   │   │   └── global-resolvers/
│   │   │       └── affirmation_denial.json
│   │   └── models/
│   │       ├── .gitkeep
│   │       ├── audio/
│   │       │   ├── asr/
│   │       │   │   └── .gitkeep
│   │       │   ├── tts/
│   │       │   │   ├── .gitkeep
│   │       │   │   ├── bert-base-french-europeana-cased/
│   │       │   │   │   └── .gitkeep
│   │       │   │   ├── bert-base-uncased/
│   │       │   │   │   └── .gitkeep
│   │       │   │   └── config.json
│   │       │   └── wake_word/
│   │       │       ├── .gitkeep
│   │       │       ├── Hey_Leon.onnx
│   │       │       ├── embedding.onnx
│   │       │       └── melspectrogram.onnx
│   │       └── llm/
│   │           └── .gitkeep
│   ├── langs.json
│   ├── memory/
│   │   └── .gitkeep
│   └── skills-endpoints.json
├── eslint.config.mjs
├── hotword/
│   ├── README.md
│   ├── index.js
│   ├── models/
│   │   ├── leon-en.pmdl
│   │   └── leon-fr.pmdl
│   └── package.json
├── jsconfig.json
├── logs/
│   └── .gitkeep
├── nodemon.json
├── nodemon.nolint.json
├── package.json
├── scripts/
│   ├── app/
│   │   ├── build-app.js
│   │   └── run-build-app.js
│   ├── assets/
│   │   ├── CHANGELOG-TEMPLATE.md
│   │   ├── leon.lv
│   │   ├── nodejs-bridge-intent-object.json
│   │   └── python-bridge-intent-object.json
│   ├── build-binaries.js
│   ├── check-os.js
│   ├── check.js
│   ├── clean-test-dbs.js
│   ├── commit-msg.js
│   ├── generate/
│   │   ├── generate-http-api-key.js
│   │   ├── generate-json-schemas.js
│   │   ├── generate-prompt.js
│   │   ├── generate-skills-endpoints.js
│   │   ├── run-generate-http-api-key.js
│   │   ├── run-generate-json-schemas.js
│   │   ├── run-generate-prompt.js
│   │   └── run-generate-skills-endpoints.js
│   ├── lint.js
│   ├── out/
│   │   └── .gitkeep
│   ├── prompt-templates/
│   │   ├── create-skill-template.md
│   │   └── create-tool-template.md
│   ├── release/
│   │   ├── generate-changelog.js
│   │   ├── pre-release-binaries.js
│   │   ├── prepare-release.js
│   │   └── update-version.js
│   ├── run-agentic-loop-vitest.ts
│   ├── run-clean-test-dbs.js
│   ├── setup/
│   │   ├── create-instance-id.js
│   │   ├── preinstall.js
│   │   ├── set-ffprobe-permissions.js
│   │   ├── setup-binaries.js
│   │   ├── setup-cmake.js
│   │   ├── setup-core.js
│   │   ├── setup-dotenv.js
│   │   ├── setup-llama-cpp.js
│   │   ├── setup-local-llm.js
│   │   ├── setup-ninja.js
│   │   ├── setup-nvidia-libs.js
│   │   ├── setup-python-dev-env.js
│   │   ├── setup-pytorch.js
│   │   ├── setup-qmd-llm.js
│   │   ├── setup-skills/
│   │   │   ├── install-nodejs-skills-packages.js
│   │   │   ├── setup-skills-settings.js
│   │   │   └── setup-skills.js
│   │   ├── setup-tcp-server-models.js
│   │   └── setup.js
│   ├── setup-offline/
│   │   ├── run-setup-hotword.js
│   │   ├── run-setup-stt.js
│   │   ├── run-setup-tts.js
│   │   ├── setup-hotword.js
│   │   ├── setup-offline.js
│   │   ├── setup-stt.js
│   │   └── setup-tts.js
│   ├── skill-package.js
│   ├── test-module.js
│   └── train/
│       ├── run-train.js
│       ├── train-llm-actions-classifier.js
│       ├── train-main-model/
│       │   ├── train-global-entities.js
│       │   └── train-skills-actions.js
│       ├── train-resolvers-model/
│       │   ├── train-global-resolvers.js
│       │   └── train-skills-resolvers.js
│       ├── train-skill-router-duty.js
│       └── train.js
├── server/
│   └── src/
│       ├── ajv.ts
│       ├── constants.ts
│       ├── conversation-logger.ts
│       ├── core/
│       │   ├── asr/
│       │   │   ├── asr.ts
│       │   │   └── types.ts
│       │   ├── brain/
│       │   │   ├── answer-queue.ts
│       │   │   ├── brain.ts
│       │   │   ├── dialog-action-skill-handler.ts
│       │   │   ├── logic-action-skill-handler.ts
│       │   │   └── types.ts
│       │   ├── context-manager/
│       │   │   ├── context-file-factory.ts
│       │   │   ├── context-file.ts
│       │   │   ├── context-files/
│       │   │   │   ├── activity-context-file.ts
│       │   │   │   ├── architecture-context-file.ts
│       │   │   │   ├── browser-history-context-file.ts
│       │   │   │   ├── gpu-compute-context-file.ts
│       │   │   │   ├── habits-context-file.ts
│       │   │   │   ├── home-context-file.ts
│       │   │   │   ├── host-system-context-file.ts
│       │   │   │   ├── leon-context-file.ts
│       │   │   │   ├── leon-runtime-context-file.ts
│       │   │   │   ├── local-inventory-context-file.ts
│       │   │   │   ├── media-profile-context-file.ts
│       │   │   │   ├── network-ecosystem-context-file.ts
│       │   │   │   ├── owner-context-file.ts
│       │   │   │   ├── storage-context-file.ts
│       │   │   │   ├── system-resources-context-file.ts
│       │   │   │   └── workspace-intelligence-context-file.ts
│       │   │   ├── context-manager.ts
│       │   │   ├── context-probe-helper.ts
│       │   │   ├── context-refresh-worker.ts
│       │   │   ├── context-state-store.ts
│       │   │   ├── index.ts
│       │   │   ├── owner-profile-sync.ts
│       │   │   └── owner-profile.ts
│       │   ├── http-server/
│       │   │   ├── api/
│       │   │   │   ├── fetch-widget/
│       │   │   │   │   ├── get.ts
│       │   │   │   │   └── index.ts
│       │   │   │   ├── info/
│       │   │   │   │   ├── get.ts
│       │   │   │   │   └── index.ts
│       │   │   │   ├── llm-inference/
│       │   │   │   │   ├── index.ts
│       │   │   │   │   └── post.ts
│       │   │   │   ├── open-path/
│       │   │   │   │   ├── index.ts
│       │   │   │   │   └── post.ts
│       │   │   │   ├── run-action/
│       │   │   │   │   ├── index.ts
│       │   │   │   │   └── post.ts
│       │   │   │   └── utterance/
│       │   │   │       ├── index.ts
│       │   │   │       └── post.ts
│       │   │   ├── http-server.ts
│       │   │   ├── old-server.js
│       │   │   └── plugins/
│       │   │       ├── cors.ts
│       │   │       ├── key.ts
│       │   │       └── other.ts
│       │   ├── index.ts
│       │   ├── llm-manager/
│       │   │   ├── llm-duties/
│       │   │   │   ├── action-calling-llm-duty.ts
│       │   │   │   ├── action-recognition-llm-duty.ts
│       │   │   │   ├── conversation-llm-duty.ts
│       │   │   │   ├── custom-llm-duty.ts
│       │   │   │   ├── custom-ner-llm-duty.ts
│       │   │   │   ├── paraphrase-llm-duty.ts
│       │   │   │   ├── react-llm-duty/
│       │   │   │   │   ├── catalog.ts
│       │   │   │   │   ├── constants.ts
│       │   │   │   │   ├── execution.ts
│       │   │   │   │   ├── final-answer.ts
│       │   │   │   │   ├── history-compaction.ts
│       │   │   │   │   ├── metrics.ts
│       │   │   │   │   ├── phase-helpers.ts
│       │   │   │   │   ├── phase-policy.ts
│       │   │   │   │   ├── phases.ts
│       │   │   │   │   ├── plan-contract.ts
│       │   │   │   │   ├── plan-widget.ts
│       │   │   │   │   ├── planning.ts
│       │   │   │   │   ├── recovery-planning.ts
│       │   │   │   │   ├── types.ts
│       │   │   │   │   └── utils.ts
│       │   │   │   ├── react-llm-duty.ts
│       │   │   │   ├── skill-router-llm-duty.ts
│       │   │   │   └── slot-filling-llm-duty.ts
│       │   │   ├── llm-duty.ts
│       │   │   ├── llm-manager.ts
│       │   │   ├── llm-provider.ts
│       │   │   ├── llm-providers/
│       │   │   │   ├── ai-sdk-remote-llm-provider.ts
│       │   │   │   ├── anthropic-llm-provider.ts
│       │   │   │   ├── cerebras-llm-provider.ts
│       │   │   │   ├── groq-llm-provider.ts
│       │   │   │   ├── huggingface-llm-provider.ts
│       │   │   │   ├── llamacpp-llm-provider.ts
│       │   │   │   ├── local-llm-provider.ts
│       │   │   │   ├── moonshotai-llm-provider.ts
│       │   │   │   ├── openai-llm-provider.ts
│       │   │   │   ├── openrouter-llm-provider.ts
│       │   │   │   ├── sglang-llm-provider.ts
│       │   │   │   └── z-ai-llm-provider.ts
│       │   │   ├── persona.ts
│       │   │   ├── streaming-chunk.ts
│       │   │   ├── types.ts
│       │   │   └── warm-up-llm-duties.ts
│       │   ├── memory-manager/
│       │   │   ├── index.ts
│       │   │   ├── memory-manager.ts
│       │   │   ├── memory-repository.ts
│       │   │   ├── qmd-backend.ts
│       │   │   ├── sql/
│       │   │   │   └── schema.sql
│       │   │   ├── summarizer.ts
│       │   │   └── types.ts
│       │   ├── nlp/
│       │   │   ├── conversation.ts
│       │   │   ├── nlu/
│       │   │   │   ├── action-loop.ts
│       │   │   │   ├── model-loader.ts
│       │   │   │   ├── ner.ts
│       │   │   │   ├── nlu-process-result-updater.ts
│       │   │   │   ├── nlu.ts
│       │   │   │   └── slot-filling.ts
│       │   │   └── types.ts
│       │   ├── pulse-manager.ts
│       │   ├── self-model-manager.ts
│       │   ├── socket-server.ts
│       │   ├── stt/
│       │   │   ├── parsers/
│       │   │   │   ├── coqui-stt-parser.ts
│       │   │   │   ├── google-cloud-stt-parser.ts
│       │   │   │   ├── local-parser.ts
│       │   │   │   └── watson-stt-parser.ts
│       │   │   ├── stt-parser-base.ts
│       │   │   ├── stt.ts
│       │   │   └── types.ts
│       │   ├── tcp-client.ts
│       │   ├── tool-executor.ts
│       │   ├── toolkit-registry.ts
│       │   └── tts/
│       │       ├── synthesizers/
│       │       │   ├── amazon-polly-synthesizer.ts
│       │       │   ├── flite-synthesizer.ts
│       │       │   ├── google-cloud-tts-synthesizer.ts
│       │       │   ├── local-synthesizer.ts
│       │       │   └── watson-tts-synthesizer.ts
│       │       ├── tts-synthesizer-base.ts
│       │       ├── tts.ts
│       │       └── types.ts
│       ├── declarations.d.ts
│       ├── global.d.ts
│       ├── helpers/
│       │   ├── date-helper.ts
│       │   ├── file-helper.ts
│       │   ├── lang-helper.ts
│       │   ├── loader-helper.ts
│       │   ├── log-helper.ts
│       │   ├── network-helper.ts
│       │   ├── skill-domain-helper.ts
│       │   ├── string-helper.ts
│       │   └── system-helper.ts
│       ├── index.ts
│       ├── intent-object.sample.json
│       ├── pre-check.ts
│       ├── schemas/
│       │   ├── global-data-schemas.ts
│       │   ├── skill-schemas.ts
│       │   ├── tool-schemas.ts
│       │   ├── toolkit-schemas.ts
│       │   └── voice-config-schemas.ts
│       ├── telemetry.ts
│       ├── tool-call-logger.ts
│       ├── types.ts
│       ├── updater.ts
│       └── utilities.ts
├── skills/
│   ├── bash_skill/
│   │   ├── README.md
│   │   ├── locales/
│   │   │   └── en.json
│   │   ├── skill.json
│   │   └── src/
│   │       ├── actions/
│   │       │   └── execute.py
│   │       └── settings.sample.json
│   ├── business_finance/
│   │   └── domain.json
│   ├── color_skill/
│   │   ├── README.md
│   │   ├── locales/
│   │   │   └── en.json
│   │   ├── memory/
│   │   │   └── .gitkeep
│   │   ├── skill.json
│   │   ├── src/
│   │   │   ├── actions/
│   │   │   │   └── tell_hexadecimal_color.py
│   │   │   ├── lib/
│   │   │   │   ├── .gitkeep
│   │   │   │   └── hexa_colors.py
│   │   │   ├── settings.sample.json
│   │   │   └── widgets/
│   │   │       └── .gitkeep
│   │   └── test/
│   │       └── .gitkeep
│   ├── food_drink/
│   │   └── domain.json
│   ├── games/
│   │   ├── akinator/
│   │   │   ├── README.md
│   │   │   ├── config/
│   │   │   │   └── en.json
│   │   │   ├── memory/
│   │   │   │   └── .gitkeep
│   │   │   ├── skill.json
│   │   │   ├── src/
│   │   │   │   ├── actions/
│   │   │   │   │   ├── guess.py
│   │   │   │   │   ├── retry.py
│   │   │   │   │   └── setup.py
│   │   │   │   ├── lib/
│   │   │   │   │   ├── .gitkeep
│   │   │   │   │   ├── __init__.py
│   │   │   │   │   ├── main.py
│   │   │   │   │   ├── memory.py
│   │   │   │   │   └── question_widget.py
│   │   │   │   ├── settings.sample.json
│   │   │   │   └── widgets/
│   │   │   │       └── .gitkeep
│   │   │   └── test/
│   │   │       └── .gitkeep
│   │   └── domain.json
│   ├── good_bye_skill/
│   │   ├── README.md
│   │   ├── config/
│   │   │   ├── en.json
│   │   │   └── fr.json
│   │   ├── locales/
│   │   │   └── en.json
│   │   ├── memory/
│   │   │   └── .gitkeep
│   │   ├── skill.json
│   │   └── test/
│   │       └── .gitkeep
│   ├── greeting_skill/
│   │   ├── README.md
│   │   ├── locales/
│   │   │   ├── en.json
│   │   │   └── fr.json
│   │   ├── memory/
│   │   │   └── .gitkeep
│   │   ├── skill.json
│   │   ├── src/
│   │   │   ├── actions/
│   │   │   │   └── greet.py
│   │   │   ├── lib/
│   │   │   │   └── .gitkeep
│   │   │   ├── settings.sample.json
│   │   │   └── widgets/
│   │   │       └── .gitkeep
│   │   └── test/
│   │       └── .gitkeep
│   ├── guess_the_number_skill/
│   │   ├── README.md
│   │   ├── locales/
│   │   │   └── en.json
│   │   ├── memory/
│   │   │   └── .gitkeep
│   │   ├── skill.json
│   │   ├── src/
│   │   │   ├── actions/
│   │   │   │   ├── guess.py
│   │   │   │   ├── replay.py
│   │   │   │   └── set_up.py
│   │   │   ├── lib/
│   │   │   │   ├── .gitkeep
│   │   │   │   └── memory.py
│   │   │   ├── settings.sample.json
│   │   │   └── widgets/
│   │   │       └── .gitkeep
│   │   └── test/
│   │       └── .gitkeep
│   ├── health_fitness/
│   │   └── domain.json
│   ├── knowledge_education/
│   │   └── domain.json
│   ├── leon/
│   │   ├── age/
│   │   │   ├── README.md
│   │   │   ├── config/
│   │   │   │   └── en.json
│   │   │   ├── memory/
│   │   │   │   └── .gitkeep
│   │   │   ├── skill.json
│   │   │   ├── src/
│   │   │   │   ├── actions/
│   │   │   │   │   └── run.ts
│   │   │   │   ├── lib/
│   │   │   │   │   ├── .gitkeep
│   │   │   │   │   └── getTimeDifferenceBetweenDates.ts
│   │   │   │   ├── settings.sample.json
│   │   │   │   └── widgets/
│   │   │   │       └── .gitkeep
│   │   │   └── test/
│   │   │       └── .gitkeep
│   │   ├── domain.json
│   │   ├── good_bye/
│   │   │   ├── README.md
│   │   │   ├── config/
│   │   │   │   ├── en.json
│   │   │   │   └── fr.json
│   │   │   ├── memory/
│   │   │   │   └── .gitkeep
│   │   │   ├── skill.json
│   │   │   └── test/
│   │   │       └── .gitkeep
│   │   ├── help/
│   │   │   ├── README.md
│   │   │   ├── config/
│   │   │   │   └── en.json
│   │   │   ├── memory/
│   │   │   │   └── .gitkeep
│   │   │   ├── skill.json
│   │   │   ├── src/
│   │   │   │   ├── actions/
│   │   │   │   │   └── help.ts
│   │   │   │   ├── lib/
│   │   │   │   │   └── .gitkeep
│   │   │   │   ├── settings.sample.json
│   │   │   │   └── widgets/
│   │   │   │       └── .gitkeep
│   │   │   └── test/
│   │   │       └── .gitkeep
│   │   ├── introduction/
│   │   │   ├── README.md
│   │   │   ├── config/
│   │   │   │   ├── en.json
│   │   │   │   └── fr.json
│   │   │   ├── memory/
│   │   │   │   └── .gitkeep
│   │   │   ├── skill.json
│   │   │   ├── src/
│   │   │   │   ├── actions/
│   │   │   │   │   ├── introduce_leon.py
│   │   │   │   │   └── remember.py
│   │   │   │   ├── lib/
│   │   │   │   │   ├── .gitkeep
│   │   │   │   │   └── memory.py
│   │   │   │   ├── settings.sample.json
│   │   │   │   └── widgets/
│   │   │   │       └── .gitkeep
│   │   │   └── test/
│   │   │       └── .gitkeep
│   │   ├── joke/
│   │   │   ├── README.md
│   │   │   ├── config/
│   │   │   │   ├── en.json
│   │   │   │   └── fr.json
│   │   │   ├── memory/
│   │   │   │   └── .gitkeep
│   │   │   ├── skill.json
│   │   │   └── test/
│   │   │       └── .gitkeep
│   │   ├── meaning_of_life/
│   │   │   ├── README.md
│   │   │   ├── config/
│   │   │   │   ├── en.json
│   │   │   │   └── fr.json
│   │   │   ├── memory/
│   │   │   │   └── .gitkeep
│   │   │   ├── skill.json
│   │   │   └── test/
│   │   │       └── .gitkeep
│   │   ├── random_number/
│   │   │   ├── README.md
│   │   │   ├── config/
│   │   │   │   ├── en.json
│   │   │   │   └── fr.json
│   │   │   ├── memory/
│   │   │   │   └── .gitkeep
│   │   │   ├── skill.json
│   │   │   ├── src/
│   │   │   │   ├── actions/
│   │   │   │   │   └── run.py
│   │   │   │   ├── lib/
│   │   │   │   │   └── .gitkeep
│   │   │   │   ├── settings.sample.json
│   │   │   │   └── widgets/
│   │   │   │       ├── .gitkeep
│   │   │   │       └── number_widget.py
│   │   │   └── test/
│   │   │       └── .gitkeep
│   │   └── thanks/
│   │       ├── README.md
│   │       ├── config/
│   │       │   ├── en.json
│   │       │   └── fr.json
│   │       ├── memory/
│   │       │   └── .gitkeep
│   │       ├── skill.json
│   │       └── test/
│   │           └── .gitkeep
│   ├── mbti_skill/
│   │   ├── README.md
│   │   ├── locales/
│   │   │   └── en.json
│   │   ├── memory/
│   │   │   └── .gitkeep
│   │   ├── skill.json
│   │   ├── src/
│   │   │   ├── actions/
│   │   │   │   ├── quiz.py
│   │   │   │   └── set_up.py
│   │   │   ├── lib/
│   │   │   │   ├── .gitkeep
│   │   │   │   └── memory.py
│   │   │   ├── settings.sample.json
│   │   │   └── widgets/
│   │   │       └── .gitkeep
│   │   └── test/
│   │       └── .gitkeep
│   ├── movies_tv/
│   │   └── domain.json
│   ├── music_audio/
│   │   └── domain.json
│   ├── music_audio_toolkit_skill/
│   │   ├── README.md
│   │   ├── locales/
│   │   │   └── en.json
│   │   ├── skill.json
│   │   └── src/
│   │       ├── actions/
│   │       │   ├── dub_audio.ts
│   │       │   ├── split_instrumental_vocal.ts
│   │       │   └── transcribe_audio.ts
│   │       └── settings.sample.json
│   ├── news/
│   │   ├── domain.json
│   │   ├── github_trends/
│   │   │   ├── README.md
│   │   │   ├── config/
│   │   │   │   ├── en.json
│   │   │   │   └── fr.json
│   │   │   ├── memory/
│   │   │   │   └── .gitkeep
│   │   │   ├── skill.json
│   │   │   ├── src/
│   │   │   │   ├── actions/
│   │   │   │   │   └── run.py
│   │   │   │   ├── lib/
│   │   │   │   │   ├── .gitkeep
│   │   │   │   │   └── github_lang.py
│   │   │   │   ├── settings.sample.json
│   │   │   │   └── widgets/
│   │   │   │       └── .gitkeep
│   │   │   └── test/
│   │   │       └── .gitkeep
│   │   └── product_hunt_trends/
│   │       ├── README.md
│   │       ├── config/
│   │       │   ├── en.json
│   │       │   └── fr.json
│   │       ├── memory/
│   │       │   └── .gitkeep
│   │       ├── skill.json
│   │       ├── src/
│   │       │   ├── actions/
│   │       │   │   └── run.py
│   │       │   ├── lib/
│   │       │   │   └── .gitkeep
│   │       │   ├── settings.sample.json
│   │       │   └── widgets/
│   │       │       └── .gitkeep
│   │       └── test/
│   │           └── .gitkeep
│   ├── partner_assistant_skill/
│   │   ├── README.md
│   │   ├── config/
│   │   │   ├── en.json
│   │   │   └── fr.json
│   │   ├── locales/
│   │   │   └── en.json
│   │   ├── memory/
│   │   │   └── .gitkeep
│   │   ├── skill.json
│   │   ├── src/
│   │   │   ├── actions/
│   │   │   │   └── tell_about_assistant.py
│   │   │   ├── lib/
│   │   │   │   └── .gitkeep
│   │   │   ├── settings.sample.json
│   │   │   └── widgets/
│   │   │       └── .gitkeep
│   │   └── test/
│   │       └── .gitkeep
│   ├── podcast_generator_skill/
│   │   ├── locales/
│   │   │   └── en.json
│   │   ├── skill.json
│   │   └── src/
│   │       ├── actions/
│   │       │   └── generate.ts
│   │       └── settings.sample.json
│   ├── productivity/
│   │   └── domain.json
│   ├── rochambeau_skill/
│   │   ├── README.md
│   │   ├── locales/
│   │   │   └── en.json
│   │   ├── memory/
│   │   │   └── .gitkeep
│   │   ├── skill.json
│   │   ├── src/
│   │   │   ├── actions/
│   │   │   │   ├── play.py
│   │   │   │   └── rematch.py
│   │   │   ├── lib/
│   │   │   │   └── .gitkeep
│   │   │   ├── settings.sample.json
│   │   │   └── widgets/
│   │   │       └── .gitkeep
│   │   └── test/
│   │       └── .gitkeep
│   ├── search_web_toolkit_skill/
│   │   ├── locales/
│   │   │   └── en.json
│   │   ├── skill.json
│   │   └── src/
│   │       ├── actions/
│   │       │   └── search.ts
│   │       └── settings.sample.json
│   ├── shopping/
│   │   └── domain.json
│   ├── skill_writer_skill/
│   │   ├── locales/
│   │   │   └── en.json
│   │   ├── skill.json
│   │   └── src/
│   │       ├── actions/
│   │       │   ├── create_skill.ts
│   │       │   └── modify_skill.ts
│   │       ├── lib/
│   │       │   ├── skill-plan-llm.ts
│   │       │   ├── skill-plan.ts
│   │       │   └── skill-prompt.ts
│   │       └── settings.sample.json
│   ├── smart_home/
│   │   └── domain.json
│   ├── social_communication/
│   │   ├── conversation/
│   │   │   ├── README.md
│   │   │   ├── config/
│   │   │   │   └── en.json
│   │   │   ├── memory/
│   │   │   │   └── .gitkeep
│   │   │   ├── skill.json
│   │   │   ├── src/
│   │   │   │   ├── actions/
│   │   │   │   │   ├── chit_chat.ts
│   │   │   │   │   └── converse.ts
│   │   │   │   ├── lib/
│   │   │   │   │   └── .gitkeep
│   │   │   │   ├── settings.sample.json
│   │   │   │   └── widgets/
│   │   │   │       └── .gitkeep
│   │   │   └── test/
│   │   │       └── .gitkeep
│   │   └── domain.json
│   ├── sport/
│   │   └── domain.json
│   ├── timer_skill/
│   │   ├── README.md
│   │   ├── locales/
│   │   │   └── en.json
│   │   ├── memory/
│   │   │   └── .gitkeep
│   │   ├── skill.json
│   │   ├── src/
│   │   │   ├── actions/
│   │   │   │   ├── cancel_timer.ts
│   │   │   │   ├── check_timer.ts
│   │   │   │   └── set_timer.ts
│   │   │   ├── lib/
│   │   │   │   ├── .gitkeep
│   │   │   │   └── memory.ts
│   │   │   ├── settings.sample.json
│   │   │   └── widgets/
│   │   │       ├── .gitkeep
│   │   │       ├── components/
│   │   │       │   └── timer.ts
│   │   │       └── timer-widget.ts
│   │   └── test/
│   │       └── .gitkeep
│   ├── todo_list_skill/
│   │   ├── README.md
│   │   ├── config/
│   │   │   ├── en.json
│   │   │   └── fr.json
│   │   ├── locales/
│   │   │   └── en.json
│   │   ├── memory/
│   │   │   └── .gitkeep
│   │   ├── skill.json
│   │   ├── src/
│   │   │   ├── actions/
│   │   │   │   ├── add_todos.py
│   │   │   │   ├── complete_items.py
│   │   │   │   ├── create_list.py
│   │   │   │   ├── delete_list.py
│   │   │   │   ├── get_all_lists.py
│   │   │   │   ├── get_list_items.py
│   │   │   │   ├── rename_list.py
│   │   │   │   └── uncomplete_items.py
│   │   │   ├── lib/
│   │   │   │   ├── .gitkeep
│   │   │   │   └── memory.py
│   │   │   ├── settings.sample.json
│   │   │   └── widgets/
│   │   │       ├── .gitkeep
│   │   │       ├── list_of_lists_widget.py
│   │   │       └── todos_list_widget.py
│   │   └── test/
│   │       └── .gitkeep
│   ├── translator_poc_skill/
│   │   ├── README.md
│   │   ├── config/
│   │   │   └── en.json
│   │   ├── locales/
│   │   │   └── en.json
│   │   ├── memory/
│   │   │   └── .gitkeep
│   │   ├── skill.json
│   │   ├── src/
│   │   │   ├── actions/
│   │   │   │   └── translate.ts
│   │   │   ├── lib/
│   │   │   │   └── .gitkeep
│   │   │   ├── settings.sample.json
│   │   │   └── widgets/
│   │   │       └── .gitkeep
│   │   └── test/
│   │       └── .gitkeep
│   ├── travel_transportation/
│   │   └── domain.json
│   ├── tsconfig.json
│   ├── unknown/
│   │   ├── domain.json
│   │   └── widget-playground/
│   │       ├── README.md
│   │       ├── config/
│   │       │   └── en.json
│   │       ├── memory/
│   │       │   └── .gitkeep
│   │       ├── skill.json
│   │       ├── src/
│   │       │   ├── actions/
│   │       │   │   └── run.ts
│   │       │   ├── lib/
│   │       │   │   └── .gitkeep
│   │       │   ├── settings.sample.json
│   │       │   └── widgets/
│   │       │       ├── .gitkeep
│   │       │       └── playground-test.ts
│   │       └── test/
│   │           └── .gitkeep
│   ├── utilities/
│   │   ├── date_time/
│   │   │   ├── README.md
│   │   │   ├── config/
│   │   │   │   └── en.json
│   │   │   ├── memory/
│   │   │   │   └── .gitkeep
│   │   │   ├── skill.json
│   │   │   ├── src/
│   │   │   │   ├── actions/
│   │   │   │   │   ├── current_date.ts
│   │   │   │   │   ├── current_date_time.ts
│   │   │   │   │   ├── current_date_time_with_time_zone.ts
│   │   │   │   │   ├── current_time.ts
│   │   │   │   │   ├── current_week_number.ts
│   │   │   │   │   └── days_countdown.ts
│   │   │   │   ├── lib/
│   │   │   │   │   ├── .gitkeep
│   │   │   │   │   ├── constants.ts
│   │   │   │   │   └── zeroPad.ts
│   │   │   │   ├── package.json
│   │   │   │   ├── settings.sample.json
│   │   │   │   └── widgets/
│   │   │   │       └── .gitkeep
│   │   │   └── test/
│   │   │       └── .gitkeep
│   │   ├── domain.json
│   │   ├── have_i_been_pwned/
│   │   │   ├── README.md
│   │   │   ├── config/
│   │   │   │   ├── en.json
│   │   │   │   └── fr.json
│   │   │   ├── memory/
│   │   │   │   └── .gitkeep
│   │   │   ├── skill.json
│   │   │   ├── src/
│   │   │   │   ├── actions/
│   │   │   │   │   └── run.py
│   │   │   │   ├── lib/
│   │   │   │   │   └── .gitkeep
│   │   │   │   ├── settings.sample.json
│   │   │   │   └── widgets/
│   │   │   │       └── .gitkeep
│   │   │   └── test/
│   │   │       └── .gitkeep
│   │   ├── is_it_down/
│   │   │   ├── README.md
│   │   │   ├── config/
│   │   │   │   ├── en.json
│   │   │   │   └── fr.json
│   │   │   ├── memory/
│   │   │   │   └── .gitkeep
│   │   │   ├── skill.json
│   │   │   ├── src/
│   │   │   │   ├── actions/
│   │   │   │   │   └── run.py
│   │   │   │   ├── lib/
│   │   │   │   │   └── .gitkeep
│   │   │   │   ├── settings.sample.json
│   │   │   │   └── widgets/
│   │   │   │       └── .gitkeep
│   │   │   └── test/
│   │   │       └── .gitkeep
│   │   ├── speed_test/
│   │   │   ├── README.md
│   │   │   ├── config/
│   │   │   │   ├── en.json
│   │   │   │   └── fr.json
│   │   │   ├── memory/
│   │   │   │   └── .gitkeep
│   │   │   ├── skill.json
│   │   │   ├── src/
│   │   │   │   ├── actions/
│   │   │   │   │   └── run.py
│   │   │   │   ├── lib/
│   │   │   │   │   ├── .gitkeep
│   │   │   │   │   └── speedtest.py
│   │   │   │   ├── settings.sample.json
│   │   │   │   └── widgets/
│   │   │   │       └── .gitkeep
│   │   │   └── test/
│   │   │       └── .gitkeep
│   │   ├── timer/
│   │   │   ├── README.md
│   │   │   ├── config/
│   │   │   │   └── en.json
│   │   │   ├── memory/
│   │   │   │   └── .gitkeep
│   │   │   ├── skill.json
│   │   │   ├── src/
│   │   │   │   ├── actions/
│   │   │   │   │   ├── cancel_timer.ts
│   │   │   │   │   ├── check_timer.ts
│   │   │   │   │   └── set_timer.ts
│   │   │   │   ├── lib/
│   │   │   │   │   ├── .gitkeep
│   │   │   │   │   └── memory.ts
│   │   │   │   ├── settings.sample.json
│   │   │   │   └── widgets/
│   │   │   │       ├── .gitkeep
│   │   │   │       ├── components/
│   │   │   │       │   └── timer.ts
│   │   │   │       └── timer-widget.ts
│   │   │   └── test/
│   │   │       └── .gitkeep
│   │   └── translator-poc/
│   │       ├── README.md
│   │       ├── config/
│   │       │   └── en.json
│   │       ├── memory/
│   │       │   └── .gitkeep
│   │       ├── skill.json
│   │       ├── src/
│   │       │   ├── actions/
│   │       │   │   └── translate.ts
│   │       │   ├── lib/
│   │       │   │   └── .gitkeep
│   │       │   ├── settings.sample.json
│   │       │   └── widgets/
│   │       │       └── .gitkeep
│   │       └── test/
│   │           └── .gitkeep
│   ├── video_summarizer_skill/
│   │   ├── locales/
│   │   │   └── en.json
│   │   ├── skill.json
│   │   └── src/
│   │       ├── actions/
│   │       │   ├── prepare_audio.ts
│   │       │   └── summarize_transcription.ts
│   │       └── settings.sample.json
│   ├── video_translator_skill/
│   │   ├── README.md
│   │   ├── locales/
│   │   │   └── en.json
│   │   ├── memory/
│   │   │   └── .gitkeep
│   │   ├── skill.json
│   │   └── src/
│   │       ├── actions/
│   │       │   ├── create_new_audio.ts
│   │       │   ├── detect_genders.ts
│   │       │   ├── download_video.ts
│   │       │   ├── extract_audio.ts
│   │       │   ├── get_speakers_references.ts
│   │       │   ├── merge_audio.ts
│   │       │   └── translate_transcription.ts
│   │       ├── lib/
│   │       │   └── memory.ts
│   │       ├── settings.sample.json
│   │       └── widgets/
│   │           └── download-progress-widget.ts
│   ├── voice_designer_skill/
│   │   ├── locales/
│   │   │   └── en.json
│   │   ├── skill.json
│   │   └── src/
│   │       ├── actions/
│   │       │   └── design_and_speak.ts
│   │       └── settings.sample.json
│   ├── weather/
│   │   └── domain.json
│   └── weather_forecast_skill/
│       ├── locales/
│       │   └── en.json
│       ├── skill.json
│       └── src/
│           ├── actions/
│           │   └── get_forecast.ts
│           ├── settings.sample.json
│           └── widgets/
│               └── weather-forecast-widget.ts
├── tcp_server/
│   ├── settings.json
│   └── src/
│       ├── Pipfile
│       ├── lib/
│       │   ├── asr/
│       │   │   └── api.py
│       │   ├── constants.py
│       │   ├── nlp.py
│       │   ├── tcp_server.py
│       │   ├── tmp/
│       │   │   └── .gitkeep
│       │   ├── tts/
│       │   │   ├── __init__.py
│       │   │   ├── api.py
│       │   │   ├── attentions.py
│       │   │   ├── commons.py
│       │   │   ├── models.py
│       │   │   ├── modules.py
│       │   │   ├── monotonic_align/
│       │   │   │   ├── __init__.py
│       │   │   │   └── core.py
│       │   │   ├── split_utils.py
│       │   │   ├── text/
│       │   │   │   ├── __init__.py
│       │   │   │   ├── cleaner.py
│       │   │   │   ├── cleaner_multiling.py
│       │   │   │   ├── cmudict.rep
│       │   │   │   ├── cmudict_cache.pickle
│       │   │   │   ├── english.py
│       │   │   │   ├── english_bert.py
│       │   │   │   ├── english_utils/
│       │   │   │   │   ├── __init__.py
│       │   │   │   │   ├── abbreviations.py
│       │   │   │   │   ├── number_norm.py
│       │   │   │   │   └── time_norm.py
│       │   │   │   ├── fr_phonemizer/
│       │   │   │   │   ├── __init__.py
│       │   │   │   │   ├── base.py
│       │   │   │   │   ├── cleaner.py
│       │   │   │   │   ├── en_symbols.json
│       │   │   │   │   ├── example_ipa.txt
│       │   │   │   │   ├── fr_symbols.json
│       │   │   │   │   ├── fr_to_ipa.py
│       │   │   │   │   ├── french_abbreviations.py
│       │   │   │   │   ├── french_symbols.txt
│       │   │   │   │   ├── gruut_wrapper.py
│       │   │   │   │   └── punctuation.py
│       │   │   │   ├── french.py
│       │   │   │   ├── french_bert.py
│       │   │   │   ├── opencpop-strict.txt
│       │   │   │   └── symbols.py
│       │   │   ├── transforms.py
│       │   │   └── utils.py
│       │   ├── utils.py
│       │   └── wake_word/
│       │       └── api.py
│       ├── main.py
│       ├── setup.py
│       └── version.py
├── test/
│   ├── agentic-loop/
│   │   ├── e2e/
│   │   │   ├── provider-matrix.ts
│   │   │   ├── react-provider-smoke.spec.ts
│   │   │   └── run-agentic-loop-provider-scenario.ts
│   │   └── unit/
│   │       └── react-llm-duty.spec.ts
│   ├── assets/
│   │   ├── broken-leon-model.nlp
│   │   └── expressions.json
│   ├── e2e/
│   │   ├── modules/
│   │   │   ├── e2e.modules.jest.json
│   │   │   └── e2e.modules.setup.js
│   │   ├── nlp-modules.spec.js
│   │   └── over-http.spec.js
│   ├── json/
│   │   ├── is-valid.spec.js
│   │   ├── json.jest.json
│   │   ├── no-punctuation.spec.js
│   │   └── punctuation.spec.js
│   ├── paths.setup.js
│   └── unit/
│       ├── server/
│       │   ├── core/
│       │   │   ├── asr.spec.js
│       │   │   ├── brain.spec.js
│       │   │   ├── ner.spec.js
│       │   │   ├── nlu.spec.js
│       │   │   ├── server.spec.js
│       │   │   └── synchronizer.spec.js
│       │   ├── helpers/
│       │   │   ├── date.spec.js
│       │   │   ├── loader.spec.js
│       │   │   ├── log.spec.js
│       │   │   ├── os.spec.js
│       │   │   └── string.spec.js
│       │   ├── stt/
│       │   │   ├── coqui/
│       │   │   │   └── parser.spec.js
│       │   │   └── stt.spec.js
│       │   └── tts/
│       │       ├── flite/
│       │       │   └── synthesizer.spec.js
│       │       └── tts.spec.js
│       ├── unit.jest.json
│       └── unit.setup.js
├── tsconfig.json
└── vitest.agentic-loop.config.ts

================================================
FILE CONTENTS
================================================

================================================
FILE: .changelogrc
================================================
{
  "app_name": "Leon",
  "sections": [
    {
      "title": "BREAKING CHANGES",
      "grep": "BREAKING"
    },
    {
      "title": "Features",
      "grep": "^feat"
    },
    {
      "title": "Bug Fixes",
      "grep": "^fix"
    },
    {
      "title": "Performance Improvements",
      "grep": "^perf"
    },
    {
      "title": "Documentation Changes",
      "grep": "^docs"
    }
  ]
}


================================================
FILE: .editorconfig
================================================
# EditorConfig is awesome: https://EditorConfig.org

# top-most EditorConfig file
root = true

# Unix-style newlines with a newline ending every file
[*]
indent_style = space
indent_size = 2
charset = utf-8
end_of_line = lf
insert_final_newline = true

[*.py]
indent_size = 4


================================================
FILE: .env.sample
================================================
# Main settings of Leon
# https://docs.getleon.ai/configuration

# Language currently used
LEON_LANG=en-US

# Server
LEON_HOST=http://localhost
LEON_PORT=1337

# Routing mode: smart | workflow | agent
LEON_ROUTING_MODE=smart
# Comma-separated context files to disable (e.g. BROWSER_HISTORY.md,ACTIVITY.md)
LEON_DISABLED_CONTEXT_FILES=
# Memory system

# Enable/disable LLM
LEON_LLM=true
# Default LLM provider fallback for all duties
# Supported values: llamacpp | sglang | openrouter | zai | openai | anthropic | moonshotai | huggingface | cerebras | groq
LEON_LLM_PROVIDER=llamacpp
# Workflow/provider split:
# - if both workflow and agent use a local provider, they must use the same provider and model
# - use llama.cpp to let Leon spawn its own local llama-server
# - optionally use SGLang on Linux for higher-performance local serving
LEON_WORKFLOW_LLM_PROVIDER=llamacpp
LEON_AGENT_LLM_PROVIDER=llamacpp

# llama.cpp local LLM (served by Leon via bin/llama.cpp/llama-server)
# Keep the model file under core/data/models/llm/
# Leave empty to use the default model installed by Leon.
LEON_LLAMACPP_MODEL_PATH=

# Optional Linux high-performance local provider (OpenAI-compatible)
LEON_SGLANG_BASE_URL=http://127.0.0.1:30000/v1
LEON_SGLANG_API_KEY=
LEON_SGLANG_MODEL=Qwen/Qwen3-Coder-Next
LEON_SGLANG_AGENT_LLM=Qwen/Qwen3-Coder-Next

# OpenRouter API key
LEON_OPENROUTER_API_KEY=
# OpenRouter agent LLM - https://openrouter.ai/models
LEON_OPENROUTER_AGENT_LLM=z-ai/glm-5-turbo
# LEON_OPENROUTER_AGENT_LLM=moonshotai/kimi-k2.5
# LEON_OPENROUTER_AGENT_LLM=openai/gpt-5.2
# LEON_OPENROUTER_AGENT_LLM=openai/gpt-5-mini
# LEON_OPENROUTER_AGENT_LLM=qwen/qwen3.5-35b-a3b
# LEON_OPENROUTER_AGENT_LLM=qwen/qwen3.5-122b-a10b
# LEON_OPENROUTER_AGENT_LLM=anthropic/claude-opus-4.6
# LEON_OPENROUTER_AGENT_LLM=minimax/minimax-m2.5
# LEON_OPENROUTER_AGENT_LLM=qwen/qwen3.5-flash-02-23
# LEON_OPENROUTER_AGENT_LLM=qwen/qwen3-coder-next
# LEON_OPENROUTER_AGENT_LLM=xiaomi/mimo-v2-flash
# LEON_OPENROUTER_AGENT_LLM=qwen/qwen3-235b-a22b-2507
# LEON_OPENROUTER_AGENT_LLM=openai/gpt-oss-120b

# Z.AI API key
LEON_ZAI_API_KEY=
# Z.AI agent LLM
LEON_ZAI_AGENT_LLM=glm-5

# OpenAI API key
LEON_OPENAI_API_KEY=
# OpenAI agent LLM - https://developers.openai.com/api/docs/guides/latest-model
LEON_OPENAI_AGENT_LLM=gpt-5.4
# LEON_OPENAI_AGENT_LLM=gpt-5.4-mini

# Anthropic API key
LEON_ANTHROPIC_API_KEY=
# Anthropic agent LLM
LEON_ANTHROPIC_AGENT_LLM=claude-opus-4-6
# LEON_ANTHROPIC_AGENT_LLM=claude-haiku-4-5

# Moonshot AI API key
LEON_MOONSHOTAI_API_KEY=
# Moonshot AI agent LLM
LEON_MOONSHOTAI_AGENT_LLM=kimi-k2.5

# HuggingFace API key
LEON_HUGGINGFACE_API_KEY=
# HuggingFace agent LLM
LEON_HUGGINGFACE_AGENT_LLM=meta-llama/Meta-Llama-3.1-8B-Instruct

# Cerebras API key
LEON_CEREBRAS_API_KEY=
# Cerebras agent LLM
LEON_CEREBRAS_AGENT_LLM=gpt-oss-120b

# Groq API key
LEON_GROQ_API_KEY=
# Groq agent LLM
LEON_GROQ_AGENT_LLM=llama-3.1-8b-instant

# Enable/disable Leon's wake word
LEON_WAKE_WORD=true

# Enable/disable Leon's speech-to-text
LEON_STT=true
# Speech-to-text provider
LEON_STT_PROVIDER=local

# Enable/disable Leon's text-to-speech
LEON_TTS=true
# Text-to-speech provider
LEON_TTS_PROVIDER=local

# Enable/disable LLM natural language generation
LEON_LLM_NLG=false
# Enable/disable LLM Action Recognition
# Can fallback to chit-chat if no action is recognized
LEON_LLM_ACTION_RECOGNITION=false

# Time zone (current one by default)
LEON_TIME_ZONE=

# Enable/disable after speech
LEON_AFTER_SPEECH=false

# Enable/disable skills to be available over HTTP
LEON_OVER_HTTP=true
# HTTP API key (use "npm run generate:http-api-key" to regenerate one)
LEON_HTTP_API_KEY=
# Language used for the HTTP API
LEON_HTTP_API_LANG=en-US

# Enable/disable telemetry
LEON_TELEMETRY=true

# Python TCP server
LEON_PY_TCP_SERVER_HOST=0.0.0.0
LEON_PY_TCP_SERVER_PORT=1342

# Path to the Pipfile
PIPENV_PIPFILE=tcp_server/src/Pipfile

# Path to the virtual env in .venv/
PIPENV_VENV_IN_PROJECT=true


================================================
FILE: .github/CODE_OF_CONDUCT.md
================================================
# Contributor Covenant Code of Conduct

## Our Pledge

In the interest of fostering an open and welcoming environment, we as
contributors and maintainers pledge to making participation in our project and
our community a harassment-free experience for everyone, regardless of age, body
size, disability, ethnicity, sex characteristics, gender identity and expression,
level of experience, education, socio-economic status, nationality, personal
appearance, race, religion, or sexual identity and orientation.

## Our Standards

Examples of behavior that contributes to creating a positive environment
include:

- Using welcoming and inclusive language
- Being respectful of differing viewpoints and experiences
- Gracefully accepting constructive criticism
- Focusing on what is best for the community
- Showing empathy towards other community members

Examples of unacceptable behavior by participants include:

- The use of sexualized language or imagery and unwelcome sexual attention or
  advances
- Trolling, insulting/derogatory comments, and personal or political attacks
- Public or private harassment
- Publishing others' private information, such as a physical or electronic
  address, without explicit permission
- Other conduct which could reasonably be considered inappropriate in a
  professional setting

## Our Responsibilities

Project maintainers are responsible for clarifying the standards of acceptable
behavior and are expected to take appropriate and fair corrective action in
response to any instances of unacceptable behavior.

Project maintainers have the right and responsibility to remove, edit, or
reject comments, commits, code, wiki edits, issues, and other contributions
that are not aligned to this Code of Conduct, or to ban temporarily or
permanently any contributor for other behaviors that they deem inappropriate,
threatening, offensive, or harmful.

## Scope

This Code of Conduct applies both within project spaces and in public spaces
when an individual is representing the project or its community. Examples of
representing a project or community include using an official project e-mail
address, posting via an official social media account, or acting as an appointed
representative at an online or offline event. Representation of a project may be
further defined and clarified by project maintainers.

## Enforcement

Instances of abusive, harassing, or otherwise unacceptable behavior may be
reported by contacting the project team at <louis@getleon.ai>. All
complaints will be reviewed and investigated and will result in a response that
is deemed necessary and appropriate to the circumstances. The project team is
obligated to maintain confidentiality with regard to the reporter of an incident.
Further details of specific enforcement policies may be posted separately.

Project maintainers who do not follow or enforce the Code of Conduct in good
faith may face temporary or permanent repercussions as determined by other
members of the project's leadership.

## Attribution

This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html

[homepage]: https://www.contributor-covenant.org

For answers to common questions about this code of conduct, see
https://www.contributor-covenant.org/faq


================================================
FILE: .github/CONTRIBUTING.md
================================================
# Contributing

Thanks a lot for your interest in contributing to Leon! :heart:

**Leon needs open source to live**, the more skills he has, the more skillful he becomes.

**Before submitting your contribution**, please take a moment to review this document.

Please note we have a [code of conduct](https://github.com/leon-ai/leon/blob/develop/.github/CODE_OF_CONDUCT.md), please follow it in all your interactions with the project.

## How You Can Help

Here are few examples about how you could help on Leon, by:

- [Creating a new module](https://docs.getleon.ai/packages-modules).
- [Working on new features](http://roadmap.getleon.ai) (what is in backlog or todo).
- [Suggesting new ideas](https://github.com/leon-ai/leon/issues/new/choose).
- [Reporting a bug](https://github.com/leon-ai/leon/issues/new?labels=bug&template=BUG.md).
- [Improving the documentation](https://github.com/leon-ai/docs.getleon.ai) (translations, typos, better writing, etc.).
- [Sponsoring Leon](http://sponsor.getleon.ai).

## Pull Requests

**Working on your first Pull Request?** You can learn how from this _free_ series [How to Contribute to an Open Source Project on GitHub](https://egghead.io/courses/how-to-contribute-to-an-open-source-project-on-github).

- **Please first discuss** the change you wish to make via [issue](https://github.com/leon-ai/leon/issues),
  email, or any other method with the owners of this repository before making a change.
  It might avoid a waste of your time.

- The `master` branch is actually used as a snapshot of the latest stable release. **Do not submit your PRs
  against the `master` branch**.

- Ensure your code **respect our coding standards** (cf. [.eslintrc.json](https://github.com/leon-ai/leon/blob/develop/.eslintrc.json)).
  To do so, you can run:

  ```sh
  npm run lint
  ```

- Make sure your **code passes the tests**. You can run the tests via the following command:

  ```sh
  npm test
  ```

  If you're adding new features to Leon, please include tests.

## Development Setup

Choose the setup method you want to go for.

### Single-Click

Gitpod will automatically set up an environment and run an instance for you.

[![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/#https://github.com/leon-ai/leon)

### Basic

```sh
# Clone the repository
git clone https://github.com/leon-ai/leon.git leon

# Go to the project root
cd leon

# Install
npm install

# Check the setup went well
npm run check

# Run the development server
npm run dev:server

# Run the development web app
npm run dev:app
```

## Versioning

- We use [Semantic Versioning](https://semver.org) for releases.

## Commits

The commit message guideline is adapted from the [AngularJS Git Commit Guidelines](https://github.com/angular/angular.js/blob/master/DEVELOPERS.md#-git-commit-guidelines).

### Types

Types define which kind of changes you made to the project.

| Types    | Description                                                                                              |
| -------- | -------------------------------------------------------------------------------------------------------- |
| BREAKING | Changes including breaking changes.                                                                      |
| build    | New build version.                                                                                       |
| chore    | Changes to the build process or auxiliary tools such as changelog generation. No production code change. |
| ci       | Changes related to continuous integration only (GitHub Actions, CircleCI, etc.).                         |
| docs     | Documentation only changes.                                                                              |
| feat     | A new feature.                                                                                           |
| fix      | A bug fix.                                                                                               |
| perf     | A code change that improves performance.                                                                 |
| refactor | A code change that neither fixes a bug nor adds a feature.                                               |
| style    | Changes that do not affect the meaning of the code (white-space, formatting, missing semi-colons, etc.). |
| test     | Adding missing or correcting existing tests.                                                             |

### Scopes

Scopes define high-level nodes of Leon.

- bridge/python
- bridge/nodejs
- hotword
- scripts
- server
- tcp server
- web app
- skill/skill_name

### Examples

```sh
git commit -m "feat(server): awesome new server feature"
git commit -m "docs(skill/leon): fix spelling"
git commit -m "chore: split training script into awesome blocks"
git commit -m "style(web app): remove chatbot useless parentheses"
```

### GUI Clients

If you are using a GUI client such as GitKraken, you may need to disable the default Git executable to make sure to use your default shell.
Otherwise you may encounter an error such as "npx not found".

## Sponsor

You can also contribute by [sponsoring Leon](http://sponsor.getleon.ai).

Please note that I dedicate most of my free time to Leon.

By sponsoring the project you make the project sustainable and faster to develop features.

The focus is not only limited to the activity you see on GitHub but also a lot of thinking about the direction of the project. Which is naturally related to the overall design, architecture, vision, learning process and so on...

## Contributing to the Python Bridge or TCP HttpServer

Leon makes use of two binaries, the Python bridge and the TCP server. These binaries are compiled from Python sources.

The Python bridge is used to communicate between the core and skills made with Python.

The TCP server is used to communicate between the core and third-party nodes, such as spaCy.

### Set Up the Python Environment

To contribute to these parts, you need to set up a Python environment running with a specific Python version and a specific Pipenv version.

It is recommended to use Pyenv to manage your Python versions.

If you are on GNU/Linux Ubuntu, you can run the following to install Pyenv, otherwise, please refer to the [Pyenv documentation to install it](https://github.com/pyenv/pyenv#installation):

```bash
# Update registry
sudo apt-get update

# Install Pyenv deps
sudo apt-get install make build-essential libssl-dev zlib1g-dev \
libbz2-dev libreadline-dev libsqlite3-dev wget curl llvm \
libncursesw5-dev xz-utils tk-dev libxml2-dev libxmlsec1-dev libffi-dev liblzma-dev

# Install Pyenv
curl https://pyenv.run | bash

# Add output lines to .bashrc

# Restart shell
exec "$SHELL"
```

Once Pyenv installed, run:

```bash
# Install Python
pyenv install 3.11.9 --force
pyenv global 3.11.9

# Install Pipenv
pip install pipenv==2024.0.1
```

Your Python environment should be ready now. So now you can set up the respective environments according to what you are going to contribute to and build them:

```bash
# Set up the Python bridge environment
npm run setup:python-bridge

# Set up the TCP server environment
npm run setup:tcp-server
# If you are in China, you can run this to download models faster:
npm run setup:tcp-server cn

# Once your code changes are done, you can build via:

# Build the Python bridge
npm run build:python-bridge

# Build the TCP server
npm run build:tcp-server

# Run the Python bridge
./bridges/python/dist/{OS-CPU_ARCH}/leon-python-bridge server/src/intent-object.sample.json

# Run the TCP server
./tcp_server/dist/{OS-CPU_ARCH}/leon-tcp-server en
```

## Spread the Word

Use [#LeonAI](<https://twitter.com/search?f=live&q=%23LeonAI%20(from%3Agrenlouis%20OR%20from%3Alouistiti_fr)&src=typed_query>) if you tweet about Leon and/or mention [@grenlouis](https://twitter.com/grenlouis).


================================================
FILE: .github/FUNDING.yml
================================================
# These are supported funding model platforms

github: [louistiti]
patreon: # Replace with a single Patreon username
open_collective: # Replace with a single Open Collective username
ko_fi: # Replace with a single Ko-fi username
tidelift: # Replace with a single Tidelift platform-name/package-name e.g., npm/babel
custom: # http://sponsor.getleon.ai


================================================
FILE: .github/ISSUE_TEMPLATE/BUG.md
================================================
---
name: 🐞 Bug Report
about: Report an unexpected problem or unintended behavior.
labels: bug
---

<!--
Thanks for your interest in Leon! ❤️
Please check if there is no similar issue before creating this one.
If the bug is related to the setup, please submit the issue at: https://github.com/leon-ai/leon-cli/issues/new/choose
-->

### Specs

- Leon version:
- OS (or browser) version:
- Node.js version:
- Complete "leon check" (or "npm run check") output:
- (optional) Leon skill version:

### Expected Behavior

### Actual Behavior

### How Do We Reproduce?

### Extra (like a sample repo to reproduce the issue, etc.)


================================================
FILE: .github/ISSUE_TEMPLATE/DOCS.md
================================================
---
name: 📝 Documentation
about: Are the docs missing, confusing, etc.? Tell us more about it.
---

<!--
Thanks for your interest in Leon! ❤️
If it is related to https://docs.getleon.ai, please open an issue there: https://github.com/leon-ai/docs.getleon.ai/issues.
Please check if there is no similar issue before creating this one.

Please place an x (no spaces - [x]) in all [ ] that apply.
-->

### Documentation Is:

- [ ] Missing
- [ ] Needed
- [ ] Confusing
- [ ] Not Sure?

### Explanation

### Proposal


================================================
FILE: .github/ISSUE_TEMPLATE/FEATURE_REQUEST.md
================================================
---
name: ✨ Feature Request
about: Suggest a new feature idea.
labels: feature request
---

<!--
Thanks for your interest in Leon! ❤️
Please check if there is no similar issue before creating this one.
-->

### Feature Use Case

### Feature Proposal


================================================
FILE: .github/ISSUE_TEMPLATE/IMPROVEMENT.md
================================================
---
name: 🔧 Improvement
about: Suggest an idea which is not a feature.
labels: improvement
---

<!--
Thanks for your interest in Leon! ❤️
Please check if there is no similar issue before creating this one.
-->

### Expected Behavior

### Actual Behavior

### Proposal


================================================
FILE: .github/ISSUE_TEMPLATE/QUESTION.md
================================================
---
name: ❓ Question
about: Ask a question about Leon.
labels: question
---

<!--
Thanks for your interest in Leon! ❤️
Please check if there is no similar issue before creating this one.

Please ask one question per issue.
-->

### Question


================================================
FILE: .github/PULL_REQUEST_TEMPLATE.md
================================================
<!--

Thanks a lot for your interest in contributing to Leon! :heart:

Please first discuss the change you wish to make via issue,
email, or any other method with the owners of this repository before making a change.
It might avoid a waste of your time.

Before submitting your contribution, please take a moment to review this document:
https://github.com/leon-ai/leon/blob/develop/.github/CONTRIBUTING.md

Please place an x (no spaces - [x]) in all [ ] that apply.

-->

### What type of change does this PR introduce?

- [ ] Bugfix
- [ ] Feature
- [ ] Refactor
- [ ] Documentation
- [ ] Not Sure?

### Does this PR introduce breaking changes?

- [ ] Yes
- [ ] No

### List any relevant issue numbers:

### Description:


================================================
FILE: .github/workflows/build.yml
================================================
name: Build

on:
  push:
    # branches: [master, develop]
    branches: [master]
  pull_request:
    # branches: [master, develop]
    branches: [master]

jobs:
  build:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v2

      - name: Use Python
        uses: actions/setup-python@v2
        with:
          python-version: 3.x

      - name: Use Node.js
        uses: actions/setup-node@v2
        with:
          node-version: 16.x
          cache: npm

      - name: Install Pipenv
        run: pip install --upgrade pip && pip install pipenv

      - name: Install
        run: npm install

      - name: Check setup
        run: npm run check

      - name: Build
        run: npm run build


================================================
FILE: .github/workflows/lint.yml
================================================
name: Lint

on:
  push:
    # branches: [master, develop]
    branches: [master]
  pull_request:
    # branches: [master, develop]
    branches: [master]

jobs:
  lint:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v2

      - name: Use Python
        uses: actions/setup-python@v2
        with:
          python-version: 3.x

      - name: Use Node.js
        uses: actions/setup-node@v2
        with:
          node-version: 16.x
          cache: npm

      - name: Install Pipenv
        run: pip install --upgrade pip && pip install pipenv

      - name: Install
        run: npm install

      - name: Run linter
        run: npm run lint


================================================
FILE: .github/workflows/pre-release-nodejs-bridge.yml
================================================
name: Pre-release Node.js bridge

on: workflow_dispatch

jobs:
  build:
    name: Build

    strategy:
      fail-fast: false
      matrix:
        include:
          - os: ubuntu-22.04
            arch: linux-x86_64
            python_arch: x64

    runs-on: ${{ matrix.os }}

    steps:
      - name: Clone repository
        uses: actions/checkout@v4

      - name: Install pnpm
        uses: pnpm/action-setup@v4
        with:
          version: latest

      - name: Install Node.js
        uses: actions/setup-node@v4
        with:
          node-version: lts/*

      - name: Create CI lockfile
        env:
          NPM_CONFIG_PACKAGE_LOCK: true
          PNPM_CONFIG_LOCKFILE: true
        run: pnpm install --lockfile-only --no-frozen-lockfile

      - name: Get pnpm store path
        id: pnpm-store
        shell: bash
        run: echo "path=$(pnpm store path --silent)" >> "$GITHUB_OUTPUT"

      - name: Cache pnpm store
        uses: actions/cache@v4
        with:
          path: ${{ steps.pnpm-store.outputs.path }}
          key: ${{ runner.os }}-pnpm-${{ matrix.arch }}-${{ hashFiles('pnpm-lock.yaml', 'package.json') }}
          restore-keys: |
            ${{ runner.os }}-pnpm-${{ matrix.arch }}-

      - name: Set Node.js bridge version
        working-directory: bridges/nodejs/src
        run: |
          echo "NODEJS_BRIDGE_VERSION=$(node --require fs --eval "const fs = require('node:fs'); const [, VERSION] = fs.readFileSync('version.ts', 'utf8').split(\"'\"); console.log(VERSION)")" >> $GITHUB_ENV

      - name: Display Node.js bridge version
        run: |
          echo "Node.js bridge version: ${{ env.NODEJS_BRIDGE_VERSION }}"

      - name: Install core
        run: pnpm install --no-frozen-lockfile

      - name: Build Node.js bridge
        run: pnpm run build:nodejs-bridge

      - name: Upload Node.js bridge
        uses: actions/upload-artifact@v4
        with:
          name: nodejs-bridge-${{ matrix.arch }}
          path: bridges/nodejs/dist/*.zip

  draft-release:
    name: Draft-release
    needs: [build]
    runs-on: ubuntu-latest

    steps:
      - name: Clone repository
        uses: actions/checkout@v4

      - name: Install Node.js
        uses: actions/setup-node@v4
        with:
          node-version: lts/*

      - name: Set Node.js bridge version
        working-directory: bridges/nodejs/src
        run: |
          echo "NODEJS_BRIDGE_VERSION=$(node --require fs --eval "const fs = require('node:fs'); const [, VERSION] = fs.readFileSync('version.ts', 'utf8').split(\"'\"); console.log(VERSION)")" >> $GITHUB_ENV

      - name: Download Node.js bridge
        uses: actions/download-artifact@v4
        with:
          path: bridges/nodejs/dist
          merge-multiple: true

      - name: Verify Node.js bridge assets
        shell: bash
        run: |
          set -euo pipefail
          ls -la bridges/nodejs/dist
          required=(
            "bridges/nodejs/dist/leon-nodejs-bridge.zip"
          )
          for asset in "${required[@]}"; do
            [ -f "$asset" ] || { echo "Missing asset: $asset"; exit 1; }
          done

      - name: Create draft release
        uses: softprops/action-gh-release@v2
        with:
          tag_name: nodejs-bridge_v${{ env.NODEJS_BRIDGE_VERSION }}
          name: Node.js Bridge ${{ env.NODEJS_BRIDGE_VERSION }}
          draft: true
          prerelease: false
          files: bridges/nodejs/dist/*.zip
          generate_release_notes: true
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}


================================================
FILE: .github/workflows/pre-release-python-bridge.yml
================================================
name: Pre-release Python bridge

on: workflow_dispatch

env:
  PIPENV_PIPFILE: bridges/python/src
  PIPENV_VENV_IN_PROJECT: true

jobs:
  build:
    name: Build

    strategy:
      fail-fast: false
      matrix:
        include:
          - os: ubuntu-latest
            arch: linux-x86_64
            python_arch: x64
          - os: ubuntu-22.04-arm
            arch: linux-aarch64
            python_arch: arm64
          - os: macos-15-intel
            arch: macosx-x86_64
            python_arch: x64
          - os: macos-latest
            arch: macosx-arm64
            python_arch: arm64
          - os: windows-latest
            arch: win-amd64
            python_arch: x64

    runs-on: ${{ matrix.os }}

    steps:
      - name: Clone repository
        uses: actions/checkout@v4

      - name: Install Python
        uses: actions/setup-python@v5
        with:
          python-version: 3.11.9
          architecture: ${{ matrix.python_arch }}

      - name: Install Pipenv
        run: pip install --upgrade pip && pip install pipenv==2024.0.1

      - name: Install pnpm
        uses: pnpm/action-setup@v4
        with:
          version: latest

      - name: Install Node.js
        uses: actions/setup-node@v4
        with:
          node-version: lts/*

      - name: Create CI lockfile
        env:
          NPM_CONFIG_PACKAGE_LOCK: true
          PNPM_CONFIG_LOCKFILE: true
        run: pnpm install --lockfile-only --no-frozen-lockfile

      - name: Get pnpm store path
        id: pnpm-store
        shell: bash
        run: echo "path=$(pnpm store path --silent)" >> "$GITHUB_OUTPUT"

      - name: Cache pnpm store
        uses: actions/cache@v4
        with:
          path: ${{ steps.pnpm-store.outputs.path }}
          key: ${{ runner.os }}-pnpm-${{ matrix.arch }}-${{ hashFiles('pnpm-lock.yaml', 'package.json') }}
          restore-keys: |
            ${{ runner.os }}-pnpm-${{ matrix.arch }}-

      - name: Set Python bridge version
        working-directory: bridges/python/src
        run: |
          echo "PYTHON_BRIDGE_VERSION=$(python -c "from version import __version__; print(__version__)")" >> $GITHUB_ENV

      - name: Display Python bridge version
        run: |
          echo "Python bridge version: ${{ env.PYTHON_BRIDGE_VERSION }}"

      - name: Install core
        run: pnpm install --no-frozen-lockfile

      - name: Set up Python bridge
        run: pnpm run setup:python-bridge

      - name: Build Python bridge
        run: pnpm run build:python-bridge

      - name: Upload Python bridge
        uses: actions/upload-artifact@v4
        with:
          name: python-bridge-${{ matrix.arch }}
          path: bridges/python/dist/*.zip

  draft-release:
    name: Draft-release
    needs: [build]
    runs-on: ubuntu-latest

    steps:
      - name: Clone repository
        uses: actions/checkout@v4

      - name: Install Python
        uses: actions/setup-python@v5
        with:
          python-version: 3.11.9

      - name: Set Python bridge version
        working-directory: bridges/python/src
        run: |
          echo "PYTHON_BRIDGE_VERSION=$(python -c "from version import __version__; print(__version__)")" >> $GITHUB_ENV

      - name: Download Python bridge
        uses: actions/download-artifact@v4
        with:
          path: bridges/python/dist
          merge-multiple: true

      - name: Verify Python bridge assets
        shell: bash
        run: |
          set -euo pipefail
          ls -la bridges/python/dist
          required=(
            "bridges/python/dist/leon-python-bridge-linux-aarch64.zip"
            "bridges/python/dist/leon-python-bridge-linux-x86_64.zip"
            "bridges/python/dist/leon-python-bridge-macosx-arm64.zip"
            "bridges/python/dist/leon-python-bridge-macosx-x86_64.zip"
            "bridges/python/dist/leon-python-bridge-win-amd64.zip"
          )
          for asset in "${required[@]}"; do
            [ -f "$asset" ] || { echo "Missing asset: $asset"; exit 1; }
          done

      - name: Create draft release
        uses: softprops/action-gh-release@v2
        with:
          tag_name: python-bridge_v${{ env.PYTHON_BRIDGE_VERSION }}
          name: Python Bridge ${{ env.PYTHON_BRIDGE_VERSION }}
          draft: true
          prerelease: false
          files: bridges/python/dist/*.zip
          generate_release_notes: true
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}


================================================
FILE: .github/workflows/pre-release-tcp-server.yml
================================================
name: Pre-release TCP server

on: workflow_dispatch

env:
  PIPENV_PIPFILE: tcp_server/src
  PIPENV_VENV_IN_PROJECT: true

jobs:
  build:
    name: Build

    strategy:
      fail-fast: false
      matrix:
        include:
          - os: ubuntu-latest
            arch: linux-x86_64
            python_arch: x64
          - os: ubuntu-22.04-arm
            arch: linux-aarch64
            python_arch: arm64
          - os: macos-15-intel
            arch: macosx-x86_64
            python_arch: x64
          - os: macos-latest
            arch: macosx-arm64
            python_arch: arm64
          - os: windows-latest
            arch: win-amd64
            python_arch: x64

    runs-on: ${{ matrix.os }}

    steps:
      - name: Clone repository
        uses: actions/checkout@v4

      - name: Install Python
        uses: actions/setup-python@v5
        with:
          python-version: 3.11.9
          architecture: ${{ matrix.python_arch }}

      - name: Install PortAudio (Linux)
        if: runner.os == 'Linux'
        run: sudo apt-get update && sudo apt-get install -y portaudio19-dev

      - name: Install PortAudio (macOS)
        if: runner.os == 'macOS'
        run: brew install portaudio

      - name: Install Pipenv
        run: pip install --upgrade pip && pip install pipenv==2024.0.1

      - name: Install pnpm
        uses: pnpm/action-setup@v4
        with:
          version: latest

      - name: Install Node.js
        uses: actions/setup-node@v4
        with:
          node-version: lts/*

      - name: Create CI lockfile
        env:
          NPM_CONFIG_PACKAGE_LOCK: true
          PNPM_CONFIG_LOCKFILE: true
        run: pnpm install --lockfile-only --no-frozen-lockfile

      - name: Get pnpm store path
        id: pnpm-store
        shell: bash
        run: echo "path=$(pnpm store path --silent)" >> "$GITHUB_OUTPUT"

      - name: Cache pnpm store
        uses: actions/cache@v4
        with:
          path: ${{ steps.pnpm-store.outputs.path }}
          key: ${{ runner.os }}-pnpm-${{ matrix.arch }}-${{ hashFiles('pnpm-lock.yaml', 'package.json') }}
          restore-keys: |
            ${{ runner.os }}-pnpm-${{ matrix.arch }}-

      - name: Set TCP server version
        working-directory: tcp_server/src
        run: |
          echo "TCP_SERVER_VERSION=$(python -c "from version import __version__; print(__version__)")" >> $GITHUB_ENV

      - name: Display TCP server version
        run: |
          echo "TCP server version: ${{ env.TCP_SERVER_VERSION }}"

      - name: Install core
        run: pnpm install --no-frozen-lockfile

      - name: Set up TCP server
        run: pnpm run setup:tcp-server

      - name: Build TCP server
        run: pnpm run build:tcp-server

      - name: Upload TCP server
        uses: actions/upload-artifact@v4
        with:
          name: tcp-server-${{ matrix.arch }}
          path: tcp_server/dist/*.zip

  draft-release:
    name: Draft-release
    needs: [build]
    runs-on: ubuntu-latest

    steps:
      - name: Clone repository
        uses: actions/checkout@v4

      - name: Install Python
        uses: actions/setup-python@v5
        with:
          python-version: 3.11.9

      - name: Set TCP server version
        working-directory: tcp_server/src
        run: |
          echo "TCP_SERVER_VERSION=$(python -c "from version import __version__; print(__version__)")" >> $GITHUB_ENV

      - name: Download TCP server
        uses: actions/download-artifact@v4
        with:
          path: tcp_server/dist
          merge-multiple: true

      - name: Verify TCP server assets
        shell: bash
        run: |
          set -euo pipefail
          ls -la tcp_server/dist
          required=(
            "tcp_server/dist/leon-tcp-server-linux-aarch64.zip"
            "tcp_server/dist/leon-tcp-server-linux-x86_64.zip"
            "tcp_server/dist/leon-tcp-server-macosx-arm64.zip"
            "tcp_server/dist/leon-tcp-server-macosx-x86_64.zip"
            "tcp_server/dist/leon-tcp-server-win-amd64.zip"
          )
          for asset in "${required[@]}"; do
            [ -f "$asset" ] || { echo "Missing asset: $asset"; exit 1; }
          done

      - name: Create draft release
        uses: softprops/action-gh-release@v2
        with:
          tag_name: tcp-server_v${{ env.TCP_SERVER_VERSION }}
          name: TCP Server ${{ env.TCP_SERVER_VERSION }}
          draft: true
          prerelease: false
          files: tcp_server/dist/*.zip
          generate_release_notes: true
        env:
          GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}


================================================
FILE: .github/workflows/tests.yml
================================================
name: Tests

on:
  push:
    # branches: [master, develop]
    branches: [master]
  pull_request:
    # branches: [master, develop]
    branches: [master]

jobs:
  tests:
    runs-on: ubuntu-latest

    steps:
      - uses: actions/checkout@v2

      - name: Use Python
        uses: actions/setup-python@v2
        with:
          python-version: 3.x

      - name: Use Node.js
        uses: actions/setup-node@v2
        with:
          node-version: 16.x
          cache: npm

      - name: Install Pipenv
        run: pip install --upgrade pip && pip install pipenv

      - name: Install
        run: npm install

      - name: Run JSON tests
        run: npm run test:json

      - name: Run over HTTP tests
        run: npm run test:over-http

      - name: Run E2E tests
        run: npm run test:e2e

      - name: Install offline STT
        run: npm run setup:offline-stt

      - name: Install offline TTS
        run: npm run setup:offline-tts

      - name: Run unit tests
        run: npm run test:unit


================================================
FILE: .gitignore
================================================
__pycache__/
.idea/
.fleet/
.vscode/
**/dist/*
**/build/
**/node_modules/
test/coverage/
**/tmp/*
**/src/.venv/*
logs/*
!logs/.gitkeep
!logs/prompts/
logs/prompts/*
!logs/prompts/.gitkeep
!logs/tool-outputs/.gitkeep
core/context/*[.md, .json]
!core/context/LEON.md
!core/context/ARCHITECTURE.md
core/context/private/
core/memory/*
!core/memory/.gitkeep
core/config/**/*.json
bin/coqui/*
bin/flite/*
bin/nvidia/*
bin/pytorch/torch
bin/llama.cpp/llama.cpp
bin/cmake/cmake
bin/ninja/ninja
scripts/out/*.md

package-lock.json
*.pyc
.DS_Store
*.sublime-workspace
npm-debug.log
debug.log
.env
.last-skill-npm-install
leon.json
bridges/python/src/Pipfile.lock
bridges/toolkits/**/bins
bridges/toolkits/**/settings/*
tcp_server/src/Pipfile.lock
!core/context/*/.gitkeep
!tcp_server/**/.gitkeep
!bridges/toolkits/**/.gitkeep
!bridges/python/**/.gitkeep
!bridges/nodejs/**/.gitkeep
!**/*.sample*
skills/**/src/settings.json
skills/**/memory/*.json
bridges/toolkits/**/settings/*.json
core/data/models/*.nlp
core/data/models/*.json
core/data/models/llm/*
core/data/models/audio/tts/**/*.*
!core/data/models/audio/tts/config.json
core/data/models/audio/asr/**/*.*
!core/data/models/**/.gitkeep
package.json.backup
.python-version
schemas/**/*.json


================================================
FILE: .gitpod.yml
================================================
image: gitpod/workspace-full

tasks:
  - before: npm install -g @leon-ai/cli
    init: leon create birth
    command: leon start

ports:
  - port: 1337
    onOpen: notify

github:
  prebuilds:
    master: true
    branches: true
    pullRequests: true
    addComment: true
    addBadge: true
    addLabel: true


================================================
FILE: .husky/commit-msg
================================================
if ! [ -x "$(command -v npm)" ]; then
  echo "npm: command not found"
  echo "If you use a version manager tool such as nvm and a git GUI such as GitKraken, please read: https://typicode.github.io/husky/how-to.html#node-version-managers-and-guis" >&2
  exit 1
else
  npx tsx scripts/commit-msg.js
fi



================================================
FILE: .husky/pre-commit
================================================
if ! [ -x "$(command -v npm)" ]; then
  echo "npm: command not found"
  echo "If you use a version manager tool such as nvm and a git GUI such as GitKraken, please read: https://typicode.github.io/husky/how-to.html#node-version-managers-and-guis" >&2
  exit 1
else
  npm run pre-commit
fi


================================================
FILE: .lintstagedrc
================================================
{
  "*": ["npm run lint"]
}


================================================
FILE: .npmrc
================================================
engine-strict=true
package-lock=false
save-exact=true


================================================
FILE: .nvmrc
================================================
lts/*


================================================
FILE: CHANGELOG.md
================================================
# [1.0.0-beta.8](https://github.com/leon-ai/leon/compare/v1.0.0-beta.7...v1.0.0-beta.8) (2023-05-01) / Binaries and TypeScript Rewrite

_Please refer to [our latest blog post](https://blog.getleon.ai/binaries-and-typescript-rewrite-1-0-0-beta-8/) for more information on the new release of our dear Leon._

# [1.0.0-beta.7](https://github.com/leon-ai/leon/compare/v1.0.0-beta.6...v1.0.0-beta.7) (2022-08-24) / A Much Better NLP

_Please [read this blog post](https://blog.getleon.ai/a-much-better-nlp-and-future-1-0-0-beta-7/) to know more about all the new features and the exciting future of Leon._

### BREAKING CHANGES

- remove legacy packages [07743657](https://github.com/leon-ai/leon/commit/07743657cd2954e7f850c08eea7c032c24b28a96)

### Features

- create new NLP skills resolvers model + NLP global resolvers model [602604e4](https://github.com/leon-ai/leon/commit/602604e43788c6b6be8c402d54fe54342d0cd5d6)
- better isolate skill resolvers from global resolvers + finish up Akinator skill [905d248e](https://github.com/leon-ai/leon/commit/905d248ebf7e84b1ccc74450520228aef9a8804a)
- transfer language from core to skills + support thematics on Akinator skill [b35a249b](https://github.com/leon-ai/leon/commit/b35a249bf68000d6708aaee4abc4cd97f5b80035)
- actions on slot level + akinator skill progress [7101b8b4](https://github.com/leon-ai/leon/commit/7101b8b4b828b49e009da2fcdac7c5ed2e48c8f8)
- add Cartesian sample training on resolvers + enum entities [6ed88a59](https://github.com/leon-ai/leon/commit/6ed88a5946c77b356e49fe8b9cbe890b8dd1f037)
- map skills resolvers intents [eb5ade76](https://github.com/leon-ai/leon/commit/eb5ade76844dd14f5d5a5c5eeb434eed70fe62f4)
- train skills resolvers and remap as per changes [82df0a3c](https://github.com/leon-ai/leon/commit/82df0a3c235fbd50ad0cfe12e23a51f777dcd658)
- achieve Cartesian training [a1e9011d](https://github.com/leon-ai/leon/commit/a1e9011d5db48ed8e9f49cef2d813ee7e2400ec2)
- introduce suggestions [dcddacca](https://github.com/leon-ai/leon/commit/dcddacca2956529de0aea8ff98e1e6f16104966a)
- communicate suggestions to the client [4b5a8835](https://github.com/leon-ai/leon/commit/4b5a883510fd4421a491f999cc21d8f7dd369a03)
- shared skills memory [795acc5b](https://github.com/leon-ai/leon/commit/795acc5bdd29e9a27d1cf3b4407453648d573973)
- support dynamic variables on skill NLU settings for logic type [10d10a16](https://github.com/leon-ai/leon/commit/10d10a1690cb65970932ee7230e3f324ec67dbce)
- tmp resolvers mapping [b1a332ba](https://github.com/leon-ai/leon/commit/b1a332bab6af8b74a8c58c07bac3ef3a1cebad89)
- start to map resolvers between the core and skills [e88495a9](https://github.com/leon-ai/leon/commit/e88495a9a94e86026fd0c7c4c44f3ff06edb2e80)
- train affirmation and denial resolver [993d52e8](https://github.com/leon-ai/leon/commit/993d52e8686f335039ff3d5e2a82c1a37efb1825)
- Python TCP server and Node.js TCP client for IPC (wip) [5970ec9e](https://github.com/leon-ai/leon/commit/5970ec9e8e4c2784c50e2ddc76b34b71aa4310e6)
- introduce spaCy for complete NER (wip) [caa86fc8](https://github.com/leon-ai/leon/commit/caa86fc8a6850b18f67ba7bedb423be693a88d17)
- slot filling (wip) [76547d94](https://github.com/leon-ai/leon/commit/76547d9411c32e0eb2ccfdac3a4901d2d2fb37f6)
- share data across domains [f4f9fff9](https://github.com/leon-ai/leon/commit/f4f9fff9783861be183990d7869973c7a30c8104)
- dynamic variable binding on NLG [0367b44f](https://github.com/leon-ai/leon/commit/0367b44f211c1629fffe6981a730f171707bf0c0)
- context and slot filling preparation (wip) [975b8ebc](https://github.com/leon-ai/leon/commit/975b8ebcf00db91b44dd067be6dde5c1bf32fff1)
- annotate entities on the fly + prepare for dialog skill type and cross-domains data [4107932d](https://github.com/leon-ai/leon/commit/4107932d000086188d6f44ef67b73cc322fc58e5)
- new NLP training [d8023308](https://github.com/leon-ai/leon/commit/d8023308d0ef1f3eede37f21f45daa2f893031b0)

- **server:**
  - trigger next action suggestions or current ones [244d08c0](https://github.com/leon-ai/leon/commit/244d08c0bd0fea315269f52ab899f9b7fe083f51)
  - introduce main NLP model and resolvers NLP model [e37526d9](https://github.com/leon-ai/leon/commit/e37526d9056d858ebcf17b81f6714f47b67c77cb)
  - change log emojis [843bc428](https://github.com/leon-ai/leon/commit/843bc428b8deb397e2d051a8e0bfaf1b82b459a2)
  - provide nextAction even when no slot is set and clean up NLU object on context switch [8377c63d](https://github.com/leon-ai/leon/commit/8377c63db4e4e42ed929171cd8b9abdb13c44b2a)
  - report full traceback from skills execution [b69b1fea](https://github.com/leon-ai/leon/commit/b69b1fea16250421bc7d5def1c973dd43e453071)
  - support on-the-fly entity annotation for built-in entities [567b030c](https://github.com/leon-ai/leon/commit/567b030c4fcf8df266c39cca61a146fb33b9e0fc)
  - save slots within conversation context [fce47cdb](https://github.com/leon-ai/leon/commit/fce47cdbd570993ac5cca2b4ff5bc97969df4e40)
  - resolve resolvers tmp [ceea47ff](https://github.com/leon-ai/leon/commit/ceea47ff7dd536bfd3adf3cc355e90e3e94b1cbd)
  - prepare the next action on non-slot-filled skills [0acb31a9](https://github.com/leon-ai/leon/commit/0acb31a9c61c1c094b29f3d0ff2647d625eab0be)
  - add more affirmative utterance samples [870ab2e8](https://github.com/leon-ai/leon/commit/870ab2e87eba2c548d38dc90d30553e7fa380c1e)
  - restart a skill with the original utterance saved in context [f4446ef1](https://github.com/leon-ai/leon/commit/f4446ef17796d38d0f98d5b7e889503622a1a998)
  - clean up context if the action loop does not meet the expected items [035c9d52](https://github.com/leon-ai/leon/commit/035c9d5240472ac19a84ae8c1a87844fa0d0af5d)
  - add handsigns custom entity [1529c720](https://github.com/leon-ai/leon/commit/1529c72039092c7b8f37304d6064e04f2dc7b795)
  - reprocess NLU in case of slot filling interruption [9e242d77](https://github.com/leon-ai/leon/commit/9e242d77d32109e9355eec422790a5a66fd18f9c)
  - handle action loop when slots have all been filled at once [f8830502](https://github.com/leon-ai/leon/commit/f88305020a5bc79056b7ff9c1a31f8d3c3a7cdce)
  - break the action loop from the skill [27dc801c](https://github.com/leon-ai/leon/commit/27dc801cf53de5af3d54b95f42d2b9e627090867)
  - stop action loop from skill to core [99681e25](https://github.com/leon-ai/leon/commit/99681e257795a18361be379b93244088401f640b)
  - introduce basic concept of action loop [c5b38400](https://github.com/leon-ai/leon/commit/c5b38400821e5bc5edc4402d007f815f24319d44)
  - prepare action loop feature [19e1aa22](https://github.com/leon-ai/leon/commit/19e1aa22f6e989e90eb745e3a7b7ccb8ff5adbfa)
  - add current utterance entities to differentiate from the whole context [8b56a185](https://github.com/leon-ai/leon/commit/8b56a1850c9d76e335f1bad1b4395d73ddc5ea19)
  - when a context is activated, pick up the most probable classification [8e186879](https://github.com/leon-ai/leon/commit/8e1868798c8750c19b1719a44dc6fb8bca68b250)
  - persist entities into contexts [87575773](https://github.com/leon-ai/leon/commit/875757739f6701f54805eeff2c7c350cff36c4ac)
  - forward slots to skill + add original utterance [68e40f65](https://github.com/leon-ai/leon/commit/68e40f65df0d1fe29ccad991868a2408c6e1015e)
  - handle case when all slots have been filled in one utterance [22e9234b](https://github.com/leon-ai/leon/commit/22e9234b3d2c97e83eaafaeeb5aa9d27c351c95a)
  - trigger next action once all slots have been filled [9b870010](https://github.com/leon-ai/leon/commit/9b870010dd929bc1aed6d87696f1cc4e9f177c0b)
  - complete slot filling before triggering the next action [9124687e](https://github.com/leon-ai/leon/commit/9124687eb0e17295a30f860752ee622ba44d1440)
  - from modules to skills with type at the actions level [77ebaf4a](https://github.com/leon-ai/leon/commit/77ebaf4a9c78b2e471d39872e361ea05b163580d)
  - verify if all slots are filled [e27c1b9c](https://github.com/leon-ai/leon/commit/e27c1b9c8f5c2f668f464f152ad227d65ba5ef6b)
  - context and slot filling, keep context and await for entities [25adf406](https://github.com/leon-ai/leon/commit/25adf406c810e48b1277105dd6c269a2ed601d28)
  - unstack oldest context [1ece25a4](https://github.com/leon-ai/leon/commit/1ece25a497acc9f9876fe158ace5da38beec31e6)
  - context setup with slot for each conversation (wip) [8257eb87](https://github.com/leon-ai/leon/commit/8257eb8792c9f4fc90bcc1b393d3fddf8ff541dc)
  - resolve slots from slot filling [960a6dc7](https://github.com/leon-ai/leon/commit/960a6dc71c2efb50ad6a8448d447ebd79c559c41)
  - pickup questions for slot filling [3bbc2f8a](https://github.com/leon-ai/leon/commit/3bbc2f8a254d10f0c37cdb7abf016b3e418f594a)
  - main slots structure (wip) [1d9b1809](https://github.com/leon-ai/leon/commit/1d9b18093b6e042ae49f557149a7822b4420cdb8)
  - introduce resolvers for slot filling (wip) [334bf393](https://github.com/leon-ai/leon/commit/334bf393f2c43edd326d9de2e93c037ffeebeab5)
  - slot filling PoC (tmp wip) [95bfcfe4](https://github.com/leon-ai/leon/commit/95bfcfe422f21a2946e50031a3623675dfe81b9d)
  - slot filling (wip) [969a83e6](https://github.com/leon-ai/leon/commit/969a83e6081de20ec5e2bdd0329a21a3fe448f13)
  - trigger unsupported language [1845eed7](https://github.com/leon-ai/leon/commit/1845eed71dadd5f693d76abd7633864014bf8af1)
  - context (wip) [d1c2a11d](https://github.com/leon-ai/leon/commit/d1c2a11d8284ca4e1d4563b871c50c006e8ef8a0)
  - context (wip) [a9a43ac4](https://github.com/leon-ai/leon/commit/a9a43ac478c46f3832d2af49c287bb574a70cc14)
  - differenciate cities from countries for location entities [bf9bf231](https://github.com/leon-ai/leon/commit/bf9bf231f714e1edc1417e43af12fa54c00ba064)
  - auto restart the TCP server when language is switching [9be7c700](https://github.com/leon-ai/leon/commit/9be7c700767672ac6e0c875d3b5ae7fa6414e4fa)
  - support multi languages on TCP server [a808742c](https://github.com/leon-ai/leon/commit/a808742c927d45c18df45af133e67c98d4a0415a)
  - add auto reconnect on TCP client [cbe89ed6](https://github.com/leon-ai/leon/commit/cbe89ed6ccfd727356eb34078a8a4348b2fd696f)
  - make TCP client global [006e9fb0](https://github.com/leon-ai/leon/commit/006e9fb01148c2107f6acc6a562ace4809da92be)
  - fully implement low-level networking for IPC [8acb82da](https://github.com/leon-ai/leon/commit/8acb82da9bacdb9b7952c4a4d130d094e07def5e)
  - more accurate NLG [d5577b1e](https://github.com/leon-ai/leon/commit/d5577b1ef5cf1b8b4a924636ba4425b8b4ae133d)
  - unknown_answers fallback on dialog type [28efe6e7](https://github.com/leon-ai/leon/commit/28efe6e7d542f19bf12ddede1815f7fa8cf01036)
  - deep data mapping on enum NER [3ca48265](https://github.com/leon-ai/leon/commit/3ca48265e7115c8e0f02c65ba92d90412325ad76)
  - NLG and entities mapping [8f2f935b](https://github.com/leon-ai/leon/commit/8f2f935b949ceb965941460d4ff1ed0084b72442)
  - bootstrap skill structure [fe90c68e](https://github.com/leon-ai/leon/commit/fe90c68ea0e9b0e857b62aa9f3b0a42ba1ffed6b)
  - on-the-fly language switching [f24513a2](https://github.com/leon-ai/leon/commit/f24513a22395d1903e485883f4813cdceccdbd18)
  - new NLP containers [34b2aa56](https://github.com/leon-ai/leon/commit/34b2aa5655e55284d59db4569960c49965a0483c)
  - (WIP) NLU refactoring [ca3f5f42](https://github.com/leon-ai/leon/commit/ca3f5f42da26eb634e10b56e9b84bd45b5543024)
  - add skills domains [cf2a28aa](https://github.com/leon-ai/leon/commit/cf2a28aac2d936cc15e6aa9aa13747015d952053)
- **skill/akinator:**
  - finish up [79e7df02](https://github.com/leon-ai/leon/commit/79e7df022f7daedf43db7f892e049a31924ce985)
  - finished main business logic [76cae42f](https://github.com/leon-ai/leon/commit/76cae42fdeac0edcd3ebd6aa7718728617687b1b)
  - backbone [02a2f714](https://github.com/leon-ai/leon/commit/02a2f71470bb4c0c6ca04526e89461d863d17145)
- **skill/birthday:**
  remove birthday skill [be0b345d](https://github.com/leon-ai/leon/commit/be0b345d3f7fea562548e3fbed62b65c32eff4c0)
- **skill/color:**
  introduce color skill [ce00989b](https://github.com/leon-ai/leon/commit/ce00989b01f65c5cbb5a2e13f454207c1ba7741c)
- **skill/guess_the_number:**
  introduce the Guess the Number skill [fba80966](https://github.com/leon-ai/leon/commit/fba80966c937a32182e48670c47358babb539d64)
- **skill/introduction:**
  - add one utterance sample [af0fdd1e](https://github.com/leon-ai/leon/commit/af0fdd1e18975bf8b60abb2957ddf79831281817)
  - ask about owner info if necessary [c5cc9bdd](https://github.com/leon-ai/leon/commit/c5cc9bdd52afaaa710f9476d1e9918f3d168e243)
- **skill/mbti:**
  - complete form resolver [aad9f3f1](https://github.com/leon-ai/leon/commit/aad9f3f1ef61499d438ea40c9d2d95764667678d)
  - finish business logic [99a3f103](https://github.com/leon-ai/leon/commit/99a3f103e00b5a58745ee851d2fa95c61871f75a)
  - questions mapping [ae4f69f7](https://github.com/leon-ai/leon/commit/ae4f69f7c7189ff75e004f68c9a2a8b6bb37b6bd)
  - complete questionnaire [7f1f8871](https://github.com/leon-ai/leon/commit/7f1f8871598746c5475b24e086ea6e581f2a988e)
  - main logic backbone [33109a4c](https://github.com/leon-ai/leon/commit/33109a4c8b5df82e7b98e48e66f8d53f0cc114fb)
  - main NLU structure [skip ci] [86d5040a](https://github.com/leon-ai/leon/commit/86d5040a7dc2006036c7e67a2cf54a4c992e64aa)
- **skill/rochambeau:**
  - add start answers [192dd0a8](https://github.com/leon-ai/leon/commit/192dd0a87ab5dc025bb90b20b187e36a58be54ea)
  - introduce paper scissors rock [57370470](https://github.com/leon-ai/leon/commit/573704706c843d870f2498146bc3cd659bab4f06)
  - init [7f5e30ac](https://github.com/leon-ai/leon/commit/7f5e30ac82f2a2d7579e361229a4044348915867)
- **web app:**
  - join us on Discord [141c89ec](https://github.com/leon-ai/leon/commit/141c89ecbfd329a8e63d5a603d0ae6b42f9abf38)
  - wait for TCP client to be connected first [bc228a68](https://github.com/leon-ai/leon/commit/bc228a68600c07871c489d6624bbc837971079a6)
  ### Bug Fixes
- check script with new intent-object format [fdf0a389](https://github.com/leon-ai/leon/commit/fdf0a389b76caba5dd47996a43a34c0c7821c70a)
- check new resolvers paths [cfd8f7cb](https://github.com/leon-ai/leon/commit/cfd8f7cbe5e8fd9ce3d1659c725d7af261db8d71)
- use ports.ubuntu.com mirror for the offline TTS [skip ci] [3dd90396](https://github.com/leon-ai/leon/commit/3dd9039678820fceb7ccbb1c96358c8d2f188ede)
- set skill config only when a bridge is set [7513aa7d](https://github.com/leon-ai/leon/commit/7513aa7d20fee1fe9ca5442a7909d22fd1c3b39e)
- only set skill config when it is a logic type [9ce9a8bc](https://github.com/leon-ai/leon/commit/9ce9a8bc4fe0864730a08d8e9a436982f1365aa5)
- **docker:**
  - usage of Ubuntu base image with pyenv and nvm (#408) [f507f6f7](https://github.com/leon-ai/leon/commit/f507f6f7e499f56768b3e624164cbcd58193b153)
  - check should not allocate a pseudo-TTY (#359) [4372b45f](https://github.com/leon-ai/leon/commit/4372b45fc605893d4130cf7110dd87519b934345)
- **server:**
  - make leon handle multiple socket.io-client instances [6e7c0aac](https://github.com/leon-ai/leon/commit/6e7c0aac57008b152b45f1b0f3886ae38777467b)
  - fallback on global resolver during resolver classification [ec77dd0f](https://github.com/leon-ai/leon/commit/ec77dd0f02a8ae94fb3f02c7b7847b5509d71406)
  - make use of current entities to match global entities [a8d82050](https://github.com/leon-ai/leon/commit/a8d82050c86b5c24c4c898c06e5ffc3882524c0b)
  - multiple slots filling [2ac1bc63](https://github.com/leon-ai/leon/commit/2ac1bc63ccd11757d586adfb2e75ce04e3ffbcb5)
  - context switching on action loop [6712ae55](https://github.com/leon-ai/leon/commit/6712ae5539ef44ed33e360cfcad71c760c4b13b1)
  - check one-shot slot filling case causing infinite loop [782a3aaa](https://github.com/leon-ai/leon/commit/782a3aaa0a07dda667557bc84db906b3fa9b237c)
  - clean up active context after all slots have been filled [faabc2c7](https://github.com/leon-ai/leon/commit/faabc2c7b0992fcea035eedf66103d84b101e1a7)
  - correctly extract all spaCy entities [6aa60bfb](https://github.com/leon-ai/leon/commit/6aa60bfbd8c72e678fe3faf5e7f9dbd37dfd209f)
  - intent not found [8280c658](https://github.com/leon-ai/leon/commit/8280c65897dba0fe470a3589d151b391c51e344e)
  - fallback due to modules to skills refactoring [ef0c54b2](https://github.com/leon-ai/leon/commit/ef0c54b22667ef2bd1d2c07003f6b4beb5fa25c0)
  - NER due to modules to skills refactoring [e4d3904c](https://github.com/leon-ai/leon/commit/e4d3904ceeb2a3ee2c0187a1817331fac916e1a7)
  - **skill/akinator:**
    remove direct end on guess action [f6461f73](https://github.com/leon-ai/leon/commit/f6461f733b4a5d944dfa4a987dd1109628c6cbca)
  - **skill/color:**
    more appropriate answer [cb18ed63](https://github.com/leon-ai/leon/commit/cb18ed6397cb0e0ad8fbea30c57d7d40137441ee)
  - **skill/rochambeau:**
    final logic [0ebc0518](https://github.com/leon-ai/leon/commit/0ebc0518e61b899c35dd13df65a43f69399e784d)
  ### Performance Improvements
- check Pipfile instead of Pipfile.lock to judge whether Python packages must be installed [afdb71f7](https://github.com/leon-ai/leon/commit/afdb71f766f2956c5cb4a5e0be9025340d1a89db)

### Documentation Changes

- change newsletter link [4bf2a9af](https://github.com/leon-ai/leon/commit/4bf2a9af963f75aeff96f4a43da8ec1024ac583a)
- README - Edited sentence for clarity (#389) [e83a1c42](https://github.com/leon-ai/leon/commit/e83a1c4230897e8b63251ef86225cf773148c38e)
- edit newsletter link [fa558a44](https://github.com/leon-ai/leon/commit/fa558a447ade4071f352d56f14602690ed90f521)
- update sponsor [skip ci] [f30ddb6b](https://github.com/leon-ai/leon/commit/f30ddb6be5f531df2b0042be0ed5ffbe79f73b07)
- remove sponsor [skip ci] [5dbc010f](https://github.com/leon-ai/leon/commit/5dbc010fa643279a24081f3148022e2211af63f4)
- remove sponsor [skip ci] [f36dd20f](https://github.com/leon-ai/leon/commit/f36dd20f822cd33c9e8a03efc2849c8d8d1fc75e)
- remove sponsor [skip ci] [5ee57ddf](https://github.com/leon-ai/leon/commit/5ee57ddf2a9f7817ec35b2e70d49e5bb422d8f78)
- add @ant-media sponsor [skip ci] [b47cbc3a](https://github.com/leon-ai/leon/commit/b47cbc3a5ecb6591f7abb4f62feae8102b9a6468)
- add long dev notice to README [skip ci] [499be77d](https://github.com/leon-ai/leon/commit/499be77d509231b853f591e27f726381da5a50d8)
- move sponsor to new section [skip ci] [8825d687](https://github.com/leon-ai/leon/commit/8825d6877c19d86495e89a858b859b7ab1f9ae37)
- change Twitter handle [skip ci] [c1afc11c](https://github.com/leon-ai/leon/commit/c1afc11cdb283526540d0fecdf83efddf3f3a9f7)
- remove sponsor [skip ci] [99b401a6](https://github.com/leon-ai/leon/commit/99b401a668a6fb248e33c22782940402be7c9b17)
- add new sponsor self-hosted img [skip ci] [238d928c](https://github.com/leon-ai/leon/commit/238d928cace13d4ecd174ca14b136967d8845e0f)
- remove new sponsor link (broken) [skip ci] [254f2848](https://github.com/leon-ai/leon/commit/254f2848aab622b79cce16d10c58d53ff6db9a8f)
- in GitHub BUG.md from modules to skills [4a5480a3](https://github.com/leon-ai/leon/commit/4a5480a3ccc54ee34d42f6edcec2a40224dee7ed)
- change @FluxIndustries sponsorship [skip ci] [1a118b71](https://github.com/leon-ai/leon/commit/1a118b718e5d4ade123756ac94758a01c50b12ae)
- add @FluxIndustries sponsor [skip ci] [9a604d7c](https://github.com/leon-ai/leon/commit/9a604d7ccc0c6aaec257299078141dd0c3077933)
- new #LeonAI link [skip ci] [a0107d62](https://github.com/leon-ai/leon/commit/a0107d629473f7fd057d367926e83822d46f1227)
- changelog new version diff link fix [skip ci] [e14c2498](https://github.com/leon-ai/leon/commit/e14c249826db92af7b85422e566be6aa834a7fb7)

# [1.0.0-beta.6](https://github.com/leon-ai/leon/compare/v1.0.0-beta.5...v1.0.0-beta.6) (2022-02-07) / Leon Over HTTP + Making Friends with Coqui STT

### Features

- simple coqui-ai stt integration [86a4816b](https://github.com/leon-ai/leon/commit/86a4816b777fee8ec9c89648c5866a75de56c017)
- HTTP API key generator [d10a7fa7](https://github.com/leon-ai/leon/commit/d10a7fa7880a0bf2fb1cae7904d1ef4257f05257)
- avoid unnecessary routes generation

- **server:**
  - make Coqui STT the default STT solution [70399187](https://github.com/leon-ai/leon/commit/7039918760c0ef7ba93bf45820e3cae774c42d8c)
    - add HTTP API key middleware [cdf41499](https://github.com/leon-ai/leon/commit/cdf4149939cbe3f3ae81039957dba3377a78f5a6)
    - expose queries over HTTP [b6428d03](https://github.com/leon-ai/leon/commit/b6428d038452619f1682c863892cd8f376efca84)
    - add timeout action over HTTP [115f9c16](https://github.com/leon-ai/leon/commit/115f9c164559d761625cc6f362749f7d2417d300)
    - handle built-in and trim entities over HTTP + add "disabled" HTTP API action option [82fb967a](https://github.com/leon-ai/leon/commit/82fb967af8f49421e3b2474184da3d34fb17294f)
    - execute modules over HTTP [2e5b2c59](https://github.com/leon-ai/leon/commit/2e5b2c59da0bafe3acd966773c6fac3611b3bd0c)
    - generate Fastify routes on the file to expose packages over HTTP [5b41713a](https://github.com/leon-ai/leon/commit/5b41713a68ee628e695212dbebc88f6b9a94b461)

### Bug Fixes

- do not ask to regenerate the HTTP API key if this one isn't available yet [d265377a](https://github.com/leon-ai/leon/commit/d265377a43fd4506cf12db46f261b891f2054ed2)
- Python deps tree check [c6c01291](https://github.com/leon-ai/leon/commit/c6c012915824227efdf0c50df6a8f1cd8d70ed42)
- hotword offline (#342) [f563d01d](https://github.com/leon-ai/leon/commit/f563d01d077499c836e94c86f85cedc2ad4d56e6)
- addressed comments by @JRMeyer [b1c6f5c8](https://github.com/leon-ai/leon/commit/b1c6f5c883103d57d4fe566af640fc3ac5ce713d)
- allow to detect STT offline capabilities [04d62288](https://github.com/leon-ai/leon/commit/04d622884165e0bde65785569a659f59cf9e8582)
- Amazon Polly is always configured on check script due to new structure [e6246d1f](https://github.com/leon-ai/leon/commit/e6246d1f8f9ec15a4ebe9600764afffbaa7e62d9)

### Performance Improvements

- check if Python deps tree has been updated before going through deps install [2d0b0f13](https://github.com/leon-ai/leon/commit/2d0b0f1365d8e4d6eadf9f7cc0a16b7b4b4306f4)

# [1.0.0-beta.5](https://github.com/leon-ai/leon/compare/v1.0.0-beta.4...v1.0.0-beta.5) (2021-12-28) / Refocus

_This release marks a major turn in the future versions of the Leon core. Please [read this blog post](https://blog.getleon.ai/i-ran-away-from-open-source/) to know more._

### BREAKING CHANGES

- Node.js 16+ and npm 8+ minimum requirements [2f66f1c1](https://github.com/leon-ai/leon/commit/2f66f1c17bb2e4a1c18b4251d49de252b8d87344)

### Features

- **server:** support arrays on NER between conditions [7cf7f979](https://github.com/leon-ai/leon/commit/7cf7f9791254e1950fe9128ce1b3a58079cc2ada)

### Bug Fixes

- jest-extended new setup due to latest update [02f766d6](https://github.com/leon-ai/leon/commit/02f766d6a8453609ebaec78356aa6e6d4df0967b)

### Performance Improvements

- Windows setup on DeepSpeech dep removal [13f5a49f](https://github.com/leon-ai/leon/commit/13f5a49f678f8f67a93b67d4f558cddcf237e204)

### Documentation Changes

- URL redirect managed by registrar [c16d5b28](https://github.com/leon-ai/leon/commit/c16d5b280b758f7e18305e30678adec79f0a0716)

# [1.0.0-beta.4](https://github.com/leon-ai/leon/compare/1.0.0-beta.2...v1.0.0-beta.4) (2021-05-01) / Getting Rid of Dust

_This release includes a lot of changes that are made under the hood and are not displayed here, please **[read the blog post](https://blog.getleon.ai/getting-rid-of-dust-1-0-0-beta-4/)** to know more._

### BREAKING CHANGES

- **package/checker:** introduce Have I Been Pwned v3 API with API key ([0ca89fe3](https://github.com/leon-ai/leon/commit/0ca89fe32d51c80cec5f9446acf14990390a5917))
- **server:**
  - AWS SDK new structure due to v3 and adapt Amazon Polly changes ([f15f2db7](https://github.com/leon-ai/leon/commit/f15f2db78e5781d05e5e2bcb186645966d17debf))
  - IBM Watson TTS and STT new structure ([f41ea0e9](https://github.com/leon-ai/leon/commit/f41ea0e9a1479bfd6a1cb2e8d1f70aec744c685b) | [2668c295](https://github.com/leon-ai/leon/commit/2668c295880ee753ef7ca26a91dbc7e0901febff))

### Features

- **package/calendar:** introduce To-Do list module ([0cdd73d6](https://github.com/leon-ai/leon/commit/0cdd73d6c24a287915f691e3b12edacd75fd383a) | [857be947](https://github.com/leon-ai/leon/commit/857be947792c650ac35847e14fc41064008cef24) | [2041be14](https://github.com/leon-ai/leon/commit/2041be14dbc01640a61de96d1982cc20cd05a8b3) | [12e8f5c3](https://github.com/leon-ai/leon/commit/12e8f5c3bfb436aa212557cd99d9926aa431ab4f) | [8575e9e3](https://github.com/leon-ai/leon/commit/8575e9e3ef01499d9f7be6d313a85d48549e9107) | [5e128df0](https://github.com/leon-ai/leon/commit/5e128df023977525de3e66ce2826aace87569308) | [602aa694](https://github.com/leon-ai/leon/commit/602aa694ac49333f48c119cf2ca2aa7f54b8ae44) | [b9693df9](https://github.com/leon-ai/leon/commit/b9693df90cbc01067e18e64db4d377e41b3fd1d4) | [581da8cd](https://github.com/leon-ai/leon/commit/581da8cd9806323aabb0e85778d645df3c0948b9) | [53f7db55](https://github.com/leon-ai/leon/commit/53f7db55c6e916751f1d59c239628d5ea8914009) | [ae073971](https://github.com/leon-ai/leon/commit/ae0739717b6a17373d8f9bc69571c67c1c571b4a))
- **package/checker:** introduce Have I Been Pwned module ([61c1b55a](https://github.com/leon-ai/leon/commit/61c1b55af5691c03f6a6dae0cf3f236a374f1fe7) | [5a999bc6](https://github.com/leon-ai/leon/commit/5a999bc63aa0c667c4e3092daac6a05a6c4b4499) | [36368664](https://github.com/leon-ai/leon/commit/36368664fce8bcf0c17c4c83818aeb418f1e2f23) | [a7a6d885](https://github.com/leon-ai/leon/commit/a7a6d885a83455163eeca74a355177d65db156b8) | [c73ba52b](https://github.com/leon-ai/leon/commit/c73ba52ba8575a64b3329e59a50050d15281d0ec) | [8374e548](https://github.com/leon-ai/leon/commit/8374e5481022de9b134f49180a8dfe28db136261) | [a476fd0f](https://github.com/leon-ai/leon/commit/a476fd0f38f18bf8035db213be2c55f83871038d))
- **package/network:** add speedtest module ([09ad4340](https://github.com/leon-ai/leon/commit/09ad43406d3df8ca65f385a91c159def51f91811))
- **server:**
  - add regex entity type [3fda3526](https://github.com/leon-ai/leon/commit/3fda3526c7425bdea4b669474fa77efd61c06a8e)
  - catch unsupported action entity type [5bc6c3f1](https://github.com/leon-ai/leon/commit/5bc6c3f116d6b9ece2cc3bebdbdb08f019ee90b9)
  - NER backbone [24cf3c9a](https://github.com/leon-ai/leon/commit/24cf3c9a4facd05a4c626ff9d2e7c83a5ae15298)
  - introduce actions module [b449376f](https://github.com/leon-ai/leon/commit/b449376f61dc995e2e264c6a14ba123926f5cc58)

### Bug Fixes

- set correct status code for GET /downloads [690f1841](https://github.com/leon-ai/leon/commit/690f1841d681a1e48e1837e3e166228d6c2ddaf6)
- take `.env` in consideration when using Docker [d38e6095](https://github.com/leon-ai/leon/commit/d38e6095f9b71467b8486430fba4bb7007ec4c5a)
- spinner test [9071c927](https://github.com/leon-ai/leon/commit/9071c92790be674687590e4a896bbf44bc26fb43)
- e2e tests by adding modules actions level [5cf77d90](https://github.com/leon-ai/leon/commit/5cf77d9011a80b326f229b2309a6910ac0f1cfa2)

- **package/leon:** fix english translations [90225707](https://github.com/leon-ai/leon/commit/90225707f94154021cadeb9c61bdc48c3de5aa29)
- **package/network:** make use of new compatible speedtest lib [0c925626](https://github.com/leon-ai/leon/commit/0c925626df65858fa039972b3f3d5f38fde93eb6)
- **package/trend:**
  - GitHub module new scraping [68414937](https://github.com/leon-ai/leon/commit/6841493740ca859000c1fd8d692b73fc79fcf500)
  - when there is no star provided on the GitHub module [563fb409](https://github.com/leon-ai/leon/commit/563fb40955e2deb5c6d0bd064fc9cc8766a6fcaf)
- **server:**
  - make use of Basic plugin from the main NLP container [e1d5bed3](https://github.com/leon-ai/leon/commit/e1d5bed3e688db566a0cb803dda5c2d57c599d8c)
  - NER trim entity on after conditions [fa6a5a43](https://github.com/leon-ai/leon/commit/fa6a5a43a60b493aa403a44957082382494c129b)

### Documentation Changes

- add minimum Pipenv version requirement to README [72e46bd6](https://github.com/leon-ai/leon/commit/72e46bd6c175a4a149fb6b14522823b224d7c152)
- hunt broken links [b2a22792](https://github.com/leon-ai/leon/commit/b2a2279243e7566b57fb7f696024bdf08294e853)
- add "ci" commit type in CONTRIBUTING.md [09e2672b](https://github.com/leon-ai/leon/commit/09e2672b0b399f5ce9dd7cd446d04f4d6fd7c13a)
- use emojies in README [0ea7a78b](https://github.com/leon-ai/leon/commit/0ea7a78b7c94dc44c992913ae1c90fb1cf8a7692)
- add social badges to README [c55c7532](https://github.com/leon-ai/leon/commit/c55c7532b25bf420c4819be71b0f9c21ccc58711)
- Node.js 14 requirement [d1034bd1](https://github.com/leon-ai/leon/commit/d1034bd135fd5a6314a1571d4088fd85a8e6a1da)

# [1.0.0-beta.2](https://github.com/leon-ai/leon/compare/1.0.0-beta.1...1.0.0-beta.2) (2019-04-24)

### Features

- can send custom HTTP headers
  ([2685cdab](https://github.com/leon-ai/leon/commit/2685cdab07cc1a9ea418eab812e5163d2dd0da90))
- allow HTML output
  ([ec3f02df](https://github.com/leon-ai/leon/commit/ec3f02dfaf2f4b7623ce350350ebee28cf18740e))
- NLU improvement with node-nlp
  ([6585db71](https://github.com/leon-ai/leon/commit/6585db718ccae1d750a35783075cf61cc8fe84f1))

- **package/trend:**
  - add answer when the Product Hunt developer token is not provided
    ([f40b479b](https://github.com/leon-ai/leon/commit/f40b479b295247c5a8a0e6ed81afe56fadfd2730))
  - Product Hunt module done
    ([37794306](https://github.com/leon-ai/leon/commit/3779430621bef970be0e8d048eb0b4bf160ae8a4))
  - basics done on the Product Hunt module
    ([32cc7dbe](https://github.com/leon-ai/leon/commit/32cc7dbe36592fb9618d9c10da5f05a4be7e41b6))
  - complete dedicated answers according to the technology and given time
    ([8997d691](https://github.com/leon-ai/leon/commit/8997d6917445f837c9647a5a9b4d6998d2df4952))
  - GitHub module done
    ([7c6f3922](https://github.com/leon-ai/leon/commit/7c6f3922f299193ee0fb54d0fc97f8b436fc706b))
  - be able to choose a limit and a date range for the GitHub module
    ([3c088371](https://github.com/leon-ai/leon/commit/3c0883716e1c10371c399843a578095a1e16781d))
  - format GitHub results in one message
    ([9d026b94](https://github.com/leon-ai/leon/commit/9d026b94efa8871d421ae2b593b96622a98537ac))
  - simple GitHub module results
    ([5baec074](https://github.com/leon-ai/leon/commit/5baec07455f453d4ad003f1da360b2663b7e15e0))
  - list GitHub trends in HTML raw
    ([3441629e](https://github.com/leon-ai/leon/commit/3441629e3cde933b322cb114d9f1bc3ef0eb3944) | [6b932e94](https://github.com/leon-ai/leon/commit/6b932e947fc365ea6435fda798b7cca32708b443))
  - expressions dataset and structure
    ([f406a5a0](https://github.com/leon-ai/leon/commit/f406a5a09894e12c56a1e76dda609adada00b0d7) | [f54c2272](https://github.com/leon-ai/leon/commit/f54c2272b4b4dc5c56b512b0ccc1519d77ef15a3))

### Bug Fixes

- Leon was not fully installed with Docker if a `.env` file was existing
  ([c8a68ab0](https://github.com/leon-ai/leon/commit/c8a68ab02eec9ddaf803b6e36cd7e91a4989cdea))

- **package/trend:**
  when there is no contributor on GitHub module
  ([d845e49b](https://github.com/leon-ai/leon/commit/d845e49b0f18caeb306e2d399c50a03883b2f55d))
- **server:**
  - skip Pipenv locking until they fix it
    ([029381e3](https://github.com/leon-ai/leon/commit/029381e3256933f37f5c2950c4eb1f0192f55ec6) | [ecfdc73f](https://github.com/leon-ai/leon/commit/ecfdc73f8290dd9e1910df9519095516a1227763))

### Documentation Changes

- add `What is Leon able to do?` section in the readme
  ([87f53c91](https://github.com/leon-ai/leon/commit/87f53c91368141966959f3ad7299bb7b643828a5) | [d558fc8b](https://github.com/leon-ai/leon/commit/d558fc8b7c6494babf5dec799802227f77c33d8a))
- open-source != open source
  ([16a9372e](https://github.com/leon-ai/leon/commit/16a9372e05d4d31a7a39a65a52d4708b72499d4c) | [2155cd88](https://github.com/leon-ai/leon/commit/2155cd88decbbd671bd58840291d9330ce06ebba))

# [1.0.0-beta.1](https://github.com/leon-ai/leon/compare/1.0.0-beta.0...1.0.0-beta.1) (2019-02-24)

### Features

- add Docker support
  ([209760db](https://github.com/leon-ai/leon/commit/209760dba747001300692fb6a6af97543de584d6))

### Bug Fixes

- **package/checker:**
  isitdown module fails with capital letters in URL
  ([ada6aaef](https://github.com/leon-ai/leon/commit/ada6aaef4bada47e87d28f9f6eaa05b9e23f58d2))
- **web app:**
  enable environment variables
  ([a438d6f9](https://github.com/leon-ai/leon/commit/a438d6f942812f74e3dda75a9875609f8bea21cd))

### Performance Improvements

- **web app:**
  favicon compression
  ([33dbcb42](https://github.com/leon-ai/leon/commit/33dbcb425eaafba90176ff64e5f689eb36bc6ce1))

### Documentation Changes

- update README to make the reader genderless
  ([58662658](https://github.com/leon-ai/leon/commit/586626586b7a2f84cb2cd84028111976bc5172f0))
- use "to rule them all" in README
  ([c74dda4c](https://github.com/leon-ai/leon/commit/c74dda4cb9acc78de143ae01fdc6b4ef0a5ec3ef))

- **readme:**
  add story write-up
  ([08a68e37](https://github.com/leon-ai/leon/commit/08a68e376b6a9367425947380564120943376500))

# [1.0.0-beta.0](https://github.com/leon-ai/leon/compare/https://github.com/leon-ai/leon.git...1.0.0-beta.0) (2019-02-10)

Initial release.


================================================
FILE: LICENSE.md
================================================
MIT License

Copyright (c) 2019-present, Louis Grenard <louis@getleon.ai>

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.


================================================
FILE: README.md
================================================
<p align="center">
  <a href="https://getleon.ai"><img width="800" src="https://getleon.ai/img/hero-animation.gif" /></a>
</p>

<h1 align="center">
  <a href="https://getleon.ai"><img width="96" src="https://getleon.ai/img/logo.svg" alt="Leon"></a><br>
  Leon
</h1>

_<p align="center">Your open-source personal assistant.</p>_

<p align="center">
  <a href="https://github.com/leon-ai/leon/blob/develop/LICENSE.md"><img src="https://img.shields.io/badge/license-MIT-blue.svg?label=License&style=flat" /></a>
  <a href="https://github.com/leon-ai/leon/blob/develop/.github/CONTRIBUTING.md"><img src="https://img.shields.io/badge/PRs-welcome-brightgreen.svg?style=flat" /></a>
  <br>
  <a href="https://github.com/leon-ai/leon/actions/workflows/build.yml"><img src="https://github.com/leon-ai/leon/actions/workflows/build.yml/badge.svg?branch=develop" /></a>
  <a href="https://github.com/leon-ai/leon/actions/workflows/tests.yml"><img src="https://github.com/leon-ai/leon/actions/workflows/tests.yml/badge.svg?branch=develop" /></a>
  <a href="https://github.com/leon-ai/leon/actions/workflows/lint.yml"><img src="https://github.com/leon-ai/leon/actions/workflows/lint.yml/badge.svg?branch=develop" /></a>
  <br>
  <a href="https://discord.gg/MNQqqKg"><img src="https://img.shields.io/badge/Discord-%235865F2.svg?style=for-the-badge&logo=discord&logoColor=white" /></a>
</p>

<p align="center">
  <a href="https://getleon.ai">Website</a> ::
  <a href="https://docs.getleon.ai">Documentation</a> ::
  <a href="http://roadmap.getleon.ai">Roadmap</a> ::
  <a href="https://github.com/leon-ai/leon/blob/develop/.github/CONTRIBUTING.md">Contributing</a> ::
  <a href="https://blog.getleon.ai/the-story-behind-leon/">Story</a>
</p>

---

## Important Notice (as of 2026-01-11)

> [!IMPORTANT]
> **Leon is currently undergoing a massive architectural rewrite.**
>
> The `develop` branch is highly experimental and may be unstable as I implement the new agentic core.
> 
> - If you are looking for the legacy, stable version (pre-LLM), please use the `master` branch.
> - If you want to contribute to the future of Leon (LLMs, Agents, Automation), you are in the right place.

### Outdated Documentation

Please note that the current documentation and this README are outdated regarding the technical architecture. We are moving away from simple classification toward a hybrid approach involving Local LLMs, Transformers, and Atomic Tools. Updated documentation will be released alongside the new core stability.

### Project Evolution and Future Plans

**I have been working on Leon since 2017**. While development has been inconsistent in the past, the current era of AI unlocks capabilities that were previously impossible. I'm now transitioning Leon from a standard assistant to a fully **autonomous personal AI assistant** designed to be used by technical hobbyists to non-tech users.

I'm currently building the foundation for the next generation of Leon, focusing on 3 key milestones:

**1. Workflow Architecture and Atomic Tools**

We are restructuring Leon around a robust flow: `Skills > Actions > Tools > Functions (> Binaries)`.
Instead of monolithic scripts, Leon will use atomic components (e.g. compiled binaries using ONNX runtime) to execute complex workflows.

- Example: a "Video Translator" skill won't just be a script; it will be a workflow where Leon orchestrates tools like vocal isolation, zero-shot voice cloning, ASR, audio gender recognition, etc. to achieve the result.

**2. Autonomous Skill Generation (self-coding)**

We are developing a meta-skill capable of writing code for new skills automatically.

- Leon will analyze a request, check if a skill exists, and if not, write the code itself following our strict architectural standards.
- It will leverage existing tools and inject the new skill directly into its memory for future reuse.

**3. Agentic Behavior (ReAct) and Local LLM Optimization**

The ultimate phase will be to adopt the ReAct (Reason + Act) approach.

- Leon will be provided with low-level **tools** (organized in toolkits, e.g., `music_audio` containing FFmpeg).
- Using Local LLMs, Leon will loop through thoughts and actions to solve problems dynamically.
- Optimization: we are implementing strict context filtering to save tokens, reduce hallucinations, and ensure high performance on local hardware.

**Get Involved**

[Join us on Discord](https://discord.gg/MNQqqKg) to ask questions, or express interest in becoming an active contributor.

- Check out [the roadmap](http://roadmap.getleon.ai/) for more information on our upcoming plans.
- Watch a [preview of our last progress](https://www.youtube.com/watch?v=6CInSt6pTVA) to see what we've been working on.

---

### Why is there a small amount of contributors?

I'm taking a lot of time to work on the new core of Leon due to personal reasons. I can only work on it during my spare time. Hence, I'm blocking any contribution as the whole core of Leon is coming with many breaking changes. Many of you are willing to contribute in Leon (create new skills, help to improve the core, translations and so on...), a big thanks to every one of you!

While I would love to devote more time to Leon, I'm currently unable to do so because I have bills to pay. I have some ideas about how to monetize Leon in the future (Leon's core will always remain open source), but before to get there there is still a long way to go.

Until then, any financial support by [sponsoring Leon](http://sponsor.getleon.ai) is much appreciated 🙂

---

## Latest Release

Check out the [latest release blog post](https://blog.getleon.ai/binaries-and-typescript-rewrite-1-0-0-beta-8/).

<a href="https://blog.getleon.ai/binaries-and-typescript-rewrite-1-0-0-beta-8/"><img width="400" src="https://blog.getleon.ai/static/a0d1cbafd1968e7531dc17e229f8cc61/aa440/beta-8.png" /></a>

---

## 👋 Introduction

**Leon** is an **open-source personal assistant** who can live **on your server**.

He **does stuff** when you **ask him to**.

You can **talk to him** and he can **talk to you**.
You can also **text him** and he can also **text you**.
If you want to, Leon can communicate with you by being **offline to protect your privacy**.

### Why?

> 1. If you are a developer (or not), you may want to build many things that could help in your daily life.
>    Instead of building a dedicated project for each of those ideas, Leon can help you with his
>    Skills structure.
> 2. With this generic structure, everyone can create their own skills and share them with others.
>    Therefore there is only one core (to rule them all).
> 3. Leon uses AI concepts, which is cool.
> 4. Privacy matters, you can configure Leon to talk with him offline. You can already text with him without any third party services.
> 5. Open source is great.

### What is this repository for?

> This repository contains the following nodes of Leon:
>
> - The server
> - Skills
> - The web app
> - The hotword node
> - The TCP server (for inter-process communication between Leon and third-party nodes such as spaCy)
> - The Python bridge (the connector between the core and skills made with Python)

### What is Leon able to do?

> Today, the most interesting part is about his core and the way he can scale up. He is pretty young but can easily scale to have new features (skills).
> You can find what he is able to do by browsing the [skills list](https://github.com/leon-ai/leon/tree/develop/skills).<br>
> Please do know that after the official release, we will build many skills along with the community. Feel free to [join us on Discord](https://discord.gg/MNQqqKg) to be part of the journey.

Sounds good to you? Then let's get started!

## ☁️ Try with a Single-Click

Gitpod will automatically set up an environment and run an instance for you.

[![Open in Gitpod](https://gitpod.io/button/open-in-gitpod.svg)](https://gitpod.io/#https://github.com/leon-ai/leon)

## 🚀 Getting Started

### Prerequisites

- [Node.js](https://nodejs.org/) >= 24.0.0
- [npm](https://npmjs.com/) >= 11.3.0
- Supported OSes: Linux, macOS and Windows

To install these prerequisites, you can follow the [How To section](https://docs.getleon.ai/how-to/) of the documentation.

### Installation

```sh
# Install the Leon CLI
npm install --global @leon-ai/cli

# Install Leon (stable branch)
leon create birth
# OR install from the develop branch: leon create birth --develop
```

### Usage

```sh
# Check the setup went well
leon check

# Run
leon start

# Go to http://localhost:1337
# Hooray! Leon is running
```

## 📚 Documentation

For full documentation, visit [docs.getleon.ai](https://docs.getleon.ai).

## 🇫🇷 Documenting the Journey on YouTube

[I'm documenting the journey on YouTube](https://www.youtube.com/@louisgyt) in developing our dear Leon. I also take you along in my daily life here in China.

For non-French speakers, translated English subtitles are available.

## 📺 Video

[Watch a demo](https://www.youtube.com/watch?v=p7GRGiicO1c).

## 🧭 Roadmap

To know what is going on, follow [roadmap.getleon.ai](http://roadmap.getleon.ai).

## ❤️ Contributing

If you have an idea for improving Leon, do not hesitate.

**Leon needs open source to live**, the more skills he has, the more skillful he becomes.

## 📖 The Story Behind Leon

You'll find a write-up on this [blog post](https://blog.getleon.ai/the-story-behind-leon/).

## 🔔 Stay Tuned

- [Twitter](https://twitter.com/grenlouis)
- [Newsletter](https://newsletter.getleon.ai/subscription/form)
- [Blog](https://blog.getleon.ai)
- [GitHub issues](https://github.com/leon-ai/leon/issues)
- [YouTube](https://www.youtube.com/channel/UCW6mk6j6nQUzFYY97r47emQ)
- [#LeonAI](<https://twitter.com/search?f=live&q=%23LeonAI%20(from%3Agrenlouis%20OR%20from%3Alouistiti_fr)&src=typed_query>)

## 👨 Author

**Louis Grenard** ([@grenlouis](https://twitter.com/grenlouis))

## 👍 Sponsors

<table>
  <tbody>
    <tr>
      <td align="center" valign="middle" width="128">
        <a href="https://github.com/Appwrite">
          <img src="https://github.com/Appwrite.png?size=128" />
          Appwrite
        </a><br>
        <sub><sup>250 USD / month</sup></sub>
      </td>
      <td align="center" valign="middle" width="128">
        <img src="https://getleon.ai/img/anonymous.svg" width="128" />
        Anonymous
        <br>
        <sub><sup>100 USD / month</sup></sub>
      </td>
      <td align="center" valign="middle" width="128">
        <a href="https://github.com/herbundkraut">
          <img src="https://github.com/herbundkraut.png?size=128" />
          herbundkraut
        </a><br>
        <sub><sup>10 USD / month</sup></sub>
      </td>
      <td align="center" valign="middle" width="128">
        <a href="http://sponsor.getleon.ai/">
          You?
        </a>
      </td>
    </tr>
  </tbody>
</table>

You can also contribute by [sponsoring Leon](http://sponsor.getleon.ai).

Please note that I dedicate most of my free time to Leon.

By sponsoring the project you make the project sustainable and faster to develop features.

The focus is not only limited to the activity you see on GitHub but also a lot of thinking about the direction of the project. Which is naturally related to the overall design, architecture, vision, learning process and so on...

### Special Thanks

<a href="https://vercel.com/?utm_source=leon-ai&utm_campaign=oss">
  <img src="https://i.imgur.com/S5olXWh.png" alt="Vercel" width="128" />
</a>
&nbsp; &nbsp; &nbsp;
<a href="https://www.macstadium.com/">
  <img src="https://getleon.ai/img/thanks/mac-stadium.svg" alt="MacStadium" width="128" />
</a>
&nbsp; &nbsp; &nbsp;
<a href="https://www.aoz.studio">
  <img src="https://getleon.ai/_next/image?url=%2Fimg%2Fthanks%2Faoz-studio.png&w=384&q=75" alt="AOZ Studio" width="128" />
</a>

## 📝 License

[MIT License](https://github.com/leon-ai/leon/blob/develop/LICENSE.md)

Copyright (c) 2019-present, Louis Grenard <louis@getleon.ai>

## Cheers!

![Cheers!](https://github.githubassets.com/images/icons/emoji/unicode/1f379.png 'Cheers!')


================================================
FILE: app/src/css/style.scss
================================================
@import '@fontsource/source-sans-pro/200.css';
@import '@fontsource/source-sans-pro/300.css';
@import '@fontsource/source-sans-pro/400.css';
@import '@fontsource/source-sans-pro/600.css';
@import '@fontsource/source-sans-pro/700.css';
@import '@fontsource/source-sans-pro/900.css';
@import 'remixicon/fonts/remixicon.css';
@import 'voice-energy/main.scss';

html,
body,
div,
span,
applet,
object,
iframes,
h1,
h2,
h3,
h4,
h5,
h6,
p,
blockquote,
pre,
a,
abbr,
acronym,
address,
big,
cite,
code,
del,
dfn,
em,
img,
ins,
kbd,
q,
s,
samp,
small,
strike,
sub,
sup,
tt,
var,
u,
i,
center,
dl,
dt,
dd,
ol,
ul,
li,
fieldset,
form,
label,
legend,
table,
caption,
tbody,
tfoot,
thead,
tr,
th,
td,
article,
aside,
canvas,
details,
embed,
figure,
figcaption,
footer,
header,
hgroup,
menu,
nav,
output,
ruby,
section,
summary,
time,
mark,
audio,
video {
  margin: 0;
  padding: 0;
  border: 0;
  font-size: 100%;
  vertical-align: baseline;
}

article,
aside,
details,
figcaption,
figure,
footer,
header,
hgroup,
menu,
nav,
section {
  display: block;
}

blockquote,
q {
  quotes: none;
}

blockquote:before,
blockquote:after,
q:before,
q:after {
  content: '';
  content: none;
}

table {
  border-collapse: collapse;
  border-spacing: 0;
}

* {
  box-sizing: border-box;
  outline: none;
}

:root {
  --black-color: #000;
  --light-black-color: #222426;
  --white-color: #fff;
  --grey-color: #323739;
  --blue-color: #1c75db;
  --pink-color: #ed297a;

  --a-loader-size-md: 20px !important;
}

a {
  color: inherit;
}

#feed ul li:not(.aurora-list-item) {
  margin-left: 20px;
}

body {
  color: var(--white-color);
  background-color: var(--black-color);
  font-family:
    'Source Sans Pro',
    system-ui,
    -apple-system,
    BlinkMacSystemFont,
    'Segoe UI',
    Roboto,
    'Helvetica Neue',
    Arial,
    'Noto Sans',
    sans-serif,
    'Apple Color Emoji',
    'Segoe UI Emoji',
    'Segoe UI Symbol',
    'Noto Color Emoji';
  font-weight: 400;
}

@keyframes plan-tool-status-cozy-shine {
  0% {
    opacity: 0.4;
    filter: drop-shadow(0 0 0 rgba(255, 255, 255, 0));
  }

  50% {
    opacity: 1;
    filter: drop-shadow(0 0 5px rgba(255, 255, 255, 0.22));
  }

  100% {
    opacity: 0.4;
    filter: drop-shadow(0 0 0 rgba(255, 255, 255, 0));
  }
}

#feed
  .bubble-container[data-message-id^='plan-']
  .aurora-list
  .aurora-list-item--center:last-child
  .aurora-status
  .aurora-icon {
  animation: plan-tool-status-cozy-shine 2.6s ease-in-out infinite;
}

body > * {
  transition: opacity 0.5s;
}
body.settingup > *:not(#init) {
  opacity: 0;
}
#init .not-initialized {
  visibility: hidden;
}
#init .initialized {
  opacity: 0;
  visibility: hidden;
}

kbd {
  font-family: 'Source Sans Pro', monospace;
  display: inline-block;
  background-color: var(--light-black-color);
  color: rgba(255, 255, 255, 0.4);
  border-radius: 4px;
  text-align: center;
  min-width: 16px;
  min-height: 16px;
  line-height: 16px !important;
  padding: 2px 6px !important;
  margin: 0 !important;
}

main {
  position: absolute;
  width: 63%;
  top: 0;
  left: 50%;
  height: 100%;
  transform: translate(-50%, 0);
}

footer {
  position: absolute;
  text-align: center;
  left: 50%;
  bottom: 0;
  line-height: 18px;
  transform: translate(-50%, -50%);
}

textarea {
  font-family: inherit;
  text-align: center;
  color: var(--white-color);
  width: 100%;
  border: none;
  border-bottom: 2px solid var(--grey-color);
  background: none;
  font-weight: 600;
  font-size: 4em;
  padding-right: 39px;
  height: 140px;
  resize: none;
  overflow-y: auto;
}
textarea::-webkit-scrollbar {
  width: 6px;
}
textarea::-webkit-scrollbar-thumb {
  background-color: rgba(255, 255, 255, 0.2);
  border-radius: 12px;
}

#tip {
  display: inline-flex;
  margin-top: 2px;
  color: var(--white-color);
  line-height: 22px;
  font-size: 0.9em;
  gap: 20px;
  li {
    margin-left: 0;
  }
}

.hide {
  display: none;
}

#logo {
  background: no-repeat url(../img/logo.svg);
  margin: 0 auto;
  width: 40px;
  height: 40px;
}

#top-container {
  position: absolute;
  top: 4%;
  color: var(--grey-color);
  display: flex;
  width: 100%;
  justify-content: space-between;
}
#mood {
  position: relative;
  font-size: 16px;
}
#info {
  position: relative;
  text-decoration: underline;
  background: none;
  border: none;
  color: var(--grey-color);
  cursor: pointer;
  font-size: inherit;
}

#feed {
  position: absolute;
  width: 100%;
  top: 8%;
  height: 50%;
  overflow-y: auto;
  border: 2px solid var(--grey-color);
  border-radius: 12px;
}
#feed::-webkit-scrollbar {
  width: 6px;
}
#feed::-webkit-scrollbar-thumb {
  background-color: rgba(255, 255, 255, 0.2);
  border-radius: 12px;
}

#no-bubble {
  margin-top: 64px;
  text-align: center;
}

#is-typing {
  position: absolute;
  top: 59%;
  padding: 0 8px;
  opacity: 0;
  margin-top: 20px;
  transition: opacity 0.3s;
}
#is-typing.on {
  opacity: 1;
}

#is-typing .circle {
  display: inline-block;
  border-radius: 50%;
  width: 10px;
  height: 10px;
  background-color: var(--white-color);
  transform: scale(1);
}
#is-typing .circle:nth-child(1) {
  animation: typing 0.2s linear infinite alternate;
  background-color: #0071f0;
}
#is-typing .circle:nth-child(2) {
  animation: typing 0.2s 0.2s linear infinite alternate;
  background-color: var(--white-color);
}
#is-typing .circle:nth-child(3) {
  animation: typing 0.2s linear infinite alternate;
  background-color: #ec297a;
}
@keyframes typing {
  100% {
    transform: scale(1.5);
  }
}

.llm-token {
  opacity: 0;
  transition: opacity 2.5s;
}

.llm-token.fade-in {
  animation: fadeIn 2.5s forwards;
}

.reasoning-block-container {
  padding: 6px;
  text-align: left;
}

.reasoning-block {
  max-width: 72%;
  border: 1px solid rgba(255, 255, 255, 0.16);
  border-radius: 12px;
  background-color: #111315;
  overflow: hidden;
  animation: fadeIn 0.2s ease-in forwards;
}

.reasoning-header {
  display: flex;
  align-items: center;
  gap: 6px;
  padding: 8px 12px;
  border-bottom: 1px solid rgba(255, 255, 255, 0.1);
  background-color: rgba(255, 255, 255, 0.03);
}

.reasoning-icon {
  color: var(--blue-color);
  font-size: 15px;
}

.reasoning-title {
  font-size: 0.85rem;
  letter-spacing: 0.04em;
  text-transform: uppercase;
  color: rgba(255, 255, 255, 0.8);
}

.reasoning-content {
  padding: 10px 12px;
  font-family: 'Courier New', Consolas, monospace;
  font-size: 0.95rem;
  line-height: 1.45;
  color: rgba(255, 255, 255, 0.82);
  white-space: pre-wrap;
  word-break: break-word;
  max-height: 296px;
  overflow-y: auto;
}

.reasoning-content::-webkit-scrollbar {
  width: 6px;
}

.reasoning-content::-webkit-scrollbar-thumb {
  background-color: rgba(255, 255, 255, 0.2);
  border-radius: 12px;
}

.reasoning-token {
  opacity: 0;
}

.reasoning-token.fade-in {
  animation: fadeIn 0.35s forwards;
}

.bubble-container {
  padding: 6px;
  display: flex;
  flex-direction: column;
  width: fit-content;
  max-width: 60%;
}
.bubble-container.me {
  margin-left: auto;
  align-items: flex-end;
  text-align: right;
}
.bubble-container.leon {
  margin-right: auto;
  align-items: flex-start;
  text-align: left;
}
.show-more {
  margin: 3px;
  text-decoration: underline;
}
.show-more:hover {
  cursor: pointer;
  text-decoration: none;
}
.show-all {
  max-height: 100% !important;
}

.bubble {
  padding: 10px 16px;
  border-radius: 16px;
  display: inline-block;
  max-width: 100%;
  word-break: break-word;
  text-align: left;
  opacity: 0;
  animation: fadeIn 0.2s ease-in forwards;
  overflow: hidden;
  font-size: 1.8rem;
  line-height: 2.4rem;
}
.bubble-metrics {
  cursor: default;
  margin-top: 2px;
  padding: 0 4px;
  font-size: 0.95rem;
  line-height: 1.2rem;
  color: var(--grey-color);
  align-self: flex-end;
  text-align: right;
}
.bubble-metric-item {
  display: inline-flex;
  align-items: center;
  gap: 4px;
}
.bubble-metric-item i {
  font-size: 1rem;
}
.bubble-metric-separator {
  margin: 0 6px;
}
#feed .me .bubble-metrics {
  text-align: right;
}
#feed .me .bubble {
  background-color: #1c75db;
  color: var(--white-color);
  right: 0;
}
#feed .leon .bubble {
  background-color: var(--light-black-color);
  color: var(--white-color);
}
@keyframes fadeIn {
  100% {
    opacity: 1;
  }
}

#suggestions-container {
  position: absolute;
  z-index: 10;
  width: 100%;
  bottom: 36%;
  display: flex;
  justify-content: flex-end;
  column-gap: 8px;
  overflow-x: auto;
}
.suggestion {
  border: 1px solid var(--white-color);
  background-color: transparent;
  color: var(--white-color);
  border-radius: 8px;
  padding: 2px 8px;
  font-size: inherit;
  cursor: pointer;
  transition:
    background-color 0.2s,
    color 0.2s;
}
.suggestion:hover {
  color: var(--black-color);
  background-color: var(--white-color);
}

#input-container {
  position: absolute;
  width: 100%;
  bottom: 18%;
}

#mic-container {
  position: absolute;
  right: 0;
  margin-top: 38px;
}

.italic {
  font-style: italic;
}

#mic-button {
  position: absolute;
  border: none;
  cursor: pointer;
  height: 26px;
  width: 26px;
  border-radius: 50%;
  background-color: #888;
  -webkit-mask-image: url(../img/mic.svg);
  mask-image: url(../img/mic.svg);
  transition: background-color 0.2s;
}
#mic-button:not(.enabled) {
  margin-left: -26px;
}
#mic-button:hover {
  background-color: var(--white-color);
}
#mic-button.enabled {
  background-color: #00e676;
}
#mic-button.enabled + #sonar {
  width: 26px;
  height: 26px;
  border-radius: 50%;
  opacity: 0.3;
  background-color: #575757;
  pointer-events: none;
  animation: sonar 1.3s linear infinite;
}
@keyframes sonar {
  25% {
    transform: scale(1.5);
  }
  50% {
    transform: scale(1.2);
  }
  60% {
    transform: scale(1.5);
  }
  75% {
    transform: scale(2);
  }
  100% {
    transform: scale(1);
  }
}

/* Clickable URL styles */
.clickable-url {
  text-decoration: underline;
}

/* Clickable file path styles */
.clickable-path {
  cursor: pointer;
  text-decoration: underline;
}

/* Tool Output Container Styles */
.tool-group-container {
  margin: 8px 6px;
  border: 1px solid var(--grey-color);
  border-radius: 8px;
  background-color: #1a1a1a;
  font-family: 'Courier New', Consolas, monospace;
  font-size: 0.9em;
  opacity: 0;
  animation: fadeIn 0.3s ease-in forwards;
}

.tool-header {
  display: flex;
  align-items: center;
  padding: 8px 12px;
  background-color: var(--light-black-color);
  border-radius: 8px 8px 0 0;
  cursor: pointer;
  border-bottom: 1px solid var(--grey-color);
  transition: background-color 0.2s;
}

.tool-header:hover {
  background-color: #2a2c2e;
}

.tool-icon {
  color: var(--blue-color);
  margin-right: 8px;
  font-size: 16px;
}

.tool-name {
  flex: 1;
  font-weight: 600;
  color: var(--white-color);
  font-size: 0.95em;
}

.expand-icon {
  color: var(--grey-color);
  font-size: 18px;
  transition: transform 0.2s ease;
}

.expand-icon.rotated {
  transform: rotate(180deg);
}

.tool-content {
  max-height: 0;
  overflow: hidden;
  transition: max-height 0.3s ease;
}

.tool-content.expanded {
  max-height: 500px;
  overflow-y: auto;
}

.tool-content::-webkit-scrollbar {
  width: 4px;
}

.tool-content::-webkit-scrollbar-thumb {
  background-color: rgba(255, 255, 255, 0.1);
  border-radius: 2px;
}

.shell-output {
  padding: 12px;
  background-color: #0d1117;
  border-radius: 0 0 8px 8px;
  min-height: 40px;
}

.shell-message {
  margin: 2px 0;
  line-height: 1.4;
  color: #e6edf3;
  word-break: break-word;
}

.shell-prompt {
  color: var(--pink-color);
  font-weight: bold;
  margin-right: 8px;
}

.shell-message .clickable-path {
  color: var(--blue-color);
  background-color: rgba(28, 117, 219, 0.1);
  padding: 1px 4px;
  border-radius: 3px;
  border: 1px solid rgba(28, 117, 219, 0.3);
}

.shell-message .clickable-url {
  color: var(--blue-color);
}


================================================
FILE: app/src/css/voice-energy/base.scss
================================================
/**
 * Overlay and containers
 */

body.voice-mode-enabled {
  #voice-overlay-transitor,
  #voice-overlay-bg {
    visibility: visible;
  }
  #voice-overlay-bg {
    opacity: 1;
  }
}
#voice-overlay-transitor {
  position: fixed;
  background-color: var(--black-color);
  z-index: 10;
  width: 12px;
  height: 12px;
  border-radius: 50%;
  top: 50%;
  left: 50%;
  transform: translate(-50%, -50%);
  will-change: transform;
  animation: scaleIn 1s;
}
@keyframes scaleIn {
  0% {
    transform: scale3d(0, 0, 1);
  }
  100% {
    transform: scale3d(172, 172, 1);
  }
}

#voice-status,
#voice-tips {
  color: var(--grey-color);
  text-align: center;
}
#voice-status {
  font-size: 17px;
  font-style: italic;
}
#voice-tips {
  margin-top: 32px;
  line-height: 18px;
  font-size: 15px;
}

#voice-overlay-bg {
  visibility: hidden;
  cursor: pointer;
  opacity: 0;
  position: fixed;
  width: 100vw;
  height: 100vh;
  z-index: 100;
  will-change: opacity;
  display: flex;
  justify-content: center;
  // backdrop-filter: saturate(140%) blur(5px);
  /*background-color: rgba(0, 0, 0, .9);*/
  background-color: var(--black-color);
}
@keyframes skipFadeIn {
  0% {
    opacity: 1;
  }
  100% {
    opacity: 1;
  }
}

#voice-container {
  opacity: 0;
  position: relative;
  top: 64px;
  display: flex;
  flex-direction: column;
  width: 1024px;
  height: 756px;
  align-items: center;
  gap: 64px;
  animation: fadeIn 1s 3s both;
}

#voice-energy-container {
  --neon-size: 228px;

  // animation: fadeIn 1s 1.5s both;
  //opacity: 0;
  overflow: hidden;
  position: relative;
  height: 400px;
  border-radius: 50%;
  display: flex;
  justify-content: center;
  align-items: center;
}
p#voice-speech {
  width: 100%;
  height: 100%;
  flex: 1;
  text-align: center;
  font-size: 3rem;
  font-weight: 600;
}

/**
 * Neons
 */

.voice-neon {
  position: absolute;
  z-index: 10;
  width: var(--neon-size);
  height: var(--neon-size);
}

#purple-neon-blur {
  --neon-blur: calc(var(--neon-size) + 96px);

  position: absolute;
  z-index: 0;
  opacity: 0.7;
  width: var(--neon-blur);
  height: var(--neon-blur);
}

#blue-neon-1 {
  margin-top: -8px;
  margin-left: 12px;
}

#blue-neon-2 {
  margin-top: 8px;
  margin-right: 12px;
}

/**
 * Particles
 */

.voice-particle {
  position: absolute;
  width: 3px;
  height: 3px;
  border-radius: 50%;
  opacity: 1;
  will-change: transform, opacity;
  animation-duration: 1s;
  animation-iteration-count: infinite;
}
.voice-particle.blue {
  background-color: #c4e0ff;
  box-shadow: 0 0 2px 2px var(--blue-color);
}
.voice-particle.pink {
  background-color: #ffb9d7;
  box-shadow: 0 0 2px 2px var(--pink-color);
}


================================================
FILE: app/src/css/voice-energy/idle.scss
================================================
/**
 * IDLE status
 */

#voice-energy-container.idle {
  .voice-particle {
    visibility: hidden;
    animation-play-state: paused;
    opacity: 0;
  }
  .voice-neon {
    margin: 0;
  }
  #purple-neon-blur {
    transform: scale(1);
  }
  #purple-neon-blur circle {
    filter: drop-shadow(0px 0px 64px mix(#ed297a, #1c75db));
    animation: idleNeonBlurBreath 2.2s infinite alternate;
  }
  #pink-neon-1 {
    transform: scale(1);
    animation: idleBouncePinkNeon1 1.8s 1s infinite alternate;
  }
  #blue-neon-1 {
    transform: scale(0.8);
    animation: idleMoveBlueNeon1 1.8s infinite alternate;
  }
  #blue-neon-2 {
    transform: scale(0.9);
    animation: idleMoveBlueNeon2 1.8s 0.5s infinite alternate;
  }
}

@keyframes idleNeonBlurBreath {
  100% {
    filter: drop-shadow(0px 0px 0px mix(#ed297a, #1c75db));
  }
}
@keyframes idleBouncePurpleNeonBlur {
  100% {
    transform: scale(1);
  }
}
@keyframes idleBouncePinkNeon1 {
  100% {
    transform: scale(1.1);
  }
}
@keyframes idleMoveBlueNeon1 {
  100% {
    transform: scale(0.9);
  }
}
@keyframes idleMoveBlueNeon2 {
  100% {
    transform: scale(1);
  }
}


================================================
FILE: app/src/css/voice-energy/listening.scss
================================================
/**
 * Listening status
 */

#voice-energy-container.listening {
  .voice-particle {
    visibility: hidden;
    animation-play-state: paused;
    opacity: 0;
  }
  .voice-neon {
    margin: 0;
  }
  #purple-neon-blur {
    transform: scale(1);
  }
  #purple-neon-blur circle {
    filter: drop-shadow(0px 0px 64px mix(#ed297a, #1c75db));
    animation: listeningNeonBlurBreath 0.7s infinite alternate;
  }
  #pink-neon-1 {
    transform: scale(1);
    animation: listeningBouncePinkNeon1 0.3s 1s infinite alternate;
  }
  #blue-neon-1 {
    transform: scale(0.8);
    animation: listeningMoveBlueNeon1 0.3s infinite alternate;
  }
  #blue-neon-2 {
    transform: scale(0.9);
    animation: listeningMoveBlueNeon2 0.3s 0.5s infinite alternate;
  }
}

@keyframes listeningNeonBlurBreath {
  100% {
    filter: drop-shadow(0px 0px 0px mix(#ed297a, #1c75db));
  }
}
@keyframes listeningBouncePurpleNeonBlur {
  100% {
    transform: scale(1);
  }
}
@keyframes listeningBouncePinkNeon1 {
  100% {
    transform: scale(1.1);
  }
}
@keyframes listeningMoveBlueNeon1 {
  100% {
    transform: scale(0.9);
  }
}
@keyframes listeningMoveBlueNeon2 {
  100% {
    transform: scale(1);
  }
}


================================================
FILE: app/src/css/voice-energy/main.scss
================================================
@import 'base.scss';
@import 'listening.scss';
@import 'idle.scss';
@import 'processing.scss';
@import 'talking.scss';


================================================
FILE: app/src/css/voice-energy/processing.scss
================================================
@use 'sass:math';

/**
 * Processing status
 */

#voice-energy-container.processing {
  #purple-neon-blur {
    animation: processingBouncePurpleNeonBlur 1s infinite alternate;
  }
  #pink-neon-1 {
    animation: processingBouncePinkNeon1 0.5s infinite alternate;
  }
  #blue-neon-1 {
    animation: processingMoveBlueNeon1 0.5s infinite alternate;
  }
  #blue-neon-2 {
    animation: processingMoveBlueNeon2 0.5s infinite alternate;
  }
}

@keyframes processingBouncePurpleNeonBlur {
  50% {
    transform: scale(1.07);
  }
  100% {
    transform: scale(1);
  }
}
@keyframes processingBouncePinkNeon1 {
  50% {
    transform: scale(1.02);
  }
  100% {
    transform: scale(1);
  }
}
@keyframes processingMoveBlueNeon1 {
  0% {
    transform: translateX(0) translateY(0);
  }
  33% {
    transform: translateY(-3px) translateX(-2px);
  }
  66% {
    transform: translateY(-3px) translateX(3px);
  }
  100% {
    transform: translateY(-3px) translateX(1px);
  }
}
@keyframes processingMoveBlueNeon2 {
  0% {
    transform: translateX(0) translateY(0);
  }
  33% {
    transform: translateY(3px) translateX(2px);
  }
  66% {
    transform: translateY(3px) translateX(3px);
  }
  100% {
    transform: translateY(3px) translateX(-1px);
  }
}

@for $i from 0 through 31 {
  .processing .voice-particle[data-particle='#{$i}'] {
    animation-delay: #{$i * 0.1}s;
  }

  .processing .voice-particle[data-particle='#{$i}'] {
    animation-name: processingMoveParticle#{$i};
  }

  #voice-energy-container.processing {
    @keyframes processingMoveParticle#{$i} {
      75% {
        opacity: 0.1;
      }
      100% {
        opacity: 1;
        transform: translateX(math.cos(11.25deg * $i) * 110px)
          translateY(math.sin(11.25deg * $i) * 110px);
      }
    }
  }
}


================================================
FILE: app/src/css/voice-energy/talking.scss
================================================
@use 'sass:math';

/**
 * Talking status
 */

#voice-energy-container.talking {
  .voice-neon {
    margin: 0;
  }
  #purple-neon-blur {
    animation: talkingBouncePurpleNeonBlur 1s infinite alternate;
  }
  #pink-neon-1 {
    transform: scale(1);
    animation: talkingBouncePinkNeon1 0.5s 1s infinite alternate;
  }
  #blue-neon-1 {
    transform: scale(0.8);
    animation: talkingMoveBlueNeon1 0.5s infinite alternate;
  }
  #blue-neon-2 {
    transform: scale(0.9);
    animation: talkingMoveBlueNeon2 0.5s 0.3s infinite alternate;
  }
}

@keyframes talkingBouncePurpleNeonBlur {
  50% {
    transform: scale(1.07);
  }
  100% {
    transform: scale(1);
  }
}
@keyframes talkingBouncePinkNeon1 {
  100% {
    transform: scale(1.1);
  }
}
@keyframes talkingMoveBlueNeon1 {
  100% {
    transform: scale(0.9);
  }
}
@keyframes talkingMoveBlueNeon2 {
  100% {
    transform: scale(1);
  }
}

.talking .voice-particle {
  opacity: 0;
  animation-duration: 2s;
}
@for $i from 0 through 31 {
  .talking .voice-particle[data-particle='#{$i}'] {
    animation-delay: #{$i * 0.2}s;
    // animation-duration: #{$i * 0.5}s;
  }

  .talking .voice-particle[data-particle='#{$i}'] {
    animation-name: talkingMoveParticle#{$i};
  }

  #voice-energy-container.talking {
    @keyframes talkingMoveParticle#{$i} {
      0% {
        opacity: 1;
        transform: translate(0);
      }
      50% {
        opacity: 0;
      }
      100% {
        opacity: 0;
        transform: translateX(math.cos(math.random() * 360deg))
          translateY(math.sin(math.random() * 360deg));
      }
    }
  }
}


================================================
FILE: app/src/custom-aurora-components/index.ts
================================================
export * from './timer'


================================================
FILE: app/src/custom-aurora-components/timer/index.ts
================================================
export * from './timer'


================================================
FILE: app/src/custom-aurora-components/timer/timer.tsx
================================================
import React, { useState, useEffect } from 'react'
import { CircularProgress, Flexbox, Text } from '@leon-ai/aurora'

interface TimerProps {
  initialTime: number
  interval: number
  totalTimeContent: string
  initialProgress?: number
  onEnd?: () => void
}

function formatTime(seconds: number): string {
  const minutes = seconds >= 60 ? Math.floor(seconds / 60) : 0
  const remainingSeconds = seconds % 60
  const formattedMinutes = minutes < 10 ? `0${minutes}` : minutes
  const formattedSeconds =
    remainingSeconds < 10 ? `0${remainingSeconds}` : remainingSeconds

  return `${formattedMinutes}:${formattedSeconds}`
}

export function Timer({
  initialTime,
  initialProgress,
  interval,
  totalTimeContent,
  onEnd
}: TimerProps) {
  const [progress, setProgress] = useState(initialProgress || 0)
  const [timeLeft, setTimeLeft] = useState(initialTime)

  useEffect(() => {
    setTimeLeft(initialTime)
    setProgress(progress)
  }, [initialTime])

  useEffect(() => {
    if (timeLeft <= 0) {
      return
    }

    const timer = setInterval(() => {
      setTimeLeft((prevTime) => {
        const newTime = prevTime - 1

        if (newTime <= 0 && onEnd) {
          onEnd()
        }

        return newTime
      })
      setProgress((prevProgress) => prevProgress + 100 / initialTime)
    }, interval)

    return () => clearInterval(timer)
  }, [initialTime, interval, timeLeft])

  return (
    <CircularProgress value={progress} size="lg">
      <Flexbox gap="xs" alignItems="center" justifyContent="center">
        <Text fontSize="lg" fontWeight="semi-bold">
          {formatTime(timeLeft)}
        </Text>
        <Text fontSize="xs" secondary>
          {totalTimeContent}
        </Text>
      </Flexbox>
    </CircularProgress>
  )
}


================================================
FILE: app/src/index.html
================================================
<!doctype html>
<html lang="en">
  <head>
    <meta charset="utf-8" />
    <link rel="icon" type="image/png" href="/img/favicon.png" />
    <meta name="viewport" content="width=device-width, initial-scale=1.0" />
    <title>Leon</title>
    <style>
      @import './css/style.scss';
    </style>
  </head>
  <body class="settingup">
    <div id="init"></div>
    <div id="voice-overlay-bg">
      <div id="voice-container">
        <div>
          <div id="voice-energy-container">
            <svg
              class="voice-neon"
              id="pink-neon-1"
              viewBox="0 0 237 237"
              fill="none"
              xmlns="http://www.w3.org/2000/svg"
            >
              <g filter="url(#filter0_i_6_16)">
                <circle
                  cx="118.5"
                  cy="118.5"
                  r="113.5"
                  stroke="#FFF"
                  stroke-width="10"
                />
              </g>
              <defs>
                <filter
                  id="filter0_i_6_16"
                  x="0"
                  y="0"
                  width="237"
                  height="237"
                  filterUnits="userSpaceOnUse"
                  color-interpolation-filters="sRGB"
                >
                  <feFlood flood-opacity="0" result="BackgroundImageFix" />
                  <feBlend
                    mode="normal"
                    in="SourceGraphic"
                    in2="BackgroundImageFix"
                    result="shape"
                  />
                  <feColorMatrix
                    in="SourceAlpha"
                    type="matrix"
                    values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
                    result="hardAlpha"
                  />
                  <feMorphology
                    radius="1"
                    operator="erode"
                    in="SourceAlpha"
                    result="effect1_innerShadow_6_16"
                  />
                  <feOffset />
                  <feGaussianBlur stdDeviation="1" />
                  <feComposite
                    in2="hardAlpha"
                    operator="arithmetic"
                    k2="-1"
                    k3="1"
                  />
                  <feColorMatrix
                    type="matrix"
                    values="0 0 0 0 0.929412 0 0 0 0 0.160784 0 0 0 0 0.478431 0 0 0 1 0"
                  />
                  <feBlend
                    mode="normal"
                    in2="shape"
                    result="effect1_innerShadow_6_16"
                  />
                </filter>
              </defs>
            </svg>

            <svg
              class="voice-neon"
              id="blue-neon-1"
              viewBox="0 0 237 237"
              fill="none"
              xmlns="http://www.w3.org/2000/svg"
            >
              <g filter="url(#filter0_i_6_24)">
                <circle
                  cx="118.5"
                  cy="118.5"
                  r="116.5"
                  stroke="#FFF"
                  stroke-width="4"
                />
              </g>
              <defs>
                <filter
                  id="filter0_i_6_24"
                  x="0"
                  y="0"
                  width="237"
                  height="237"
                  filterUnits="userSpaceOnUse"
                  color-interpolation-filters="sRGB"
                >
                  <feFlood flood-opacity="0" result="BackgroundImageFix" />
                  <feBlend
                    mode="normal"
                    in="SourceGraphic"
                    in2="BackgroundImageFix"
                    result="shape"
                  />
                  <feColorMatrix
                    in="SourceAlpha"
                    type="matrix"
                    values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
                    result="hardAlpha"
                  />
                  <feMorphology
                    radius="1"
                    operator="erode"
                    in="SourceAlpha"
                    result="effect1_innerShadow_6_24"
                  />
                  <feOffset />
                  <feGaussianBlur stdDeviation="1" />
                  <feComposite
                    in2="hardAlpha"
                    operator="arithmetic"
                    k2="-1"
                    k3="1"
                  />
                  <feColorMatrix
                    type="matrix"
                    values="0 0 0 0 0.109804 0 0 0 0 0.458824 0 0 0 0 0.858824 0 0 0 1 0"
                  />
                  <feBlend
                    mode="normal"
                    in2="shape"
                    result="effect1_innerShadow_6_24"
                  />
                </filter>
              </defs>
            </svg>

            <svg
              class="voice-neon"
              id="blue-neon-2"
              viewBox="0 0 237 237"
              fill="none"
              xmlns="http://www.w3.org/2000/svg"
            >
              <g filter="url(#filter0_i_6_24)">
                <circle
                  cx="118.5"
                  cy="118.5"
                  r="116.5"
                  stroke="#FFF"
                  stroke-width="4"
                />
              </g>
              <defs>
                <filter
                  id="filter0_i_6_24"
                  x="0"
                  y="0"
                  width="237"
                  height="237"
                  filterUnits="userSpaceOnUse"
                  color-interpolation-filters="sRGB"
                >
                  <feFlood flood-opacity="0" result="BackgroundImageFix" />
                  <feBlend
                    mode="normal"
                    in="SourceGraphic"
                    in2="BackgroundImageFix"
                    result="shape"
                  />
                  <feColorMatrix
                    in="SourceAlpha"
                    type="matrix"
                    values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"
                    result="hardAlpha"
                  />
                  <feMorphology
                    radius="5"
                    operator="erode"
                    in="SourceAlpha"
                    result="effect1_innerShadow_6_24"
                  />
                  <feOffset />
                  <feGaussianBlur stdDeviation="1" />
                  <feComposite
                    in2="hardAlpha"
                    operator="arithmetic"
                    k2="-1"
                    k3="1"
                  />
                  <feColorMatrix
                    type="matrix"
                    values="0 0 0 0 0.109804 0 0 0 0 0.458824 0 0 0 0 0.858824 0 0 0 1 0"
                  />
                  <feBlend
                    mode="normal"
                    in2="shape"
                    result="effect1_innerShadow_6_24"
                  />
                </filter>
              </defs>
            </svg>

            <svg
              id="purple-neon-blur"
              viewBox="0 0 341 341"
              fill="none"
              xmlns="http://www.w3.org/2000/svg"
            >
              <g opacity="0.72" filter="url(#filter0_f_18_61)">
                <circle
                  cx="170.5"
                  cy="170.5"
                  r="116.5"
                  stroke="#ED297A"
                  stroke-width="24"
                />
              </g>
              <g opacity="0.72" filter="url(#filter1_f_18_61)">
                <circle
                  cx="170.5"
                  cy="170.5"
                  r="116.5"
                  stroke="#1C75DB"
                  stroke-width="24"
                />
              </g>
              <defs>
                <filter
                  id="filter0_f_18_61"
                  x="0"
                  y="0"
                  width="341"
                  height="341"
                  filterUnits="userSpaceOnUse"
                  color-interpolation-filters="sRGB"
                >
                  <feFlood flood-opacity="0" result="BackgroundImageFix" />
                  <feBlend
                    mode="normal"
                    in="SourceGraphic"
                    in2="BackgroundImageFix"
                    result="shape"
                  />
                  <feGaussianBlur
                    stdDeviation="21"
                    result="effect1_foregroundBlur_18_61"
                  />
                </filter>
                <filter
                  id="filter1_f_18_61"
                  x="0"
                  y="0"
                  width="341"
                  height="341"
                  filterUnits="userSpaceOnUse"
                  color-interpolation-filters="sRGB"
                >
                  <feFlood flood-opacity="0" result="BackgroundImageFix" />
                  <feBlend
                    mode="normal"
                    in="SourceGraphic"
                    in2="BackgroundImageFix"
                    result="shape"
                  />
                  <feGaussianBlur
                    stdDeviation="21"
                    result="effect1_foregroundBlur_18_61"
                  />
                </filter>
              </defs>
            </svg>
          </div>
          <div id="voice-status"></div>
          <div id="voice-tips">
            It is recommended to use a headset for a better voice experience.
            <br />
            Otherwise, if your microphone is too sensitive or speakers are too
            loud,
            <br />
            Leon may hear his own voice and get confused.
          </div>
        </div>
        <p id="voice-speech"></p>
      </div>
    </div>
    <main>
      <div id="top-container">
        <div id="mood"></div>
        <button id="info">Info</button>
      </div>
      <div id="feed">
        <p id="no-bubble" class="hide">
          You can start to interact with Leon, don't be shy.
        </p>
      </div>
      <div id="suggestions-container"></div>
      <div id="is-typing">
        <div class="circle"></div>
        <div class="circle"></div>
        <div class="circle"></div>
      </div>
      <div id="input-container">
        <div id="mic-container">
          <button id="mic-button"></button>
          <div id="sonar"></div>
        </div>
        <label for="utterance"></label>
        <textarea id="utterance" autocomplete="off" autofocus></textarea>
        <ul id="tip">
          <li><kbd>enter</kbd> to submit.</li>
          <li><kbd>shift</kbd> + <kbd>enter</kbd> for new line.</li>
          <li>
            <kbd>shift</kbd> + <kbd>↑</kbd> / <kbd>↓</kbd> to browse history.
          </li>
          <li><kbd>alt</kbd> / <kbd>cmd</kbd> + <kbd>c</kbd> to listen.</li>
        </ul>
      </div>
    </main>
    <footer>
      <div id="logo"></div>
      <br />
      <div id="version">
        <small>v</small>
      </div>
      <div id="discord">
        <small class="italic">
          <a href="https://discord.gg/MNQqqKg" target="_blank"
            >Join us on Discord</a
          >
        </small>
      </div>
    </footer>
    <script type="module" src="/js/main.js"></script>
  </body>
</html>


================================================
FILE: app/src/js/chatbot.js
================================================
import { createElement } from 'react'
import { createRoot } from 'react-dom/client'
import axios from 'axios'
// eslint-disable-next-line no-redeclare
import { WidgetWrapper, Flexbox, Loader, Text } from '@leon-ai/aurora'

import renderAuroraComponent from './render-aurora-component'
import ToolUIHandler from './tool-ui-handler'

const WIDGETS_TO_FETCH = []
const WIDGETS_FETCH_CACHE = new Map()
const REPLACED_MESSAGES = new Set()
const AUTO_SCROLL_BOTTOM_THRESHOLD_PX = 24

export default class Chatbot {
  constructor(socket, serverURL) {
    this.socket = socket
    this.serverURL = serverURL
    this.et = new EventTarget()
    this.feed = document.querySelector('#feed')
    this.typing = document.querySelector('#is-typing')
    this.noBubbleMessage = document.querySelector('#no-bubble')
    this.bubbles = localStorage.getItem('bubbles')
    this.parsedBubbles = JSON.parse(this.bubbles)
    this.reasoningBlocks = new Map()
    this.feedAutoScrollEnabled = true
    this.isProgrammaticFeedScroll = false

    // Initialize tool UI handler
    this.toolUIHandler = new ToolUIHandler(
      this.feed,
      this.scrollDown.bind(this),
      this.formatMessage.bind(this)
    )
  }

  async init() {
    await this.loadFeed()
    this.scrollDown()

    this.et.addEventListener('to-leon', (event) => {
      this.createBubble({
        who: 'me',
        string: event.detail
      })
    })

    this.et.addEventListener('me-received', (event) => {
      this.createBubble({
        who: 'leon',
        string: event.detail
      })
    })

    // Add event delegation for clickable paths
    this.feed.addEventListener('click', (event) => {
      if (event.target.classList.contains('clickable-path')) {
        const path = event.target.getAttribute('data-path')
        if (path) {
          this.openPath(path)
        }
      }
    })

    this.feed.addEventListener(
      'scroll',
      () => {
        this.handleFeedScroll()
      },
      { passive: true }
    )
  }

  sendTo(who, string) {
    if (who === 'leon') {
      this.et.dispatchEvent(new CustomEvent('to-leon', { detail: string }))
    }
  }

  receivedFrom(who, string) {
    if (who === 'leon') {
      this.et.dispatchEvent(new CustomEvent('me-received', { detail: string }))
    }
  }

  isTyping(who, value) {
    if (who === 'leon') {
      if (value) {
        this.enableTyping()
      } else if (value === false) {
        this.disableTyping()
      }
    }
  }

  enableTyping() {
    if (!this.typing.classList.contains('on')) {
      this.typing.classList.add('on')
    }
  }

  disableTyping() {
    if (this.typing.classList.contains('on')) {
      this.typing.classList.remove('on')
    }
  }

  isElementNearBottom(element) {
    if (!element) {
      return true
    }

    const remainingScrollableDistance =
      element.scrollHeight - (element.scrollTop + element.clientHeight)

    return remainingScrollableDistance <= AUTO_SCROLL_BOTTOM_THRESHOLD_PX
  }

  handleFeedScroll() {
    if (!this.feed || this.isProgrammaticFeedScroll) {
      return
    }

    this.feedAutoScrollEnabled = this.isElementNearBottom(this.feed)
  }

  scrollDown(options = {}) {
    if (!this.feed) {
      return
    }

    const { force = false } = options

    if (!force && !this.feedAutoScrollEnabled) {
      return
    }

    this.isProgrammaticFeedScroll = true
    this.feed.scrollTo(0, this.feed.scrollHeight)

    requestAnimationFrame(() => {
      this.isProgrammaticFeedScroll = false
      this.feedAutoScrollEnabled = this.isElementNearBottom(this.feed)
    })
  }

  scrollReasoningContentToBottom(reasoningBlock) {
    if (!reasoningBlock?.content || !reasoningBlock.isAutoScrollEnabled) {
      return
    }

    reasoningBlock.isProgrammaticScroll = true
    reasoningBlock.content.scrollTop = reasoningBlock.content.scrollHeight

    requestAnimationFrame(() => {
      reasoningBlock.isProgrammaticScroll = false
      reasoningBlock.isAutoScrollEnabled = this.isElementNearBottom(
        reasoningBlock.content
      )
    })
  }

  getWidgetPayload(formattedString) {
    if (
      typeof formattedString !== 'string' ||
      !formattedString.includes('"component":"WidgetWrapper"')
    ) {
      return null
    }

    try {
      return JSON.parse(formattedString)
    } catch {
      return null
    }
  }

  getPlanWidgetInsertionPoint(widgetPayload) {
    if (!widgetPayload || widgetPayload.widget !== 'PlanWidget') {
      return null
    }

    // Always append new plan widgets as new bubbles.
    // Widget updates are handled via replaceMessageId targeting the same
    // messageId, so insertion-point heuristics are unnecessary and can cause
    // visual reuse across turns.
    return null
  }

  isPlanWidgetData(data) {
    return Boolean(data && typeof data === 'object' && data.widget === 'PlanWidget')
  }

  loadFeed() {
    return new Promise(async (resolve) => {
      if (this.parsedBubbles === null || this.parsedBubbles.length === 0) {
        this.noBubbleMessage.classList.remove('hide')
        localStorage.setItem('bubbles', JSON.stringify([]))
        this.parsedBubbles = []
        resolve()
      } else {
        for (let i = 0; i < this.parsedBubbles.length; i += 1) {
          const bubble = this.parsedBubbles[i]

          // Skip tool output markers when recreating bubbles
          if (
            bubble.originalString &&
            ToolUIHandler.isToolOutputMarker(bubble.originalString)
          ) {
            continue
          }

          this.createBubble({
            who: bubble.who,
            string: bubble.originalString
              ? bubble.originalString
              : bubble.string,
            save: false,
            isCreatingFromLoadingFeed: true,
            metrics: bubble.llmMetrics || null
          })

          if (i + 1 === this.parsedBubbles.length) {
            setTimeout(() => {
              resolve()
            }, 100)
          }
        }

        /**
         * Browse widgets that need to be fetched.
         * Reverse widgets to fetch the last widgets first.
         * Replace the loading content with the fetched widget
         */
        const widgetContainers = WIDGETS_TO_FETCH.reverse()
        for (let i = 0; i < widgetContainers.length; i += 1) {
          const widgetContainer = widgetContainers[i]
          const hasWidgetBeenFetched = WIDGETS_FETCH_CACHE.has(
            widgetContainer.widgetId
          )

          if (hasWidgetBeenFetched) {
            const fetchedWidget = WIDGETS_FETCH_CACHE.get(
              widgetContainer.widgetId
            )
            widgetContainer.reactRootNode.render(fetchedWidget.reactNode)

            setTimeout(() => {
              this.scrollDown()
            }, 100)

            continue
          }

          const data = await axios.get(
            `${this.serverURL}/api/v1/fetch-widget?skill_action=${widgetContainer.onFetch.actionName}&widget_id=${widgetContainer.widgetId}`
          )
          const fetchedWidget = data.data.widget
          const reactNode = fetchedWidget
            ? renderAuroraComponent(
                this.socket,
                fetchedWidget.componentTree,
                fetchedWidget.supportedEvents
              )
            : createElement(WidgetWrapper, {
                children: createElement(Flexbox, {
                  alignItems: 'center',
                  justifyContent: 'center',
                  children: createElement(Text, {
                    secondary: true,
                    children: 'This widget has been deleted.'
                  })
                })
              })

          widgetContainer.reactRootNode.render(reactNode)
          WIDGETS_FETCH_CACHE.set(widgetContainer.widgetId, {
            ...fetchedWidget,
            reactNode
          })
          setTimeout(() => {
            this.scrollDown()
          }, 100)
        }
      }
    })
  }

  createBubble(params) {
    const {
      who,
      string,
      metrics = null,
      save = true,
      bubbleId,
      isCreatingFromLoadingFeed = false,
      messageId,
      beforeElement = null
    } = params
    const container = document.createElement('div')
    const bubble = document.createElement('p')

    container.className = `bubble-container ${who}`
    bubble.className = 'bubble'

    if (messageId) {
      container.setAttribute('data-message-id', messageId)
    }

    // Store original string before formatting
    const originalString = string
    const formattedString = this.formatMessage(string)
    const widgetPayload = this.getWidgetPayload(formattedString)
    const autoPlanInsertionPoint = this.getPlanWidgetInsertionPoint(widgetPayload)
    const resolvedBeforeElement = beforeElement || autoPlanInsertionPoint

    bubble.innerHTML = formattedString

    if (bubbleId) {
      container.classList.add(bubbleId)
    }

    if (resolvedBeforeElement && resolvedBeforeElement.parentNode === this.feed) {
      this.feed.insertBefore(container, resolvedBeforeElement)
    } else {
      this.feed.appendChild(container)
    }
    container.appendChild(bubble)

    if (who === 'leon' && metrics) {
      container.appendChild(this.createMetricsElement(metrics))
    }

    let widgetComponentTree = null
    let widgetSupportedEvents = null

    /**
     * Widget rendering
     */
    if (
      formattedString.includes &&
      formattedString.includes('"component":"WidgetWrapper"')
    ) {
      const parsedWidget = widgetPayload || JSON.parse(formattedString)
      container.setAttribute('data-widget-id', parsedWidget.id)

      /**
       * On widget fetching, render the loader
       */
      if (isCreatingFromLoadingFeed && parsedWidget.onFetch) {
        const root = createRoot(container)

        root.render(
          createElement(WidgetWrapper, {
            children: createElement(Flexbox, {
              alignItems: 'center',
              justifyContent: 'center',
              children: createElement(Loader)
            })
          })
        )

        WIDGETS_TO_FETCH.push({
          reactRootNode: root,
          widgetId: parsedWidget.id,
          onFetch: parsedWidget.onFetch
        })

        return container
      }

      widgetComponentTree = parsedWidget.componentTree
      widgetSupportedEvents = parsedWidget.supportedEvents

      /**
       * On widget creation
       */
      const root = createRoot(container)

      const reactNode = renderAuroraComponent(
        this.socket,
        widgetComponentTree,
        widgetSupportedEvents
      )

      root.render(reactNode)
    }

    if (save) {
      this.saveBubble(who, originalString, formattedString, messageId, metrics)
    }

    return container
  }

  formatReasoningPhaseTitle(phase) {
    const normalizedPhase =
      typeof phase === 'string' && phase.trim()
        ? phase.replaceAll('_', ' ').toUpperCase()
        : 'EXECUTION'

    return `REASONING - ${normalizedPhase}`
  }

  createOrUpdateReasoningBlock(generationId, token, phase) {
    if (!generationId || !token) {
      return null
    }

    if (!this.noBubbleMessage.classList.contains('hide')) {
      this.noBubbleMessage.classList.add('hide')
    }

    let reasoningBlock = this.reasoningBlocks.get(generationId)

    if (!reasoningBlock) {
      const container = document.createElement('div')
      const block = document.createElement('div')
      const header = document.createElement('div')
      const icon = document.createElement('i')
      const title = document.createElement('span')
      const content = document.createElement('div')

      container.className = 'reasoning-block-container leon'
      container.setAttribute('data-reasoning-id', generationId)
      block.className = 'reasoning-block'
      header.className = 'reasoning-header'
      icon.className = 'ri-brain-ai-3-line reasoning-icon'
      title.className = 'reasoning-title'
      title.textContent = this.formatReasoningPhaseTitle(phase)
      content.className = 'reasoning-content'

      header.appendChild(icon)
      header.appendChild(title)
      block.appendChild(header)
      block.appendChild(content)
      container.appendChild(block)
      this.feed.appendChild(container)

      reasoningBlock = {
        container,
        content,
        text: '',
        isAutoScrollEnabled: true,
        isProgrammaticScroll: false
      }
      content.addEventListener(
        'scroll',
        () => {
          if (reasoningBlock.isProgrammaticScroll) {
            return
          }

          reasoningBlock.isAutoScrollEnabled = this.isElementNearBottom(content)
        },
        { passive: true }
      )
      this.reasoningBlocks.set(generationId, reasoningBlock)
    }

    reasoningBlock.text += token
    reasoningBlock.content.textContent = reasoningBlock.text
    this.scrollReasoningContentToBottom(reasoningBlock)

    return reasoningBlock.container
  }

  handleToolOutput(data) {
    const result = this.toolUIHandler.handleToolOutput(data)

    // Save to localStorage if it's a new group
    if (result && result.isNewGroup) {
      const { toolkitName, toolName, answer } = data
      const toolInfo = this.toolUIHandler.getToolGroupInfo(
        result.groupId,
        toolkitName,
        toolName,
        answer
      )

      this.saveBubble(
        'leon',
        toolInfo.originalString,
        toolInfo.formattedMessage,
        toolInfo.messageId
      )
    }
  }

  saveBubble(who, originalString, string, messageId, metrics = null) {
    if (!this.noBubbleMessage.classList.contains('hide')) {
      this.noBubbleMessage.classList.add('hide')
    }

    if (this.parsedBubbles.length === 62) {
      this.parsedBubbles.shift()
    }

    // Store both original and formatted strings
    this.parsedBubbles.push({
      who,
      string,
      originalString,
      messageId,
      llmMetrics: metrics
    })
    localStorage.setItem('bubbles', JSON.stringify(this.parsedBubbles))
    this.scrollDown()
  }

  formatMessage(message) {
    const isWidget =
      message.includes && message.includes('"component":"WidgetWrapper"')

    if (typeof message === 'string' && !isWidget) {
      message = message.replace(/\n/g, '<br />')

      // Handle HTTP/HTTPS URLs with simple regex
      message = message.replace(/https?:\/\/[^\s<>"{}|\\^`[\]]+/gi, (match) => {
        return `<a href="${match}" target="_blank" rel="noopener noreferrer" class="clickable-url" title="Open URL in browser">${match}</a>`
      })

      // Handle file paths with delimiters for exact matching
      message = message.replace(
        /\[FILE_PATH\](.*?)\[\/FILE_PATH\]/g,
        (match, filePath) => {
          return `<span class="clickable-path" data-path="${filePath}" title="Open in file explorer">${filePath}</span>`
        }
      )
    }

    return message
  }

  formatMetrics(metrics) {
    if (!metrics) {
      return ''
    }

    const inputTokens = Number(metrics.inputTokens || 0)
    const outputTokens = Number(metrics.outputTokens || 0)
    const totalTokens = Number(metrics.totalTokens || inputTokens + outputTokens)
    const durationSeconds = Number(metrics.durationMs || 0) / 1_000
    const tokensPerSecond = Number(
      metrics.tokensPerSecond || metrics.averagedPhaseTokensPerSecond || 0
    )
    const tokenFormatter = new Intl.NumberFormat()

    return `
      <span class="bubble-metric-item">
        <i class="ri-copper-coin-line" aria-hidden="true"></i>
        <span>${tokenFormatter.format(totalTokens)} (i:${tokenFormatter.format(inputTokens)}/o:${tokenFormatter.format(outputTokens)}) tok</span>
      </span>
      <span class="bubble-metric-separator" aria-hidden="true">•</span>
      <span class="bubble-metric-item">
        <i class="ri-time-line" aria-hidden="true"></i>
        <span>${durationSeconds.toFixed(1)}s</span>
      </span>
      <span class="bubble-metric-separator" aria-hidden="true">•</span>
      <span class="bubble-metric-item">
        <i class="ri-flashlight-line" aria-hidden="true"></i>
        <span>${tokensPerSecond.toFixed(2)} t/s</span>
      </span>
    `.trim()
  }

  createMetricsElement(metrics) {
    const metricsElement = document.createElement('div')

    metricsElement.className = 'bubble-metrics'
    metricsElement.innerHTML = this.formatMetrics(metrics)

    return metricsElement
  }

  updateBubbleMetrics(container, metrics) {
    if (!container) {
      return
    }

    const existingMetricsElement = container.querySelector('.bubble-metrics')

    if (!metrics) {
      if (existingMetricsElement) {
        existingMetricsElement.remove()
      }

      return
    }

    if (existingMetricsElement) {
      existingMetricsElement.innerHTML = this.formatMetrics(metrics)
      return
    }

    container.appendChild(this.createMetricsElement(metrics))
  }

  getLatestReasoningContainer() {
    const reasoningContainers = this.feed.querySelectorAll(
      '.reasoning-block-container'
    )

    if (reasoningContainers.length === 0) {
      return null
    }

    return reasoningContainers[reasoningContainers.length - 1] || null
  }

  replaceMessage(replaceMessageId, newData) {
    const existingBubble = document.querySelector(
      `[data-message-id="${replaceMessageId}"]`
    )
    const isPlanWidget = this.isPlanWidgetData(newData)
    const nextSibling = existingBubble ? existingBubble.nextSibling : null

    if (existingBubble) {
      existingBubble.remove()

      const bubbleIndex = this.parsedBubbles.findIndex(
        (bubble) => bubble.messageId === replaceMessageId
      )
      if (bubbleIndex !== -1) {
        this.parsedBubbles.splice(bubbleIndex, 1)
      }
    }

    const isTextAnswerPayload = Boolean(
      newData &&
        typeof newData === 'object' &&
        typeof newData.answer === 'string' &&
        !newData.widget &&
        !newData.componentTree
    )
    const bubbleString = isTextAnswerPayload
      ? newData.answer
      : typeof newData === 'string'
        ? newData
        : JSON.stringify(newData)
    const metrics =
      isTextAnswerPayload && newData.llmMetrics ? newData.llmMetrics : null

    const beforeElement = isPlanWidget ? null : nextSibling

    this.createBubble({
      who: 'leon',
      string: bubbleString,
      save: isPlanWidget,
      messageId: replaceMessageId,
      beforeElement,
      metrics
    })

    /**
     * Only scroll down on the first replacement of this message
     * to avoid repeating scrolling for every message replacement
     */
    if (!REPLACED_MESSAGES.has(replaceMessageId)) {
      REPLACED_MESSAGES.add(replaceMessageId)
      this.scrollDown()
    }
  }

  openPath(filePath) {
    // Send request to server to open the file path in system file explorer
    fetch(`${this.serverURL}/api/v1/open-path`, {
      method: 'POST',
      headers: {
        'Content-Type': 'application/json'
      },
      body: JSON.stringify({ path: filePath })
    })
      .then((response) => response.json())
      .then((data) => {
        if (!data.success) {
          console.error('Failed to open path:', data.error)
        }
      })
      .catch((error) => {
        console.error('Error opening path:', error)
      })
  }
}


================================================
FILE: app/src/js/client.js
================================================
import { io } from 'socket.io-client'

import Chatbot from './chatbot'
import VoiceEnergy from './voice-energy'
import { INIT_MESSAGES } from './constants'
import handleSuggestions from './suggestion-handler.js'

export default class Client {
  constructor(client, serverUrl, input) {
    this.client = client
    this._input = input
    this._suggestionContainer = document.querySelector('#suggestions-container')
    this.voiceSpeechElement = document.querySelector('#voice-speech')
    this.serverUrl = serverUrl
    this.socket = io(this.serverUrl)
    this.history = localStorage.getItem('history')
    this.parsedHistory = []
    this.chatbot = new Chatbot(this.socket, this.serverUrl)
    this.voiceEnergy = new VoiceEnergy(this)
    this._recorder = {}
    this._suggestions = []
    this._answerGenerationId = 'xxx'
    this._activeStreamGenerationId = null
    this._ttsAudioContext = null
    this._isLeonGeneratingAnswer = false
    this._isVoiceModeEnabled = false
    // this._ttsAudioContextes = {}
  }

  set input(newInput) {
    if (typeof newInput !== 'undefined') {
      this._input.value = newInput
    }
  }

  get input() {
    return this._input
  }

  set recorder(recorder) {
    this._recorder = recorder
  }

  get recorder() {
    return this._recorder
  }

  updateMood(mood) {
    if (window.leonConfigInfo.llm.enabled) {
      const moodContainer = document.querySelector('#mood')

      moodContainer.textContent = `Leon's mood: ${mood.emoji}`
      moodContainer.setAttribute('title', mood.type)
    }
  }

  async sendInitMessages() {
    for (let i = 0; i < INIT_MESSAGES.length; i++) {
      const messages = INIT_MESSAGES[i]
      const message = messages[Math.floor(Math.random() * messages.length)]
      const sendingDelay = Math.floor(Math.random() * 2000) + 1000
      const typingFactorDelay = Math.floor(Math.random() * 4) + 2

      setTimeout(() => {
        this.chatbot.isTyping('leon', true)
      }, sendingDelay / typingFactorDelay)

      await new Promise((resolve) => setTimeout(resolve, sendingDelay))

      this.chatbot.receivedFrom('leon', message)
      this.chatbot.isTyping('leon', false)
    }
  }

  setInitStatus(statusName, statusType) {
    window.leonInitStatusEvent.dispatchEvent(
      new CustomEvent('initStatusChange', {
        detail: {
          statusName,
          statusType
        }
      })
    )
  }

  asrStartRecording() {
    if (!window.leonConfigInfo.stt.enabled) {
      console.warn('ASR is not enabled')
      return
    }

    if (!this._isVoiceModeEnabled) {
      this.enableVoiceMode()

      this.voiceEnergy.status = 'listening'

      this.socket.emit('asr-start-record')
    }
  }

  init() {
    this.chatbot.init()
    this.voiceEnergy.init()

    if (window.leonConfigInfo?.tcpServer?.enabled === false) {
      this.setInitStatus('tcpServerBoot', 'success')
    }

    this.socket.on('connect', () => {
      this.socket.emit('init', this.client)
    })

    /**
     * Init status listeners
     */
    this.socket.on('init-client-core-server-handshake', (status) => {
      this.setInitStatus('clientCoreServerHandshake', status)
    })
    this.socket.on('init-tcp-server-boot', (status) => {
      this.setInitStatus('tcpServerBoot', status)
    })
    this.socket.on('init-llm', (status) => {
      this.setInitStatus('llm', status)
    })
    this.socket.on('init-llama-server-boot', (status) => {
      this.setInitStatus('llamaServerBoot', status)
    })
    this.socket.on('warmup-llm-duties', (status) => {
      this.setInitStatus('llmDutiesWarmUp', status)
    })

    this.socket.on('ready', () => {
      setTimeout(() => {
        const body = document.querySelector('body')
        body.classList.remove('settingup')
      }, 250)

      if (this.chatbot.parsedBubbles?.length === 0) {
        this.sendInitMessages()
      }
    })

    this.socket.on('answer', (data) => {
      /*if (this._isVoiceModeEnabled) {
        this.voiceEnergy.status = 'listening'
      }*/

      // Leon has finished to answer
      this._isLeonGeneratingAnswer = false

      /**
       * Handle message replacement if replaceMessageId is provided
       */
      if (data.replaceMessageId) {
        this.chatbot.replaceMessage(data.replaceMessageId, data)
        return
      }

      /**
       * Handle tool output messages
       */
      if (data.isToolOutput) {
        this.chatbot.handleToolOutput(data)
        return
      }

      /**
       * Handle widget data directly
       */
      if (data.widget || data.componentTree) {
        // Pass the entire widget data as JSON string for chatbot.js to handle
        const widgetString =
          typeof data === 'string' ? data : JSON.stringify(data)

        this.chatbot.createBubble({
          who: 'leon',
          string: widgetString,
          messageId: data.widget?.id || data.id || `msg-${Date.now()}`
        })

        return
      }

      const answerText = typeof data === 'string' ? data : data.answer
      const llmMetrics =
        data && typeof data === 'object' && data.llmMetrics
          ? data.llmMetrics
          : null

      /**
       * Just save the bubble if the newest bubble is from the streaming.
       * Otherwise, create a new bubble
       */
      const streamGenerationId =
        this._activeStreamGenerationId || this._answerGenerationId
      const streamedBubbleContainerElement = streamGenerationId
        ? document.querySelector(
            `.bubble-container.leon.${streamGenerationId}`
          )
        : null
      const isBubbleFromStreaming = Boolean(streamedBubbleContainerElement)

      if (isBubbleFromStreaming && streamedBubbleContainerElement) {
        this.chatbot.saveBubble(
          'leon',
          answerText,
          this.chatbot.formatMessage(answerText),
          null,
          llmMetrics
        )

        // Slightly delay the update to avoid the stream animation to be interrupted
        setTimeout(() => {
          // Update the text of the bubble (quick emoji fix)
          streamedBubbleContainerElement.querySelector('p.bubble').innerHTML =
            this.chatbot.formatMessage(answerText)
          this.chatbot.updateBubbleMetrics(
            streamedBubbleContainerElement,
            llmMetrics
          )
        }, 2_500)
      } else {
        this.chatbot.createBubble({
          who: 'leon',
          string: answerText,
          metrics: llmMetrics
        })
      }
      this.chatbot.scrollDown({ force: true })

      this._activeStreamGenerationId = null
      this._answerGenerationId = 'xxx'
    })

    this.socket.on('suggest', (data) => {
      setTimeout(() => {
        handleSuggestions(data, this.chatbot, this)
      }, 400)
      setTimeout(() => {
        this.chatbot.scrollDown()
      }, 450)
      /*data?.forEach((suggestionText) => {
        this.addSuggestion(suggestionText)
      })*/
    })

    this.socket.on('is-typing', (data) => {
      this.chatbot.isTyping('leon', data)
    })

    this.socket.on('recognized', (data, cb) => {
      this._input.value = data
      this.send('utterance')

      cb('string-received')
    })

    this.socket.on('widget-send-utterance', (utterance) => {
      this._input.value = utterance
      this.send('utterance')
    })

    this.socket.on('new-mood', (mood) => {
      this.updateMood(mood)
    })

    this.socket.on('llm-token', (data) => {
      if (this._isVoiceModeEnabled) {
        this.voiceEnergy.status = 'processing'
      }

      this._isLeonGeneratingAnswer = true
      const previousGenerationId = this._answerGenerationId
      const newGenerationId = data.generationId
      this._answerGenerationId = newGenerationId
      this._activeStreamGenerationId = newGenerationId
      const isSameGeneration = previousGenerationId === newGenerationId
      let bubbleContainerElement = null

      if (!isSameGeneration) {
        bubbleContainerElement = this.chatbot.createBubble({
          who: 'leon',
          string: data.token,
          save: false,
          bubbleId: newGenerationId
        })
      } else {
        bubbleContainerElement = document.querySelector(
          `.${previousGenerationId}`
        )
      }

      const bubbleElement = bubbleContainerElement.querySelector('p.bubble')

      // Token is already appened when it's a new generation
      if (isSameGeneration) {
        // bubbleElement.textContent += data.token

        const tokenSpan = document.createElement('span')
        tokenSpan.className = 'llm-token fade-in'
        tokenSpan.textContent = data.token

        bubbleElement.appendChild(tokenSpan)
      }

      this.chatbot.scrollDown()
    })

    this.socket.on('llm-reasoning-token', (data) => {
      if (!data?.generationId || !data?.token) {
        return
      }

      if (this._isVoiceModeEnabled) {
        this.voiceEnergy.status = 'processing'
      }

      this._isLeonGeneratingAnswer = true
      this.chatbot.createOrUpdateReasoningBlock(
        data.generationId,
        data.token,
        data.phase
      )
      this.chatbot.scrollDown()
    })

    this.socket.on('asr-speech', (text) => {
      if (!this._isVoiceModeEnabled) {
        this.enableVoiceMode()
      }

      this.voiceEnergy.status = 'listening'
      this._input.value = text

      if (this.voiceSpeechElement) {
        this.voiceSpeechElement.textContent = text
      }
    })

    this.socket.on('asr-end-of-owner-speech', () => {
      this.voiceEnergy.status = 'processing'

      setTimeout(() => {
        this.send('utterance')
      }, 200)
    })

    this.socket.on('asr-active-listening-disabled', () => {
      this.voiceEnergy.status = 'idle'
    })

    /**
     * Only used for "local" TTS provider as a PoC for now.
     * Target to do a better implementation in the future
     * with streaming support
     */
    this.socket.on('tts-stream', (data) => {
      this.voiceEnergy.status = 'talking'

      // const { audioId, chunk } = data
      const { chunk } = data
      this._ttsAudioContext = new AudioContext()
      // this._ttsAudioContextes[audioId] = ctx

      const source = this._ttsAudioContext.createBufferSource()
      this._ttsAudioContext.decodeAudioData(chunk, (buffer) => {
        source.buffer = buffer

        source.connect(this._ttsAudioContext.destination)
        source.start(0)
      })
    })

    /**
     * When Leon got interrupted by the owner voice
     * while he is speaking
     */
    this.socket.on('tts-interruption', async () => {
      if (this._ttsAudioContext) {
        await this._ttsAudioContext.close()
      }
    })

    this.socket.on('tts-end-of-speech', async () => {
      this.voiceEnergy.status = 'listening'
    })

    this.socket.on('audio-forwarded', (data, cb) => {
      const ctx = new AudioContext()
      const source = ctx.createBufferSource()

      ctx.decodeAudioData(data.buffer, (buffer) => {
        source.buffer = buffer

        source.connect(ctx.destination)
        source.start(0)

        /**
         * When the after speech option is enabled and
         * the answer is a final one
         */
        if (window.leonConfigInfo.after_speech && data.is_final_answer) {
          // Enable recording after the speech + 500ms
          setTimeout(() => {
            this._recorder.start()
            this._recorder.enabled = true

            // Check every second if the recorder is enabled to stop it
            const id = setInterval(() => {
              if (this._recorder.enabled) {
                if (this._recorder.countSilenceAfterTalk <= 8) {
                  // Stop recording if there was no noise for 8 seconds
                  if (this._recorder.countSilenceAfterTalk === 8) {
                    this._recorder.stop()
                    this._recorder.enabled = false
                    this._recorder.countSilenceAfterTalk = 0
                    clearInterval(id)
                  } else if (!this._recorder.noiseDetected) {
                    this._recorder.countSilenceAfterTalk += 1
                  } else {
                    clearInterval(id)
                  }
                }
              }
            }, 1_000)
          }, data.duration + 500)
        }
      })

      cb('audio-received')
    })

    if (this.history !== null) {
      this.parsedHistory = JSON.parse(this.history)
    }
  }

  send(keyword) {
    // Prevent from sending utterance if Leon is still generating text (stream)
    if (keyword === 'utterance' && this._isLeonGeneratingAnswer) {
      return false
    }

    if (this._input.value !== '') {
      this.socket.emit(keyword, {
        client: this.client,
        value: this._input.value.trim()
      })
      this.chatbot.sendTo('leon', this._input.value)
      this.chatbot.scrollDown({ force: true })

      this._suggestions.forEach((suggestion) => {
        // Remove all event listeners of the suggestion
        suggestion.replaceWith(suggestion.cloneNode(true))
        this._suggestionContainer.replaceChildren()
      })

      this.save()

      return true
    }

    return false
  }

  save() {
    let val = this._input.value

    if (localStorage.getItem('history') === null) {
      localStorage.setItem('history', JSON.stringify([]))
      this.parsedHistory = JSON.parse(localStorage.getItem('history'))
    } else if (this.parsedHistory.length >= 32) {
      this.parsedHistory.shift()
    }

    if (val[0] === ' ') {
      val = val.substr(1, val.length - 1)
    }

    if (this.parsedHistory[this.parsedHistory.length - 1] !== val) {
      this.parsedHistory.push(val)
      localStorage.setItem('history', JSON.stringify(this.parsedHistory))
    }

    this._input.value = ''
    setTimeout(() => {
      // Remove the last character to avoid the space
      this._input.value = this._input.value.slice(0, -1)
    }, 0)
  }

  /*addSuggestion(text) {
    const newSuggestion = document.createElement('button')
    newSuggestion.classList.add('suggestion')
    newSuggestion.textContent = text

    this._suggestionContainer.appendChild(newSuggestion)

    newSuggestion.addEventListener('click', (e) => {
      e.preventDefault()
      this.input = e.target.textContent
      this.send('utterance')
    })

    this._suggestions.push(newSuggestion)
  }*/

  enableVoiceMode() {
    if (!this._isVoiceModeEnabled) {
      this._isVoiceModeEnabled = true

      const body = document.querySelector('body')
      if (!body.classList.contains('voice-mode-enabled')) {
        body.classList.add('voice-mode-enabled')

        const voiceOverlayTransitor = document.createElement('div')
        voiceOverlayTransitor.id = 'voice-overlay-transitor'
        body.appendChild(voiceOverlayTransitor)
        voiceOverlayTransitor.addEventListener('animationend', () => {
          voiceOverlayTransitor.removeEventListener('animationend', () => {})
          voiceOverlayTransitor.remove()
        })
      }
    }
  }
  disableVoiceMode() {
    if (this._isVoiceModeEnabled) {
      this._isVoiceModeEnabled = false

      const body = document.querySelector('body')

      const voiceContainer = document.querySelector('#voice-container')
      if (voiceContainer) {
        voiceContainer.style.animation = 'none'
        voiceContainer.style.animation = null
      }

      if (body.classList.contains('voice-mode-enabled')) {
        body.classList.remove('voice-mode-enabled')
      }
    }
  }
}


================================================
FILE: app/src/js/constants.js
================================================
export const INIT_MESSAGES = [
  [
    'Hello there! Glad to e-meet meet you, I\'m Leon, your open-source personal assistant. While I\'m still learning and improving, I promise to do my best to be helpful.'
  ],
  [
    `<ul>
<li>We've got lots in the works. Check out <a href="http://roadmap.getleon.ai/" target="_blank">our roadmap</a>.</li>
<li>Stay updated on our progress by checking out our <a href="https://blog.getleon.ai/" target="_blank">blog</a>.</li>
<li>You can also get updates straight to your inbox <a href="https://newsletter.getleon.ai/subscription/form" target="_blank">here</a>.</li>
`
  ],
  [
    'Come hang out with us <a href="https://discord.gg/MNQqqKg" target="_blank">on Discord</a>! Once we release our official version, our community will be working together to build new skills for me. You won\'t want to miss out on the fun!'
  ],
  [
    'Just so you know, my creator is working tirelessly to improve my skills and features, dedicating 75% of his free time to the project on top of his full-time job. If you\'d like to help speed up my development, you can sponsor his work by clicking on this link: <strong><a href=\'http://sponsor.getleon.ai/\' target=\'_blank\'>sponsor.getleon.ai</a></strong>. Your support would mean a lot to us. Thank you for choosing me as your assistant!'
  ]
]


================================================
FILE: app/src/js/init.jsx
================================================
import { useEffect, useState, useRef } from 'react'
import { createRoot } from 'react-dom/client'
import {
  WidgetWrapper,
  Text,
  Icon,
  Flexbox,
  List,
  ListHeader,
  ListItem,
  Loader
} from '@leon-ai/aurora'

const container = document.querySelector('#init')
const root = createRoot(container)

function Item({ children, status }) {
  if (status === 'error') {
    return <ErrorListItem>{children}</ErrorListItem>
  }
  if (status === 'warning') {
    return <WarningListItem>{children}</WarningListItem>
  }
  if (status === 'success') {
    return <SuccessListItem>{children}</SuccessListItem>
  }
  if (status === 'loading') {
    return <LoadingListItem>{children}</LoadingListItem>
  }

  return <ListItem>{children}</ListItem>
}

function LoadingListItem({ children }) {
  return (
    <ListItem>
      <Flexbox flexDirection="row" alignItems="center" gap="sm">
        <Loader size="sm" />
        <Text>{children}</Text>
      </Flexbox>
    </ListItem>
  )
}
function ErrorListItem({ children }) {
  return (
    <ListItem>
      <Flexbox flexDirection="row" alignItems="center" gap="sm">
        <Icon
          iconName="close"
          size="sm"
          type="fill"
          bgShape="circle"
          color="red"
          bgColor="transparent-red"
        />
        <Text>{children}</Text>
      </Flexbox>
    </ListItem>
  )
}
function WarningListItem({ children }) {
  return (
    <ListItem>
      <Flexbox flexDirection="row" alignItems="center" gap="sm">
        <Icon
          iconName="alert"
          size="sm"
          type="fill"
          bgShape="circle"
          color="yellow"
          bgColor="transparent-yellow"
        />
        <Text>{children}</Text>
      </Flexbox>
    </ListItem>
  )
}
function SuccessListItem({ children }) {
  return (
    <ListItem>
      <Flexbox flexDirection="row" alignItems="center" gap="sm">
        <Icon
          iconName="check"
          size="sm"
          type="fill"
          bgShape="circle"
          color="green"
          bgColor="transparent-green"
        />
        <Text>{children}</Text>
      </Flexbox>
    </ListItem>
  )
}

function Init() {
  const parentRef = useRef(null)
  const [config, setConfig] = useState(() => ({ ...window.leonConfigInfo }))
  const usesLlamaCPP =
    config.llm?.workflowProvider === 'llamacpp' ||
    config.llm?.agentProvider === 'llamacpp'
  const [statusMap, setStatusMap] = useState({
    clientCoreServerHandshake: 'loading',
    tcpServerBoot:
      window.leonConfigInfo?.tcpServer?.enabled === false ? 'success' : 'loading',
    llm: 'loading',
    llamaServerBoot:
      window.leonConfigInfo?.llm?.workflowProvider === 'llamacpp' ||
      window.leonConfigInfo?.llm?.agentProvider === 'llamacpp'
        ? 'loading'
        : 'success',
    llmDutiesWarmUp: 'loading'
  })

  useEffect(() => {
    setTimeout(() => {
      if (parentRef.current) {
        parentRef.current.classList.remove('not-initialized')
      }
    }, 250)

    function handleStatusChange(event) {
      const { statusName, statusType } = event.detail

      setStatusMap((prev) => ({ ...prev, [statusName]: statusType }))
    }

    window.leonInitStatusEvent.addEventListener(
      'initStatusChange',
      handleStatusChange
    )
    return () =>
      window.leonInitStatusEvent.removeEventListener(
        'initStatusChange',
        handleStatusChange
      )
  }, [])

  const statuses = []
  for (let key of Object.keys(statusMap)) {
    if (key === 'tcpServerBoot' && config.tcpServer?.enabled === false) {
      statuses.push('success')
    }
    else if (key === 'llamaServerBoot' && !usesLlamaCPP) {
      statuses.push('success')
    }
    // If LLM is not enabled, we don't need to check for LLM duties warm up
    else if (
      key === 'llmDutiesWarmUp' &&
      (!config.llm?.enabled || !config.shouldWarmUpLLMDuties)
    ) {
      statuses.push('success')
    } else if (!config[key] || config[key].enabled) {
      statuses.push(statusMap[key])
    }
  }

  const areAllStatusesSuccess = statuses.every((status) => status === 'success')

  useEffect(() => {
    if (window.leonConfigInfo) {
      setConfig({ ...window.leonConfigInfo })
    }
  }, [window.leonConfigInfo])

  return (
    <div
      style={{
        position: 'fixed',
        width: '100vw',
        height: '100vh',
        zIndex: 9999,
        backgroundColor: 'var(--black-color)'
      }}
      ref={parentRef}
      className={areAllStatusesSuccess ? 'initialized' : 'not-initialized'}
    >
      <div
        style={{
          position: 'absolute',
          top: '33%',
          left: '50%',
          transform: 'translate(-50%, -50%)'
        }}
      >
        <WidgetWrapper noPadding>
          <List>
            <ListHeader>Leon is getting ready...</ListHeader>
            <Item status={statusMap.clientCoreServerHandshake}>
              Client and core server handshaked
            </Item>
            {config.tcpServer?.enabled !== false && (
              <Item status={statusMap.tcpServerBoot}>TCP server booted</Item>
            )}
            {config.llm && config.llm.enabled && (
              <Item status={statusMap.llm}>LLM loaded</Item>
            )}
            {usesLlamaCPP && (
              <Item status={statusMap.llamaServerBoot}>llama-server booted</Item>
            )}
            {config.shouldWarmUpLLMDuties && (
              <Item status={statusMap.llmDutiesWarmUp}>
                LLM duties warmed up
              </Item>
            )}
          </List>
        </WidgetWrapper>
      </div>
    </div>
  )
}

root.render(<Init />)


================================================
FILE: app/src/js/listener.js
================================================
const listener = {}

listener.listening = (
  stream,
  minDecibels,
  maxBlankTime,
  cbOnStart,
  cbOnEnd
) => {
  const ctx = new AudioContext()
  const analyser = ctx.createAnalyser()
  const streamNode = ctx.createMediaStreamSource(stream)
  streamNode.connect(analyser)
  analyser.minDecibels = minDecibels

  const data = new Uint8Array(analyser.frequencyBinCount)
  let silenceStart = performance.now()
  let triggered = false

  const loop = (time) => {
    requestAnimationFrame(loop)

    analyser.getByteFrequencyData(data)

    if (data.some((v) => v)) {
      if (triggered) {
        triggered = false

        cbOnStart()
      }
      silenceStart = time
    }

    if (!triggered && time - silenceStart > maxBlankTime) {
      cbOnEnd()

      triggered = true
    }
  }

  loop()
}

export default listener


================================================
FILE: app/src/js/main.js
================================================
import axios from 'axios'
import '@leon-ai/aurora/style.css'

window.leonInitStatusEvent = new EventTarget()

import './init'
import Client from './client'
// import Recorder from './recorder'
// import listener from './listener'
import { onkeydownstartrecording, onkeydowninput } from './onkeydown'

const config = {
  app: 'webapp',
  server_host: import.meta.env.VITE_LEON_HOST,
  server_port: import.meta.env.VITE_LEON_PORT,
  min_decibels: -40, // Noise detection sensitivity
  max_blank_time: 1_000 // Maximum time to consider a blank (ms)
}
const serverUrl =
  import.meta.env.VITE_LEON_NODE_ENV === 'production'
    ? ''
    : `${config.server_host}:${config.server_port}`

document.addEventListener('DOMContentLoaded', async () => {
  try {
    const response = await axios.get(`${serverUrl}/api/v1/info`)
    const input = document.querySelector('#utterance')
    const mic = document.querySelector('#mic-button')
    const v = document.querySelector('#version small')
    const infoButton = document.querySelector('#info')
    const client = new Client(config.app, serverUrl, input)
    // let rec = {}
    // let chunks = []

    window.leonConfigInfo = response.data
    const infoKeys = [
      'timeZone',
      'telemetry',
      'gpu',
      'graphicsComputeAPI',
      'totalVRAM',
      'freeVRAM',
      'usedVRAM',
      'llm',
      'shouldWarmUpLLMDuties',
      'isLLMActionRecognitionEnabled',
      'isLLMNLGEnabled',
      'stt',
      'tts',
      'mood',
      'version'
    ]
    const infoToDisplay = {}
    infoKeys.forEach((key) => {
      infoToDisplay[key] = window.leonConfigInfo[key]
    })

    v.textContent += window.leonConfigInfo.version

    client.updateMood(window.leonConfigInfo.mood)
    client.init()

    infoButton.addEventListener('click', () => {
      alert(JSON.stringify(infoToDisplay, null, 2))
    })

    /*if (navigator.mediaDevices && navigator.mediaDevices.getUserMedia) {
      navigator.mediaDevices
        .getUserMedia({ audio: true })
        .then((stream) => {
          if (MediaRecorder) {
            rec = new Recorder(stream, mic, window.leonConfigInfo)
            client.recorder = rec

            rec.ondataavailable((e) => {
              chunks.push(e.data)
            })

            rec.onstart(() => {
              /!* *!/
            })

            rec.onstop(() => {
              const blob = new Blob(chunks)
              chunks = []
              rec.enabled = false

              // Ensure there are some data
              if (blob.size >= 1_000) {
                client.socket.emit('recognize', blob)
              }
            })

            listener.listening(
              stream,
              config.min_decibels,
              config.max_blank_time,
              () => {
                // Noise detected
                rec.noiseDetected = true
              },
              () => {
                // Noise ended

                rec.noiseDetected = false
                if (rec.enabled && !rec.hotwordTriggered) {
                  rec.stop()
                  rec.enabled = false
                  rec.hotwordTriggered = false
                  rec.countSilenceAfterTalk = 0
                }
              }
            )

            client.socket.on('enable-record', () => {
              rec.hotwordTriggered = true
              rec.start()
              setTimeout(() => {
                rec.hotwordTriggered = false
              }, config.max_blank_time)
              rec.enabled = true
            })
          } else {
            console.error('MediaRecorder is not supported on your browser.')
          }
        })
        .catch((err) => {
          console.error(
            'MediaDevices.getUserMedia() threw the following error:',
            err
          )
        })
    } else {
      console.error(
        'MediaDevices.getUserMedia() is not supported on your browser.'
      )
    }*/

    document.addEventListener('keydown', (e) => {
      onkeydownstartrecording(e, () => {
        client.asrStartRecording()
        /*if (rec.enabled === false) {
          input.value = ''
          rec.start()
          rec.enabled = true
        } else {
          rec.stop()
          rec.enabled = false
        }*/
      })
    })

    input.addEventListener('keydown', (e) => {
      onkeydowninput(e, client)
    })

    mic.addEventListener('click', (e) => {
      e.preventDefault()

      client.asrStartRecording()

      /*if (rec.enabled === false) {
        rec.start()
        rec.enabled = true
      } else {
        rec.stop()
        rec.enabled = false
      }*/
    })
  } catch (e) {
    alert(`Error: ${e.message}; ${JSON.stringify(e.response?.data)}`)
    console.error(e)
  }
})


================================================
FILE: app/src/js/onkeydown.js
================================================
let index = -1
let parsedHistory = null

const onkeydowninput = (e, client) => {
  const key = e.which || e.keyCode

  if (localStorage.getItem('history') !== null && (key === 38 || key === 40)) {
    parsedHistory = JSON.parse(localStorage.getItem('history')).reverse()
  }

  if (key === 13 && !e.shiftKey) {
    if (client.send('utterance')) {
      parsedHistory = JSON.parse(localStorage.getItem('history')).reverse()
      index = -1
    }
  } else if (localStorage.getItem('history') !== null) {
    if (e.shiftKey) {
      if (key === 38 && index < parsedHistory.length - 1) {
        index += 1
        client.input = parsedHistory[index]
      } else if (key === 40 && index - 1 >= 0) {
        index -= 1
        client.input = parsedHistory[index]
      } else if (key === 40 && index - 1 < 0) {
        client.input = ''
        index = -1
      }
    }
  }
}

const onkeydownstartrecording = (e, cb) => {
  if ((e.metaKey || e.altKey) && e.key === 'c') {
    cb()
  }
}

export { onkeydowninput, onkeydownstartrecording }


================================================
FILE: app/src/js/recorder.js
================================================
import on from '../sounds/on.mp3'
import off from '../sounds/off.mp3'

export default class Recorder {
  constructor(stream, el, info) {
    this.recorder = new MediaRecorder(stream, { audioBitsPerSecond: 16000 })
    this.el = el
    this.audioOn = new Audio(on)
    this.audioOff = new Audio(off)
    this.playSound = true
    this.info = info
    this.enabled = false
    this.hotwordTriggered = false
    this.noiseDetected = false
    this.countSilenceAfterTalk = 0
  }

  start(playSound = true) {
    if (this.info.stt.enabled === false) {
      console.warn('Speech-to-text disabled')
    } else {
      this.playSound = playSound
      this.recorder.start(playSound)
    }
  }

  stop(playSound = true) {
    if (this.info.stt.enabled === false) {
      console.warn('Speech-to-text disabled')
    } else {
      this.playSound = playSound
      this.recorder.stop(playSound)
    }
  }

  onstart(cb) {
    this.recorder.onstart = (e) => {
      if (this.playSound) {
        this.audioOn.play()
      }
      this.el.classList.add('enabled')

      cb(e)
    }
  }

  onstop(cb) {
    this.recorder.onstop = (e) => {
      if (this.playSound) {
        this.audioOff.play()
      }
      this.el.classList.remove('enabled')

      cb(e)
    }
  }

  ondataavailable(cb) {
    this.recorder.ondataavailable = (e) => {
      cb(e)
    }
  }
}


================================================
FILE: app/src/js/render-aurora-component.js
================================================
import { createElement } from 'react'
import * as auroraComponents from '@leon-ai/aurora'

import * as customAuroraComponents from '../custom-aurora-components'

export default function renderAuroraComponent(
  socket,
  component,
  supportedEvents
) {
  if (component) {
    let reactComponent = auroraComponents[component.component]
    /**
     * Find custom component if a former component is not found
     */
    if (!reactComponent) {
      reactComponent = customAuroraComponents[component.component]
    }

    if (!reactComponent) {
      console.error(`Component ${component.component} not found`)
      return null
    }

    // Check if the browsed component has a supported event and bind it
    if (reactComponent && Array.isArray(component.events)) {
      component.events.forEach((event) => {
        if (supportedEvents.includes(event.type)) {
          component.props[event.type] = (data) => {
            const { method } = event

            socket.emit('widget-event', { method, data })
          }
        }
      })
    }

    // When children is a component, then wrap it in an array to render properly
    const isComponent = !!component.props?.children?.component
    if (isComponent) {
      component.props.children = [component.props.children]
    }

    if (component.props?.children && Array.isArray(component.props.children)) {
      component.props.children = component.props.children.map((child) => {
        return renderAuroraComponent(socket, child, supportedEvents)
      })
    }

    return createElement(reactComponent, component.props)
  }
}


================================================
FILE: app/src/js/suggestion-handler.js
================================================
import { createElement } from 'react'
import { createRoot } from 'react-dom/client'
import { WidgetWrapper, List, ListHeader, ListItem } from '@leon-ai/aurora'

export default function handleSuggestions(data, chatbot, client) {
  const container = document.createElement('div')
  container.className = 'bubble-container leon'

  chatbot.feed.appendChild(container)

  const root = createRoot(container)

  root.render(
    createElement(WidgetWrapper, {
      noPadding: true,
      children: createElement(List, {
        children: [
          createElement(ListHeader, {
            children: 'Suggestions'
          }),
          ...data.map((suggestionText) => {
            return createElement(ListItem, {
              children: suggestionText,
              name: 'suggestion',
              value: suggestionText,
              onClick: (suggestion) => {
                const parent = container.parentNode

                if (parent) {
                  parent.removeChild(container)
                }

                client.input.value = suggestion.value
                client.send('utterance')
              }
            })
          })
        ]
      })
    })
  )
}


================================================
FILE: app/src/js/tool-ui-handler.js
================================================
/**
 * Tool UI Handler
 * Manages the display and interaction of tool output in shell-like containers
 */
export default class ToolUIHandler {
  constructor(feedElement, scrollDownCallback, formatMessageCallback) {
    this.feed = feedElement
    this.scrollDown = scrollDownCallback
    this.formatMessage = formatMessageCallback
    this.toolGroups = new Map() // Track tool group containers
  }

  /**
   * Handle tool output messages with shell-like UI
   */
  handleToolOutput(data) {
    const {
      toolkitName,
      toolName,
      toolGroupId,
      answer,
      replaceMessageId,
      key
    } = data

    // Check if we need to replace an existing message
    if (replaceMessageId) {
      this.replaceToolMessage(replaceMessageId, data)
      return
    }

    // Extract answer key from the key (take part after last dot)
    const answerKey = key ? key.split('.').pop() : 'unknown'

    // Create a fallback group ID if none provided
    const groupId = toolGroupId || `${toolkitName}_${toolName}_${Date.now()}`

    // Get or create tool group container
    let toolGroupContainer = this.toolGroups.get(groupId)

    if (!toolGroupContainer) {
      toolGroupContainer = this.createToolGroupContainer(
        groupId,
        toolkitName,
        toolName,
        answerKey
      )
      this.toolGroups.set(groupId, toolGroupContainer)
    }

    // Add the tool message to the shell output
    this.addToolMessage(toolGroupContainer, answer)

    // Auto-scroll to bottom
    this.scrollDown()

    return {
      groupId,
      isNewGroup: toolGroupContainer.isNew
    }
  }

  /**
   * Create a new tool group container
   */
  createToolGroupContainer(groupId, toolkitName, toolName, answerKey) {
    // Create new tool group container
    const groupContainer = document.createElement('div')
    groupContainer.className = 'tool-group-container'
    groupContainer.setAttribute('data-tool-group-id', groupId)

    // Create tool header (expandable)
    const toolHeader = document.createElement('div')
    toolHeader.className = 'tool-header'
    toolHeader.innerHTML = `
      <i class="ri-terminal-line tool-icon"></i>
      <span class="tool-name">${toolkitName} toolkit → ${toolName} → ${answerKey}</span>
      <i class="ri-arrow-down-s-line expand-icon"></i>
    `

    // Create tool content area
    const toolContent = document.createElement('div')
    toolContent.className = 'tool-content'

    // Create shell output area
    const shellOutput = document.createElement('div')
    shellOutput.className = 'shell-output'

    toolContent.appendChild(shellOutput)
    groupContainer.appendChild(toolHeader)
    groupContainer.appendChild(toolContent)

    // Add expand/collapse functionality
    this.addExpandCollapseHandler(toolHeader, toolContent)

    // Initially expanded
    // toolContent.classList.add('expanded')
    // toolHeader.querySelector('.expand-icon').classList.add('rotated')

    this.feed.appendChild(groupContainer)

    return {
      container: groupContainer,
      toolHeader: toolHeader,
      toolContent: toolContent,
      shellOutput: shellOutput,
      isNew: true
    }
  }

  /**
   * Add expand/collapse functionality to tool header
   */
  addExpandCollapseHandler(toolHeader, toolContent) {
    toolHeader.addEventListener('click', () => {
      const isExpanded = toolContent.classList.contains('expanded')
      const expandIcon = toolHeader.querySelector('.expand-icon')

      if (isExpanded) {
        toolContent.classList.remove('expanded')
        expandIcon.classList.remove('rotated')
      } else {
        toolContent.classList.add('expanded')
        expandIcon.classList.add('rotated')
      }
    })
  }

  /**
   * Add a tool message to the shell output
   */
  addToolMessage(toolGroupContainer, message) {
    const messageElement = document.createElement('div')
    messageElement.className = 'shell-message'

    // Format the message
    const formattedMessage = this.formatMessage(message)
    messageElement.innerHTML = `<span class="shell-prompt">></span> ${formattedMessage}`

    toolGroupContainer.shellOutput.appendChild(messageElement)

    // Mark as no longer new after first message
    if (toolGroupContainer.isNew) {
      toolGroupContainer.isNew = false
    }
  }

  /**
   * Replace a tool message (for progress updates, etc.)
   */
  replaceToolMessage(replaceMessageId, newData) {
    // Find existing tool message by ID
    const existingMessage = document.querySelector(
      `[data-message-id="${replaceMessageId}"]`
    )

    if (existingMessage && existingMessage.closest('.tool-group-container')) {
      // If it's within a tool container, update just that message
      const formattedMessage = this.formatMessage(newData.answer)
      existingMessage.innerHTML = `<span class="shell-prompt">></span> ${formattedMessage}`
    } else {
      // Fallback: create new tool output
      this.handleToolOutput(newData)
    }
  }

  /**
   * Get tool group info for saving to localStorage
   */
  getToolGroupInfo(groupId, toolkitName, toolName, message) {
    return {
      originalString: `[TOOL_OUTPUT:${groupId}] ${toolkitName} → ${toolName}`,
      messageId: `tool-${groupId}`,
      formattedMessage: this.formatMessage(message)
    }
  }

  /**
   * Check if a message is a tool output marker
   */
  static isToolOutputMarker(messageString) {
    return messageString && messageString.startsWith('[TOOL_OUTPUT:')
  }

  /**
   * Clear all tool groups (useful for cleanup)
   */
  clearToolGroups() {
    this.toolGroups.clear()
  }

  /**
   * Get the number of active tool groups
   */
  getToolGroupCount() {
    return this.toolGroups.size
  }

  /**
   * Get a specific tool group by ID
   */
  getToolGroup(groupId) {
    return this.toolGroups.get(groupId)
  }

  /**
   * Remove a tool group
   */
  removeToolGroup(groupId) {
    const toolGroup = this.toolGroups.get(groupId)
    if (toolGroup) {
      toolGroup.container.remove()
      this.toolGroups.delete(groupId)
    }
  }
}


================================================
FILE: app/src/js/voice-energy.js
================================================
const STATUS = {
  listening: 'Listening...',
  processing: 'Processing...',
  talking: 'Talking...',
  idle: 'Idle'
}

export default class VoiceEnergy {
  constructor(client) {
    this.client = client
    this.voiceEnergyContainerElement = document.querySelector(
      '#voice-energy-container'
    )
    this.voiceOverlayElement = document.querySelector('#voice-overlay-bg')
    this.statusElement = document.querySelector('#voice-status')
    this._status = 'idle'
  }

  get status() {
    return this._status
  }

  set status(newStatus) {
    if (this._status !== newStatus) {
      this._status = newStatus

      if (this.statusElement) {
        this.statusElement.textContent = STATUS[newStatus]
      }

      // Clean up speech text when listening
      if (newStatus === 'listening' && this.client.voiceSpeechElement) {
        this.client.voiceSpeechElement.textContent = ''
      }

      if (this.voiceEnergyContainerElement) {
        this.voiceEnergyContainerElement.className = ''
        this.voiceEnergyContainerElement.classList.add(newStatus)
      }
    }
  }

  init() {
    if (this.voiceEnergyContainerElement) {
      if (this.voiceOverlayElement) {
        this.voiceOverlayElement.addEventListener('click', (e) => {
          e.preventDefault()
          this.client.disableVoiceMode()
        })
      }

      const particles = new Set()
      const particleColors = ['blue', 'pink']

      for (let i = 0; i < 32; i += 1) {
        const particle = document.createElement('div')
        const randomColor = Math.floor(Math.random() * 2)
        let random = Math.floor(Math.random() * 32)

        while (particles.has(random)) {
          random = Math.floor(Math.random() * 32)
        }

        particles.add(random)
        particle.setAttribute('data-particle', String(random))
        particle.classList.add('voice-particle', particleColors[randomColor])
        particle.style.transform = `rotate(${
          i * 11.25
        }deg) translate(110px) rotate(-${i * 11.25}deg)`
        this.voiceEnergyContainerElement.appendChild(particle)
      }
    }
  }
}


================================================
FILE: app/vite.config.js
================================================
import dns from 'node:dns'

import dotenv from 'dotenv'
import { defineConfig } from 'vite'
import react from '@vitejs/plugin-react'

dotenv.config()

dns.setDefaultResultOrder('verbatim')

// Map necessary Leon's env vars as Vite only expose VITE_*
process.env.VITE_LEON_NODE_ENV = process.env.LEON_NODE_ENV
process.env.VITE_LEON_HOST = process.env.LEON_HOST
process.env.VITE_LEON_PORT = process.env.LEON_PORT

export default defineConfig({
  root: 'app/src',
  build: {
    outDir: '../dist',
    emptyOutDir: true
  },
  server: {
    port: 3000
  },
  plugins: [react()]
})


================================================
FILE: bin/cmake/versions.json
================================================
{
  "cmake": "4.3.0"
}


================================================
FILE: bin/llama.cpp/versions.json
================================================
{
  "llama.cpp": "b8417"
}


================================================
FILE: bin/ninja/versions.json
================================================
{
  "ninja": "1.13.2"
}


================================================
FILE: bin/pytorch/versions.json
================================================
{
  "torch": "2.9.0"
}


================================================
FILE: bridges/nodejs/.npmrc
================================================
package-lock=false
save-exact=true


================================================
FILE: bridges/nodejs/package.json
================================================
{
  "name": "leon-nodejs-bridge",
  "description": "Leon's Node.js bridge to communicate between the core and skills made with JavaScript",
  "main": "dist/bin/leon-nodejs-bridge.js",
  "type": "module",
  "author": {
    "name": "Louis Grenard",
    "email": "louis@getleon.ai",
    "url": "https://twitter.com/grenlouis"
  },
  "license": "MIT",
  "homepage": "https://getleon.ai",
  "bugs": {
    "url": "https://github.com/leon-ai/leon/issues"
  },
  "dependencies": {
    "axios": "1.4.0",
    "ipull": "4.0.3",
    "lodash": "4.17.21"
  },
  "devDependencies": {
    "@types/lodash": "4.14.194"
  }
}


================================================
FILE: bridges/nodejs/src/constants.ts
================================================
import fs from 'node:fs'
import path from 'node:path'

import type { SkillLocaleConfigSchema } from '@/schemas/skill-schemas'

import { IntentObject, NLPAction } from '@sdk/types'

const args = process.argv.slice(2)
const runtimeIndex = args.indexOf('--runtime')
const runtime =
  runtimeIndex >= 0 && args[runtimeIndex + 1] ? args[runtimeIndex + 1] : 'skill'
const filteredArgs = args.filter((_, index) => {
  if (index === runtimeIndex || index === runtimeIndex + 1) {
    return false
  }
  return true
})
const intentPathCandidate = filteredArgs.find((arg) => !arg.startsWith('--'))
const INTENT_OBJ_FILE_PATH =
  runtime === 'skill' ? intentPathCandidate : undefined

export const LEON_VERSION = process.env['npm_package_version']

export const RUNTIME = runtime

const BIN_PATH = path.join(process.cwd(), 'bin')
const BRIDGES_PATH = path.join(process.cwd(), 'bridges')
const NODEJS_BRIDGE_ROOT_PATH = path.join(BRIDGES_PATH, 'nodejs')
const NODEJS_BRIDGE_SRC_PATH = path.join(NODEJS_BRIDGE_ROOT_PATH, 'src')
const NODEJS_BRIDGE_VERSION_FILE_PATH = path.join(
  NODEJS_BRIDGE_SRC_PATH,
  'version.ts'
)

export const TOOLKITS_PATH = path.join(BRIDGES_PATH, 'toolkits')

export const [, NODEJS_BRIDGE_VERSION] = fs
  .readFileSync(NODEJS_BRIDGE_VERSION_FILE_PATH, 'utf8')
  .split("'")

let parsedIntentObject: IntentObject | null = null
if (INTENT_OBJ_FILE_PATH) {
  if (!fs.existsSync(INTENT_OBJ_FILE_PATH)) {
    throw new Error(`Intent file not found: ${INTENT_OBJ_FILE_PATH}`)
  }
  parsedIntentObject = JSON.parse(
    fs.readFileSync(INTENT_OBJ_FILE_PATH, 'utf8')
  ) as IntentObject
}

export const INTENT_OBJECT: IntentObject = parsedIntentObject
  ? parsedIntentObject
  : ({} as IntentObject)

export const NVIDIA_LIBS_PATH = path.join(BIN_PATH, 'nvidia')

export const PYTORCH_PATH = path.join(BIN_PATH, 'pytorch')
export const PYTORCH_TORCH_PATH = path.join(PYTORCH_PATH, 'torch')

export const SKILLS_PATH = path.join(process.cwd(), 'skills')
export const SKILL_PATH =
  runtime === 'skill' && parsedIntentObject
    ? path.join(SKILLS_PATH, parsedIntentObject.skill_name)
    : ''
const SKILL_LOCALE_CONFIG_CONTENT =
  runtime === 'skill' && INTENT_OBJ_FILE_PATH && parsedIntentObject
    ? (() => {
        const skillLocalePath = path.join(
          SKILL_PATH,
          'locales',
          parsedIntentObject.extra_context.lang + '.json'
        )
        return JSON.parse(
          fs.existsSync(skillLocalePath)
            ? fs.readFileSync(skillLocalePath, 'utf8')
            : `{"variables": {}, "common_answers": {}, "widget_contents": {}, "actions": {"${parsedIntentObject.action_name}": {}}}`
        )
      })()
    : {
        variables: {},
        common_answers: {},
        widget_contents: {},
        actions: {}
      }

export const SKILL_LOCALE_CONFIG: SkillLocaleConfigSchema &
  SkillLocaleConfigSchema['actions'][NLPAction] = {
  variables: SKILL_LOCALE_CONFIG_CONTENT.variables,
  common_answers: SKILL_LOCALE_CONFIG_CONTENT.common_answers,
  widget_contents: SKILL_LOCALE_CONFIG_CONTENT.widget_contents,
  ...((runtime === 'skill' && parsedIntentObject
    ? SKILL_LOCALE_CONFIG_CONTENT.actions[
        parsedIntentObject.action_name as NLPAction
      ]
    : {}) || {})
}


================================================
FILE: bridges/nodejs/src/main.ts
================================================
import path from 'node:path'

import { FileHelper } from '@/helpers/file-helper'

import type { ActionFunction, ActionParams } from '@sdk/types'
import { INTENT_OBJECT } from '@bridge/constants'
import { ParamsHelper } from '@sdk/params-helper'
import { leon } from '@sdk/leon'
import { setToolReporter } from '@sdk/tool-reporter'
;(async (): Promise<void> => {
  setToolReporter(async (input) => {
    await leon.answer(input)
  })

  const {
    lang,
    sentiment,
    context_name,
    skill_name,
    action_name,
    skill_config_path,
    extra_context
  } = INTENT_OBJECT

  const params: ActionParams = {
    lang,
    utterance: INTENT_OBJECT.utterance as ActionParams['utterance'],
    action_arguments:
      INTENT_OBJECT.action_arguments as ActionParams['action_arguments'],
    entities: INTENT_OBJECT.entities as ActionParams['entities'],
    sentiment,
    context_name,
    skill_name,
    action_name,
    context: INTENT_OBJECT.context as ActionParams['context'],
    skill_config: INTENT_OBJECT.skill_config as ActionParams['skill_config'],
    skill_config_path,
    extra_context
  }

  try {
    const actionModule = await FileHelper.dynamicImportFromFile(
      path.join(
        process.cwd(),
        'skills',
        skill_name,
        'src',
        'actions',
        `${action_name}.ts`
      )
    )
    const actionFunction: ActionFunction = actionModule.run
    const paramsHelper = new ParamsHelper(params)

    await actionFunction(params, paramsHelper)
  } catch (e) {
    console.error(
      `Error while running "${skill_name}" skill "${action_name}" action:`,
      e
    )
  }
})()


================================================
FILE: bridges/nodejs/src/sdk/aurora/button.ts
================================================
import { type ButtonProps } from '@leon-ai/aurora'

import { WidgetComponent } from '../widget-component'

export class Button extends WidgetComponent<ButtonProps> {
  constructor(props: ButtonProps) {
    super(props)
  }
}


================================================
FILE: bridges/nodejs/src/sdk/aurora/card.ts
================================================
import { type CardProps } from '@leon-ai/aurora'

import { WidgetComponent } from '../widget-component'

export class Card extends WidgetComponent<CardProps> {
  constructor(props: CardProps) {
    super(props)
  }
}


================================================
FILE: bridges/nodejs/src/sdk/aurora/checkbox.ts
================================================
import { type CheckboxProps } from '@leon-ai/aurora'

import { WidgetComponent } from '../widget-component'

export class Checkbox extends WidgetComponent<CheckboxProps> {
  constructor(props: CheckboxProps) {
    super(props)
  }
}


================================================
FILE: bridges/nodejs/src/sdk/aurora/circular-progress.ts
================================================
import { type CircularProgressProps } from '@leon-ai/aurora'

import { WidgetComponent } from '../widget-component'

export class CircularProgress extends WidgetComponent<CircularProgressProps> {
  constructor(props: CircularProgressProps) {
    super(props)
  }
}


================================================
FILE: bridges/nodejs/src/sdk/aurora/flexbox.ts
================================================
import { type FlexboxProps } from '@leon-ai/aurora'

import { WidgetComponent } from '../widget-component'

export class Flexbox extends WidgetComponent<FlexboxProps> {
  constructor(props: FlexboxProps) {
    super(props)
  }
}


================================================
FILE: bridges/nodejs/src/sdk/aurora/form.ts
================================================
import { type FormProps } from '@leon-ai/aurora'

import { WidgetComponent } from '../widget-component'

export class Form extends WidgetComponent<FormProps> {
  constructor(props: FormProps) {
    super(props)
  }
}


================================================
FILE: bridges/nodejs/src/sdk/aurora/icon-button.ts
================================================
import { type IconButtonProps } from '@leon-ai/aurora'

import { WidgetComponent } from '../widget-component'

export class IconButton extends WidgetComponent<IconButtonProps> {
  constructor(props: IconButtonProps) {
    super(props)
  }
}


================================================
FILE: bridges/nodejs/src/sdk/aurora/icon.ts
================================================
import { type IconProps } from '@leon-ai/aurora'

import { WidgetComponent } from '../widget-component'

export class Icon extends WidgetComponent<IconProps> {
  constructor(props: IconProps) {
    super(props)
  }
}


================================================
FILE: bridges/nodejs/src/sdk/aurora/image.ts
================================================
import { type ImageProps } from '@leon-ai/aurora'

import { WidgetComponent } from '../widget-component'

export class Image extends WidgetComponent<ImageProps> {
  constructor(props: ImageProps) {
    super(props)
  }
}


================================================
FILE: bridges/nodejs/src/sdk/aurora/index.ts
================================================
export * from './button'
export * from './card'
export * from './checkbox'
export * from './circular-progress'
export * from './flexbox'
export * from './form'
export * from './icon'
export * from './icon-button'
export * from './image'
export * from './input'
export * from './link'
export * from './list'
export * from './list-header'
export * from './list-item'
export * from './loader'
export * from './progress'
export * from './radio'
export * from './radio-group'
export * from './range-slider'
export * from './scroll-container'
export * from './select'
export * from './select-option'
export * from './status'
export * from './switch'
export * from './tab'
export * from './tab-content'
export * from './tab-group'
export * from './tab-list'
export * from './text'
export * from './widget-wrapper'


================================================
FILE: bridges/nodejs/src/sdk/aurora/input.ts
================================================
import { type InputProps } from '@leon-ai/aurora'

import { WidgetComponent } from '../widget-component'

export class Input extends WidgetComponent<InputProps> {
  constructor(props: InputProps) {
    super(props)
  }
}


================================================
FILE: bridges/nodejs/src/sdk/aurora/link.ts
================================================
import { type LinkProps } from '@leon-ai/aurora'

import { WidgetComponent } from '../widget-component'

export class Link extends WidgetComponent<LinkProps> {
  constructor(props: LinkProps) {
    super(props)
  }
}


================================================
FILE: bridges/nodejs/src/sdk/aurora/list-header.ts
================================================
import { type ListHeaderProps } from '@leon-ai/aurora'

import { WidgetComponent } from '../widget-component'

export class ListHeader extends WidgetComponent<ListHeaderProps> {
  constructor(props: ListHeaderProps) {
    super(props)
  }
}


================================================
FILE: bridges/nodejs/src/sdk/aurora/list-item.ts
================================================
import { type ListItemProps } from '@leon-ai/aurora'

import { WidgetComponent } from '../widget-component'

export class ListItem extends WidgetComponent<ListItemProps> {
  constructor(props: ListItemProps) {
    super(props)
  }
}


================================================
FILE: bridges/nodejs/src/sdk/aurora/list.ts
================================================
import { type ListProps } from '@leon-ai/aurora'

import { WidgetComponent } from '../widget-component'

export class List extends WidgetComponent<ListProps> {
  constructor(props: ListProps) {
    super(props)
  }
}


================================================
FILE: bridges/nodejs/src/sdk/aurora/loader.ts
================================================
import { type LoaderProps } from '@leon-ai/aurora'

import { WidgetComponent } from '../widget-component'

export class Loader extends WidgetComponent<LoaderProps> {
  constructor(props: LoaderProps) {
    super(props)
  }
}


================================================
FILE: bridges/nodejs/src/sdk/aurora/progress.ts
================================================
import { type ProgressProps } from '@leon-ai/aurora'

import { WidgetComponent } from '../widget-component'

export class Progress extends WidgetComponent<ProgressProps> {
  constructor(props: ProgressProps) {
    super(props)
  }
}


================================================
FILE: bridges/nodejs/src/sdk/aurora/radio-group.ts
================================================
import { type RadioGroupProps } from '@leon-ai/aurora'

import { WidgetComponent } from '../widget-component'

export class RadioGroup extends WidgetComponent<RadioGroupProps> {
  constructor(props: RadioGroupProps) {
    super(props)
  }
}


================================================
FILE: bridges/nodejs/src/sdk/aurora/radio.ts
================================================
import { type RadioProps } from '@leon-ai/aurora'

import { WidgetComponent } from '../widget-component'

export class Radio extends WidgetComponent<RadioProps> {
  constructor(props: RadioProps) {
    super(props)
  }
}


================================================
FILE: bridges/nodejs/src/sdk/aurora/range-slider.ts
================================================
import { type RangeSliderProps } from '@leon-ai/aurora'

import { WidgetComponent } from '../widget-component'

export class RangeSlider extends WidgetComponent<RangeSliderProps> {
  constructor(props: RangeSliderProps) {
    super(props)
  }
}


================================================
FILE: bridges/nodejs/src/sdk/aurora/scroll-container.ts
================================================
import { type ScrollContainerProps } from '@leon-ai/aurora'

import { WidgetComponent } from '../widget-component'

export class ScrollContainer extends WidgetComponent<ScrollContainerProps> {
  constructor(props: ScrollContainerProps) {
    super(props)
  }
}


================================================
FILE: bridges/nodejs/src/sdk/aurora/select-option.ts
================================================
import { type SelectOptionProps } from '@leon-ai/aurora'

import { WidgetComponent } from '../widget-component'

export class SelectOption extends WidgetComponent<SelectOptionProps> {
  constructor(props: SelectOptionProps) {
    super(props)
  }
}


================================================
FILE: bridges/nodejs/src/sdk/aurora/select.ts
================================================
import { type SelectProps } from '@leon-ai/aurora'

import { WidgetComponent } from '../widget-component'

export class Select extends WidgetComponent<SelectProps> {
  constructor(props: SelectProps) {
    super(props)
  }
}


================================================
FILE: bridges/nodejs/src/sdk/aurora/status.ts
================================================
import { type StatusProps } from '@leon-ai/aurora'

import { WidgetComponent } from '../widget-component'

export class Status extends WidgetComponent<StatusProps> {
  constructor(props: StatusProps) {
    super(props)
  }
}


================================================
FILE: bridges/nodejs/src/sdk/aurora/switch.ts
===============================================
Download .txt
gitextract_onovndeo/

├── .changelogrc
├── .editorconfig
├── .env.sample
├── .github/
│   ├── CODE_OF_CONDUCT.md
│   ├── CONTRIBUTING.md
│   ├── FUNDING.yml
│   ├── ISSUE_TEMPLATE/
│   │   ├── BUG.md
│   │   ├── DOCS.md
│   │   ├── FEATURE_REQUEST.md
│   │   ├── IMPROVEMENT.md
│   │   └── QUESTION.md
│   ├── PULL_REQUEST_TEMPLATE.md
│   └── workflows/
│       ├── build.yml
│       ├── lint.yml
│       ├── pre-release-nodejs-bridge.yml
│       ├── pre-release-python-bridge.yml
│       ├── pre-release-tcp-server.yml
│       └── tests.yml
├── .gitignore
├── .gitpod.yml
├── .husky/
│   ├── commit-msg
│   └── pre-commit
├── .lintstagedrc
├── .npmrc
├── .nvmrc
├── CHANGELOG.md
├── LICENSE.md
├── README.md
├── app/
│   ├── src/
│   │   ├── css/
│   │   │   ├── style.scss
│   │   │   └── voice-energy/
│   │   │       ├── base.scss
│   │   │       ├── idle.scss
│   │   │       ├── listening.scss
│   │   │       ├── main.scss
│   │   │       ├── processing.scss
│   │   │       └── talking.scss
│   │   ├── custom-aurora-components/
│   │   │   ├── index.ts
│   │   │   └── timer/
│   │   │       ├── index.ts
│   │   │       └── timer.tsx
│   │   ├── index.html
│   │   └── js/
│   │       ├── chatbot.js
│   │       ├── client.js
│   │       ├── constants.js
│   │       ├── init.jsx
│   │       ├── listener.js
│   │       ├── main.js
│   │       ├── onkeydown.js
│   │       ├── recorder.js
│   │       ├── render-aurora-component.js
│   │       ├── suggestion-handler.js
│   │       ├── tool-ui-handler.js
│   │       └── voice-energy.js
│   └── vite.config.js
├── bin/
│   ├── cmake/
│   │   └── versions.json
│   ├── llama.cpp/
│   │   └── versions.json
│   ├── ninja/
│   │   └── versions.json
│   └── pytorch/
│       └── versions.json
├── bridges/
│   ├── nodejs/
│   │   ├── .npmrc
│   │   ├── package.json
│   │   ├── src/
│   │   │   ├── constants.ts
│   │   │   ├── main.ts
│   │   │   ├── sdk/
│   │   │   │   ├── aurora/
│   │   │   │   │   ├── button.ts
│   │   │   │   │   ├── card.ts
│   │   │   │   │   ├── checkbox.ts
│   │   │   │   │   ├── circular-progress.ts
│   │   │   │   │   ├── flexbox.ts
│   │   │   │   │   ├── form.ts
│   │   │   │   │   ├── icon-button.ts
│   │   │   │   │   ├── icon.ts
│   │   │   │   │   ├── image.ts
│   │   │   │   │   ├── index.ts
│   │   │   │   │   ├── input.ts
│   │   │   │   │   ├── link.ts
│   │   │   │   │   ├── list-header.ts
│   │   │   │   │   ├── list-item.ts
│   │   │   │   │   ├── list.ts
│   │   │   │   │   ├── loader.ts
│   │   │   │   │   ├── progress.ts
│   │   │   │   │   ├── radio-group.ts
│   │   │   │   │   ├── radio.ts
│   │   │   │   │   ├── range-slider.ts
│   │   │   │   │   ├── scroll-container.ts
│   │   │   │   │   ├── select-option.ts
│   │   │   │   │   ├── select.ts
│   │   │   │   │   ├── status.ts
│   │   │   │   │   ├── switch.ts
│   │   │   │   │   ├── tab-content.ts
│   │   │   │   │   ├── tab-group.ts
│   │   │   │   │   ├── tab-list.ts
│   │   │   │   │   ├── tab.ts
│   │   │   │   │   ├── text.ts
│   │   │   │   │   └── widget-wrapper.ts
│   │   │   │   ├── base-tool.ts
│   │   │   │   ├── leon.ts
│   │   │   │   ├── memory.ts
│   │   │   │   ├── network.ts
│   │   │   │   ├── packages/
│   │   │   │   │   └── lodash.ts
│   │   │   │   ├── params-helper.ts
│   │   │   │   ├── settings.ts
│   │   │   │   ├── tool-manager.ts
│   │   │   │   ├── tool-reporter.ts
│   │   │   │   ├── toolkit-config.ts
│   │   │   │   ├── tools/
│   │   │   │   │   ├── assemblyai_audio/
│   │   │   │   │   │   ├── assemblyai_audio-tool.ts
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   └── lib/
│   │   │   │   │   │       └── .gitkeep
│   │   │   │   │   ├── bash/
│   │   │   │   │   │   ├── bash-tool.ts
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   └── lib/
│   │   │   │   │   │       └── .gitkeep
│   │   │   │   │   ├── cerebras/
│   │   │   │   │   │   ├── cerebras-tool.ts
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   └── lib/
│   │   │   │   │   │       └── .gitkeep
│   │   │   │   │   ├── chatterbox_onnx/
│   │   │   │   │   │   ├── chatterbox_onnx-tool.ts
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   └── lib/
│   │   │   │   │   │       └── .gitkeep
│   │   │   │   │   ├── context/
│   │   │   │   │   │   ├── context-tool.ts
│   │   │   │   │   │   └── index.ts
│   │   │   │   │   ├── ecapa/
│   │   │   │   │   │   ├── ecapa-tool.ts
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   └── lib/
│   │   │   │   │   │       └── .gitkeep
│   │   │   │   │   ├── elevenlabs_audio/
│   │   │   │   │   │   ├── elevenlabs_audio-tool.ts
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   └── lib/
│   │   │   │   │   │       └── .gitkeep
│   │   │   │   │   ├── faster_whisper/
│   │   │   │   │   │   ├── faster_whisper-tool.ts
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   └── lib/
│   │   │   │   │   │       └── .gitkeep
│   │   │   │   │   ├── ffmpeg/
│   │   │   │   │   │   ├── ffmpeg-tool.ts
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   └── lib/
│   │   │   │   │   │       └── .gitkeep
│   │   │   │   │   ├── ffprobe/
│   │   │   │   │   │   ├── ffprobe-tool.ts
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   └── lib/
│   │   │   │   │   │       └── .gitkeep
│   │   │   │   │   ├── grok/
│   │   │   │   │   │   ├── grok-tool.ts
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   └── lib/
│   │   │   │   │   │       └── .gitkeep
│   │   │   │   │   ├── memory/
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   ├── memory-tool.ts
│   │   │   │   │   │   ├── qmd-embed-worker.mjs
│   │   │   │   │   │   ├── qmd-retrieval.ts
│   │   │   │   │   │   └── qmd-store.ts
│   │   │   │   │   ├── open-meteo/
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   ├── lib/
│   │   │   │   │   │   │   └── .gitkeep
│   │   │   │   │   │   └── open-meteo-tool.ts
│   │   │   │   │   ├── openai_audio/
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   ├── lib/
│   │   │   │   │   │   │   └── .gitkeep
│   │   │   │   │   │   └── openai_audio-tool.ts
│   │   │   │   │   ├── opencode/
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   ├── lib/
│   │   │   │   │   │   │   ├── .gitkeep
│   │   │   │   │   │   │   └── prompt.md
│   │   │   │   │   │   └── opencode-tool.ts
│   │   │   │   │   ├── openrouter/
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   ├── lib/
│   │   │   │   │   │   │   └── .gitkeep
│   │   │   │   │   │   └── openrouter-tool.ts
│   │   │   │   │   ├── qwen3_asr/
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   ├── lib/
│   │   │   │   │   │   │   └── .gitkeep
│   │   │   │   │   │   └── qwen3_asr-tool.ts
│   │   │   │   │   ├── qwen3_tts/
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   ├── lib/
│   │   │   │   │   │   │   └── .gitkeep
│   │   │   │   │   │   └── qwen3_tts-tool.ts
│   │   │   │   │   ├── transcription-schema.ts
│   │   │   │   │   ├── ultimate_vocal_remover_onnx/
│   │   │   │   │   │   ├── index.ts
│   │   │   │   │   │   ├── lib/
│   │   │   │   │   │   │   └── .gitkeep
│   │   │   │   │   │   └── ultimate_vocal_remover_onnx-tool.ts
│   │   │   │   │   └── ytdlp/
│   │   │   │   │       ├── index.ts
│   │   │   │   │       ├── lib/
│   │   │   │   │       │   └── .gitkeep
│   │   │   │   │       ├── yt-dlp.conf
│   │   │   │   │       └── ytdlp-tool.ts
│   │   │   │   ├── types.ts
│   │   │   │   ├── utils.ts
│   │   │   │   ├── widget-component.ts
│   │   │   │   └── widget.ts
│   │   │   ├── tool-runtime.ts
│   │   │   └── version.ts
│   │   └── tsconfig.json
│   ├── python/
│   │   ├── dist/
│   │   │   └── .gitkeep
│   │   └── src/
│   │       ├── Pipfile
│   │       ├── constants.py
│   │       ├── main.py
│   │       ├── sdk/
│   │       │   ├── aurora/
│   │       │   │   ├── button.py
│   │       │   │   ├── card.py
│   │       │   │   ├── checkbox.py
│   │       │   │   ├── circular_progress.py
│   │       │   │   ├── flexbox.py
│   │       │   │   ├── form.py
│   │       │   │   ├── icon.py
│   │       │   │   ├── icon_button.py
│   │       │   │   ├── image.py
│   │       │   │   ├── input.py
│   │       │   │   ├── link.py
│   │       │   │   ├── list.py
│   │       │   │   ├── list_header.py
│   │       │   │   ├── list_item.py
│   │       │   │   ├── loader.py
│   │       │   │   ├── progress.py
│   │       │   │   ├── radio.py
│   │       │   │   ├── radio_group.py
│   │       │   │   ├── range_slider.py
│   │       │   │   ├── scroll_container.py
│   │       │   │   ├── select.py
│   │       │   │   ├── select_option.py
│   │       │   │   ├── status.py
│   │       │   │   ├── switch.py
│   │       │   │   ├── tab.py
│   │       │   │   ├── tab_content.py
│   │       │   │   ├── tab_group.py
│   │       │   │   ├── tab_list.py
│   │       │   │   ├── text.py
│   │       │   │   └── widget_wrapper.py
│   │       │   ├── base_tool.py
│   │       │   ├── leon.py
│   │       │   ├── memory.py
│   │       │   ├── network.py
│   │       │   ├── params_helper.py
│   │       │   ├── settings.py
│   │       │   ├── tool_manager.py
│   │       │   ├── toolkit_config.py
│   │       │   ├── tools/
│   │       │   │   ├── assemblyai_audio/
│   │       │   │   │   ├── __init__.py
│   │       │   │   │   ├── assemblyai_audio_tool.py
│   │       │   │   │   └── lib/
│   │       │   │   │       └── .gitkeep
│   │       │   │   ├── bash/
│   │       │   │   │   ├── __init__.py
│   │       │   │   │   ├── bash_tool.py
│   │       │   │   │   └── lib/
│   │       │   │   │       └── .gitkeep
│   │       │   │   ├── cerebras/
│   │       │   │   │   ├── __init__.py
│   │       │   │   │   ├── cerebras_tool.py
│   │       │   │   │   └── lib/
│   │       │   │   │       └── .gitkeep
│   │       │   │   ├── chatterbox_onnx/
│   │       │   │   │   ├── __init__.py
│   │       │   │   │   ├── chatterbox_onnx_tool.py
│   │       │   │   │   └── lib/
│   │       │   │   │       └── .gitkeep
│   │       │   │   ├── ecapa/
│   │       │   │   │   ├── __init__.py
│   │       │   │   │   ├── ecapa_tool.py
│   │       │   │   │   └── lib/
│   │       │   │   │       └── .gitkeep
│   │       │   │   ├── elevenlabs_audio/
│   │       │   │   │   ├── __init__.py
│   │       │   │   │   ├── elevenlabs_audio_tool.py
│   │       │   │   │   └── lib/
│   │       │   │   │       └── .gitkeep
│   │       │   │   ├── faster_whisper/
│   │       │   │   │   ├── __init__.py
│   │       │   │   │   ├── faster_whisper_tool.py
│   │       │   │   │   └── lib/
│   │       │   │   │       └── .gitkeep
│   │       │   │   ├── ffmpeg/
│   │       │   │   │   ├── __init__.py
│   │       │   │   │   ├── ffmpeg_tool.py
│   │       │   │   │   └── lib/
│   │       │   │   │       └── .gitkeep
│   │       │   │   ├── ffprobe/
│   │       │   │   │   ├── __init__.py
│   │       │   │   │   ├── ffprobe_tool.py
│   │       │   │   │   └── lib/
│   │       │   │   │       └── .gitkeep
│   │       │   │   ├── grok/
│   │       │   │   │   ├── __init__.py
│   │       │   │   │   ├── grok_tool.py
│   │       │   │   │   └── lib/
│   │       │   │   │       └── .gitkeep
│   │       │   │   ├── open_meteo/
│   │       │   │   │   ├── __init__.py
│   │       │   │   │   ├── lib/
│   │       │   │   │   │   └── .gitkeep
│   │       │   │   │   └── open_meteo_tool.py
│   │       │   │   ├── openai_audio/
│   │       │   │   │   ├── __init__.py
│   │       │   │   │   ├── lib/
│   │       │   │   │   │   └── .gitkeep
│   │       │   │   │   └── openai_audio_tool.py
│   │       │   │   ├── opencode/
│   │       │   │   │   ├── __init__.py
│   │       │   │   │   ├── lib/
│   │       │   │   │   │   ├── .gitkeep
│   │       │   │   │   │   └── prompt.md
│   │       │   │   │   └── opencode_tool.py
│   │       │   │   ├── openrouter/
│   │       │   │   │   ├── __init__.py
│   │       │   │   │   ├── lib/
│   │       │   │   │   │   └── .gitkeep
│   │       │   │   │   └── openrouter_tool.py
│   │       │   │   ├── qwen3_asr/
│   │       │   │   │   ├── __init__.py
│   │       │   │   │   ├── lib/
│   │       │   │   │   │   └── .gitkeep
│   │       │   │   │   └── qwen3_asr_tool.py
│   │       │   │   ├── qwen3_tts/
│   │       │   │   │   ├── __init__.py
│   │       │   │   │   ├── lib/
│   │       │   │   │   │   └── .gitkeep
│   │       │   │   │   └── qwen3_tts_tool.py
│   │       │   │   ├── transcription_schema.py
│   │       │   │   ├── ultimate_vocal_remover_onnx/
│   │       │   │   │   ├── __init__.py
│   │       │   │   │   ├── lib/
│   │       │   │   │   │   └── .gitkeep
│   │       │   │   │   └── ultimate_vocal_remover_onnx_tool.py
│   │       │   │   └── ytdlp/
│   │       │   │       ├── __init__.py
│   │       │   │       ├── lib/
│   │       │   │       │   └── .gitkeep
│   │       │   │       ├── yt-dlp.conf
│   │       │   │       └── ytdlp_tool.py
│   │       │   ├── types.py
│   │       │   ├── utils.py
│   │       │   ├── widget.py
│   │       │   └── widget_component.py
│   │       ├── setup.py
│   │       └── version.py
│   └── toolkits/
│       ├── business_finance/
│       │   ├── settings/
│       │   │   └── .gitkeep
│       │   └── toolkit.json
│       ├── calendar_scheduling/
│       │   ├── settings/
│       │   │   └── .gitkeep
│       │   └── toolkit.json
│       ├── coding_development/
│       │   ├── settings/
│       │   │   └── .gitkeep
│       │   ├── toolkit.json
│       │   └── tools/
│       │       └── opencode.tool.json
│       ├── communication/
│       │   ├── settings/
│       │   │   └── .gitkeep
│       │   ├── toolkit.json
│       │   └── tools/
│       │       ├── cerebras.tool.json
│       │       └── openrouter.tool.json
│       ├── dialog/
│       │   ├── settings/
│       │   │   └── .gitkeep
│       │   └── toolkit.json
│       ├── file_system/
│       │   ├── settings/
│       │   │   └── .gitkeep
│       │   └── toolkit.json
│       ├── food_drink/
│       │   ├── settings/
│       │   │   └── .gitkeep
│       │   └── toolkit.json
│       ├── games/
│       │   ├── settings/
│       │   │   └── .gitkeep
│       │   └── toolkit.json
│       ├── health_fitness/
│       │   ├── settings/
│       │   │   └── .gitkeep
│       │   └── toolkit.json
│       ├── media_generation/
│       │   ├── settings/
│       │   │   └── .gitkeep
│       │   └── toolkit.json
│       ├── movies_tv/
│       │   ├── settings/
│       │   │   └── .gitkeep
│       │   └── toolkit.json
│       ├── music_audio/
│       │   ├── settings/
│       │   │   └── .gitkeep
│       │   ├── toolkit.json
│       │   └── tools/
│       │       ├── assemblyai_audio.tool.json
│       │       ├── chatterbox_onnx.tool.json
│       │       ├── ecapa.tool.json
│       │       ├── elevenlabs_audio.tool.json
│       │       ├── faster_whisper.tool.json
│       │       ├── openai_audio.tool.json
│       │       ├── qwen3_asr.tool.json
│       │       ├── qwen3_tts.tool.json
│       │       └── ultimate_vocal_remover_onnx.tool.json
│       ├── news/
│       │   ├── settings/
│       │   │   └── .gitkeep
│       │   └── toolkit.json
│       ├── operating_system_control/
│       │   ├── settings/
│       │   │   └── .gitkeep
│       │   ├── toolkit.json
│       │   └── tools/
│       │       └── bash.tool.json
│       ├── productivity_collaboration/
│       │   ├── settings/
│       │   │   └── .gitkeep
│       │   └── toolkit.json
│       ├── search_web/
│       │   ├── settings/
│       │   │   └── .gitkeep
│       │   ├── toolkit.json
│       │   └── tools/
│       │       └── grok.tool.json
│       ├── shopping/
│       │   ├── settings/
│       │   │   └── .gitkeep
│       │   └── toolkit.json
│       ├── smart_home/
│       │   ├── settings/
│       │   │   └── .gitkeep
│       │   └── toolkit.json
│       ├── social_media/
│       │   ├── settings/
│       │   │   └── .gitkeep
│       │   └── toolkit.json
│       ├── sport/
│       │   ├── settings/
│       │   │   └── .gitkeep
│       │   └── toolkit.json
│       ├── structured_knowledge/
│       │   ├── settings/
│       │   │   └── .gitkeep
│       │   ├── toolkit.json
│       │   └── tools/
│       │       ├── context.tool.json
│       │       └── memory.tool.json
│       ├── system_utilities/
│       │   ├── settings/
│       │   │   └── .gitkeep
│       │   └── toolkit.json
│       ├── travel_transportation/
│       │   ├── settings/
│       │   │   └── .gitkeep
│       │   └── toolkit.json
│       ├── video_streaming/
│       │   ├── settings/
│       │   │   └── .gitkeep
│       │   ├── toolkit.json
│       │   └── tools/
│       │       ├── ffmpeg.tool.json
│       │       ├── ffprobe.tool.json
│       │       └── ytdlp.tool.json
│       └── weather/
│           ├── settings/
│           │   └── .gitkeep
│           ├── toolkit.json
│           └── tools/
│               └── openmeteo.tool.json
├── core/
│   ├── config/
│   │   ├── synchronizer/
│   │   │   └── google-drive.sample.json
│   │   └── voice/
│   │       ├── amazon.sample.json
│   │       ├── google-cloud.sample.json
│   │       ├── watson-stt.sample.json
│   │       └── watson-tts.sample.json
│   ├── context/
│   │   ├── .gitkeep
│   │   ├── ARCHITECTURE.md
│   │   └── LEON.md
│   ├── data/
│   │   ├── en/
│   │   │   ├── answers.json
│   │   │   ├── global-entities/
│   │   │   │   ├── color.json
│   │   │   │   ├── handsign.json
│   │   │   │   ├── language.json
│   │   │   │   └── level.json
│   │   │   └── global-resolvers/
│   │   │       └── affirmation_denial.json
│   │   ├── fr/
│   │   │   ├── answers.json
│   │   │   ├── global-entities/
│   │   │   │   ├── color.json
│   │   │   │   └── level.json
│   │   │   └── global-resolvers/
│   │   │       └── affirmation_denial.json
│   │   └── models/
│   │       ├── .gitkeep
│   │       ├── audio/
│   │       │   ├── asr/
│   │       │   │   └── .gitkeep
│   │       │   ├── tts/
│   │       │   │   ├── .gitkeep
│   │       │   │   ├── bert-base-french-europeana-cased/
│   │       │   │   │   └── .gitkeep
│   │       │   │   ├── bert-base-uncased/
│   │       │   │   │   └── .gitkeep
│   │       │   │   └── config.json
│   │       │   └── wake_word/
│   │       │       ├── .gitkeep
│   │       │       ├── Hey_Leon.onnx
│   │       │       ├── embedding.onnx
│   │       │       └── melspectrogram.onnx
│   │       └── llm/
│   │           └── .gitkeep
│   ├── langs.json
│   ├── memory/
│   │   └── .gitkeep
│   └── skills-endpoints.json
├── eslint.config.mjs
├── hotword/
│   ├── README.md
│   ├── index.js
│   ├── models/
│   │   ├── leon-en.pmdl
│   │   └── leon-fr.pmdl
│   └── package.json
├── jsconfig.json
├── logs/
│   └── .gitkeep
├── nodemon.json
├── nodemon.nolint.json
├── package.json
├── scripts/
│   ├── app/
│   │   ├── build-app.js
│   │   └── run-build-app.js
│   ├── assets/
│   │   ├── CHANGELOG-TEMPLATE.md
│   │   ├── leon.lv
│   │   ├── nodejs-bridge-intent-object.json
│   │   └── python-bridge-intent-object.json
│   ├── build-binaries.js
│   ├── check-os.js
│   ├── check.js
│   ├── clean-test-dbs.js
│   ├── commit-msg.js
│   ├── generate/
│   │   ├── generate-http-api-key.js
│   │   ├── generate-json-schemas.js
│   │   ├── generate-prompt.js
│   │   ├── generate-skills-endpoints.js
│   │   ├── run-generate-http-api-key.js
│   │   ├── run-generate-json-schemas.js
│   │   ├── run-generate-prompt.js
│   │   └── run-generate-skills-endpoints.js
│   ├── lint.js
│   ├── out/
│   │   └── .gitkeep
│   ├── prompt-templates/
│   │   ├── create-skill-template.md
│   │   └── create-tool-template.md
│   ├── release/
│   │   ├── generate-changelog.js
│   │   ├── pre-release-binaries.js
│   │   ├── prepare-release.js
│   │   └── update-version.js
│   ├── run-agentic-loop-vitest.ts
│   ├── run-clean-test-dbs.js
│   ├── setup/
│   │   ├── create-instance-id.js
│   │   ├── preinstall.js
│   │   ├── set-ffprobe-permissions.js
│   │   ├── setup-binaries.js
│   │   ├── setup-cmake.js
│   │   ├── setup-core.js
│   │   ├── setup-dotenv.js
│   │   ├── setup-llama-cpp.js
│   │   ├── setup-local-llm.js
│   │   ├── setup-ninja.js
│   │   ├── setup-nvidia-libs.js
│   │   ├── setup-python-dev-env.js
│   │   ├── setup-pytorch.js
│   │   ├── setup-qmd-llm.js
│   │   ├── setup-skills/
│   │   │   ├── install-nodejs-skills-packages.js
│   │   │   ├── setup-skills-settings.js
│   │   │   └── setup-skills.js
│   │   ├── setup-tcp-server-models.js
│   │   └── setup.js
│   ├── setup-offline/
│   │   ├── run-setup-hotword.js
│   │   ├── run-setup-stt.js
│   │   ├── run-setup-tts.js
│   │   ├── setup-hotword.js
│   │   ├── setup-offline.js
│   │   ├── setup-stt.js
│   │   └── setup-tts.js
│   ├── skill-package.js
│   ├── test-module.js
│   └── train/
│       ├── run-train.js
│       ├── train-llm-actions-classifier.js
│       ├── train-main-model/
│       │   ├── train-global-entities.js
│       │   └── train-skills-actions.js
│       ├── train-resolvers-model/
│       │   ├── train-global-resolvers.js
│       │   └── train-skills-resolvers.js
│       ├── train-skill-router-duty.js
│       └── train.js
├── server/
│   └── src/
│       ├── ajv.ts
│       ├── constants.ts
│       ├── conversation-logger.ts
│       ├── core/
│       │   ├── asr/
│       │   │   ├── asr.ts
│       │   │   └── types.ts
│       │   ├── brain/
│       │   │   ├── answer-queue.ts
│       │   │   ├── brain.ts
│       │   │   ├── dialog-action-skill-handler.ts
│       │   │   ├── logic-action-skill-handler.ts
│       │   │   └── types.ts
│       │   ├── context-manager/
│       │   │   ├── context-file-factory.ts
│       │   │   ├── context-file.ts
│       │   │   ├── context-files/
│       │   │   │   ├── activity-context-file.ts
│       │   │   │   ├── architecture-context-file.ts
│       │   │   │   ├── browser-history-context-file.ts
│       │   │   │   ├── gpu-compute-context-file.ts
│       │   │   │   ├── habits-context-file.ts
│       │   │   │   ├── home-context-file.ts
│       │   │   │   ├── host-system-context-file.ts
│       │   │   │   ├── leon-context-file.ts
│       │   │   │   ├── leon-runtime-context-file.ts
│       │   │   │   ├── local-inventory-context-file.ts
│       │   │   │   ├── media-profile-context-file.ts
│       │   │   │   ├── network-ecosystem-context-file.ts
│       │   │   │   ├── owner-context-file.ts
│       │   │   │   ├── storage-context-file.ts
│       │   │   │   ├── system-resources-context-file.ts
│       │   │   │   └── workspace-intelligence-context-file.ts
│       │   │   ├── context-manager.ts
│       │   │   ├── context-probe-helper.ts
│       │   │   ├── context-refresh-worker.ts
│       │   │   ├── context-state-store.ts
│       │   │   ├── index.ts
│       │   │   ├── owner-profile-sync.ts
│       │   │   └── owner-profile.ts
│       │   ├── http-server/
│       │   │   ├── api/
│       │   │   │   ├── fetch-widget/
│       │   │   │   │   ├── get.ts
│       │   │   │   │   └── index.ts
│       │   │   │   ├── info/
│       │   │   │   │   ├── get.ts
│       │   │   │   │   └── index.ts
│       │   │   │   ├── llm-inference/
│       │   │   │   │   ├── index.ts
│       │   │   │   │   └── post.ts
│       │   │   │   ├── open-path/
│       │   │   │   │   ├── index.ts
│       │   │   │   │   └── post.ts
│       │   │   │   ├── run-action/
│       │   │   │   │   ├── index.ts
│       │   │   │   │   └── post.ts
│       │   │   │   └── utterance/
│       │   │   │       ├── index.ts
│       │   │   │       └── post.ts
│       │   │   ├── http-server.ts
│       │   │   ├── old-server.js
│       │   │   └── plugins/
│       │   │       ├── cors.ts
│       │   │       ├── key.ts
│       │   │       └── other.ts
│       │   ├── index.ts
│       │   ├── llm-manager/
│       │   │   ├── llm-duties/
│       │   │   │   ├── action-calling-llm-duty.ts
│       │   │   │   ├── action-recognition-llm-duty.ts
│       │   │   │   ├── conversation-llm-duty.ts
│       │   │   │   ├── custom-llm-duty.ts
│       │   │   │   ├── custom-ner-llm-duty.ts
│       │   │   │   ├── paraphrase-llm-duty.ts
│       │   │   │   ├── react-llm-duty/
│       │   │   │   │   ├── catalog.ts
│       │   │   │   │   ├── constants.ts
│       │   │   │   │   ├── execution.ts
│       │   │   │   │   ├── final-answer.ts
│       │   │   │   │   ├── history-compaction.ts
│       │   │   │   │   ├── metrics.ts
│       │   │   │   │   ├── phase-helpers.ts
│       │   │   │   │   ├── phase-policy.ts
│       │   │   │   │   ├── phases.ts
│       │   │   │   │   ├── plan-contract.ts
│       │   │   │   │   ├── plan-widget.ts
│       │   │   │   │   ├── planning.ts
│       │   │   │   │   ├── recovery-planning.ts
│       │   │   │   │   ├── types.ts
│       │   │   │   │   └── utils.ts
│       │   │   │   ├── react-llm-duty.ts
│       │   │   │   ├── skill-router-llm-duty.ts
│       │   │   │   └── slot-filling-llm-duty.ts
│       │   │   ├── llm-duty.ts
│       │   │   ├── llm-manager.ts
│       │   │   ├── llm-provider.ts
│       │   │   ├── llm-providers/
│       │   │   │   ├── ai-sdk-remote-llm-provider.ts
│       │   │   │   ├── anthropic-llm-provider.ts
│       │   │   │   ├── cerebras-llm-provider.ts
│       │   │   │   ├── groq-llm-provider.ts
│       │   │   │   ├── huggingface-llm-provider.ts
│       │   │   │   ├── llamacpp-llm-provider.ts
│       │   │   │   ├── local-llm-provider.ts
│       │   │   │   ├── moonshotai-llm-provider.ts
│       │   │   │   ├── openai-llm-provider.ts
│       │   │   │   ├── openrouter-llm-provider.ts
│       │   │   │   ├── sglang-llm-provider.ts
│       │   │   │   └── z-ai-llm-provider.ts
│       │   │   ├── persona.ts
│       │   │   ├── streaming-chunk.ts
│       │   │   ├── types.ts
│       │   │   └── warm-up-llm-duties.ts
│       │   ├── memory-manager/
│       │   │   ├── index.ts
│       │   │   ├── memory-manager.ts
│       │   │   ├── memory-repository.ts
│       │   │   ├── qmd-backend.ts
│       │   │   ├── sql/
│       │   │   │   └── schema.sql
│       │   │   ├── summarizer.ts
│       │   │   └── types.ts
│       │   ├── nlp/
│       │   │   ├── conversation.ts
│       │   │   ├── nlu/
│       │   │   │   ├── action-loop.ts
│       │   │   │   ├── model-loader.ts
│       │   │   │   ├── ner.ts
│       │   │   │   ├── nlu-process-result-updater.ts
│       │   │   │   ├── nlu.ts
│       │   │   │   └── slot-filling.ts
│       │   │   └── types.ts
│       │   ├── pulse-manager.ts
│       │   ├── self-model-manager.ts
│       │   ├── socket-server.ts
│       │   ├── stt/
│       │   │   ├── parsers/
│       │   │   │   ├── coqui-stt-parser.ts
│       │   │   │   ├── google-cloud-stt-parser.ts
│       │   │   │   ├── local-parser.ts
│       │   │   │   └── watson-stt-parser.ts
│       │   │   ├── stt-parser-base.ts
│       │   │   ├── stt.ts
│       │   │   └── types.ts
│       │   ├── tcp-client.ts
│       │   ├── tool-executor.ts
│       │   ├── toolkit-registry.ts
│       │   └── tts/
│       │       ├── synthesizers/
│       │       │   ├── amazon-polly-synthesizer.ts
│       │       │   ├── flite-synthesizer.ts
│       │       │   ├── google-cloud-tts-synthesizer.ts
│       │       │   ├── local-synthesizer.ts
│       │       │   └── watson-tts-synthesizer.ts
│       │       ├── tts-synthesizer-base.ts
│       │       ├── tts.ts
│       │       └── types.ts
│       ├── declarations.d.ts
│       ├── global.d.ts
│       ├── helpers/
│       │   ├── date-helper.ts
│       │   ├── file-helper.ts
│       │   ├── lang-helper.ts
│       │   ├── loader-helper.ts
│       │   ├── log-helper.ts
│       │   ├── network-helper.ts
│       │   ├── skill-domain-helper.ts
│       │   ├── string-helper.ts
│       │   └── system-helper.ts
│       ├── index.ts
│       ├── intent-object.sample.json
│       ├── pre-check.ts
│       ├── schemas/
│       │   ├── global-data-schemas.ts
│       │   ├── skill-schemas.ts
│       │   ├── tool-schemas.ts
│       │   ├── toolkit-schemas.ts
│       │   └── voice-config-schemas.ts
│       ├── telemetry.ts
│       ├── tool-call-logger.ts
│       ├── types.ts
│       ├── updater.ts
│       └── utilities.ts
├── skills/
│   ├── bash_skill/
│   │   ├── README.md
│   │   ├── locales/
│   │   │   └── en.json
│   │   ├── skill.json
│   │   └── src/
│   │       ├── actions/
│   │       │   └── execute.py
│   │       └── settings.sample.json
│   ├── business_finance/
│   │   └── domain.json
│   ├── color_skill/
│   │   ├── README.md
│   │   ├── locales/
│   │   │   └── en.json
│   │   ├── memory/
│   │   │   └── .gitkeep
│   │   ├── skill.json
│   │   ├── src/
│   │   │   ├── actions/
│   │   │   │   └── tell_hexadecimal_color.py
│   │   │   ├── lib/
│   │   │   │   ├── .gitkeep
│   │   │   │   └── hexa_colors.py
│   │   │   ├── settings.sample.json
│   │   │   └── widgets/
│   │   │       └── .gitkeep
│   │   └── test/
│   │       └── .gitkeep
│   ├── food_drink/
│   │   └── domain.json
│   ├── games/
│   │   ├── akinator/
│   │   │   ├── README.md
│   │   │   ├── config/
│   │   │   │   └── en.json
│   │   │   ├── memory/
│   │   │   │   └── .gitkeep
│   │   │   ├── skill.json
│   │   │   ├── src/
│   │   │   │   ├── actions/
│   │   │   │   │   ├── guess.py
│   │   │   │   │   ├── retry.py
│   │   │   │   │   └── setup.py
│   │   │   │   ├── lib/
│   │   │   │   │   ├── .gitkeep
│   │   │   │   │   ├── __init__.py
│   │   │   │   │   ├── main.py
│   │   │   │   │   ├── memory.py
│   │   │   │   │   └── question_widget.py
│   │   │   │   ├── settings.sample.json
│   │   │   │   └── widgets/
│   │   │   │       └── .gitkeep
│   │   │   └── test/
│   │   │       └── .gitkeep
│   │   └── domain.json
│   ├── good_bye_skill/
│   │   ├── README.md
│   │   ├── config/
│   │   │   ├── en.json
│   │   │   └── fr.json
│   │   ├── locales/
│   │   │   └── en.json
│   │   ├── memory/
│   │   │   └── .gitkeep
│   │   ├── skill.json
│   │   └── test/
│   │       └── .gitkeep
│   ├── greeting_skill/
│   │   ├── README.md
│   │   ├── locales/
│   │   │   ├── en.json
│   │   │   └── fr.json
│   │   ├── memory/
│   │   │   └── .gitkeep
│   │   ├── skill.json
│   │   ├── src/
│   │   │   ├── actions/
│   │   │   │   └── greet.py
│   │   │   ├── lib/
│   │   │   │   └── .gitkeep
│   │   │   ├── settings.sample.json
│   │   │   └── widgets/
│   │   │       └── .gitkeep
│   │   └── test/
│   │       └── .gitkeep
│   ├── guess_the_number_skill/
│   │   ├── README.md
│   │   ├── locales/
│   │   │   └── en.json
│   │   ├── memory/
│   │   │   └── .gitkeep
│   │   ├── skill.json
│   │   ├── src/
│   │   │   ├── actions/
│   │   │   │   ├── guess.py
│   │   │   │   ├── replay.py
│   │   │   │   └── set_up.py
│   │   │   ├── lib/
│   │   │   │   ├── .gitkeep
│   │   │   │   └── memory.py
│   │   │   ├── settings.sample.json
│   │   │   └── widgets/
│   │   │       └── .gitkeep
│   │   └── test/
│   │       └── .gitkeep
│   ├── health_fitness/
│   │   └── domain.json
│   ├── knowledge_education/
│   │   └── domain.json
│   ├── leon/
│   │   ├── age/
│   │   │   ├── README.md
│   │   │   ├── config/
│   │   │   │   └── en.json
│   │   │   ├── memory/
│   │   │   │   └── .gitkeep
│   │   │   ├── skill.json
│   │   │   ├── src/
│   │   │   │   ├── actions/
│   │   │   │   │   └── run.ts
│   │   │   │   ├── lib/
│   │   │   │   │   ├── .gitkeep
│   │   │   │   │   └── getTimeDifferenceBetweenDates.ts
│   │   │   │   ├── settings.sample.json
│   │   │   │   └── widgets/
│   │   │   │       └── .gitkeep
│   │   │   └── test/
│   │   │       └── .gitkeep
│   │   ├── domain.json
│   │   ├── good_bye/
│   │   │   ├── README.md
│   │   │   ├── config/
│   │   │   │   ├── en.json
│   │   │   │   └── fr.json
│   │   │   ├── memory/
│   │   │   │   └── .gitkeep
│   │   │   ├── skill.json
│   │   │   └── test/
│   │   │       └── .gitkeep
│   │   ├── help/
│   │   │   ├── README.md
│   │   │   ├── config/
│   │   │   │   └── en.json
│   │   │   ├── memory/
│   │   │   │   └── .gitkeep
│   │   │   ├── skill.json
│   │   │   ├── src/
│   │   │   │   ├── actions/
│   │   │   │   │   └── help.ts
│   │   │   │   ├── lib/
│   │   │   │   │   └── .gitkeep
│   │   │   │   ├── settings.sample.json
│   │   │   │   └── widgets/
│   │   │   │       └── .gitkeep
│   │   │   └── test/
│   │   │       └── .gitkeep
│   │   ├── introduction/
│   │   │   ├── README.md
│   │   │   ├── config/
│   │   │   │   ├── en.json
│   │   │   │   └── fr.json
│   │   │   ├── memory/
│   │   │   │   └── .gitkeep
│   │   │   ├── skill.json
│   │   │   ├── src/
│   │   │   │   ├── actions/
│   │   │   │   │   ├── introduce_leon.py
│   │   │   │   │   └── remember.py
│   │   │   │   ├── lib/
│   │   │   │   │   ├── .gitkeep
│   │   │   │   │   └── memory.py
│   │   │   │   ├── settings.sample.json
│   │   │   │   └── widgets/
│   │   │   │       └── .gitkeep
│   │   │   └── test/
│   │   │       └── .gitkeep
│   │   ├── joke/
│   │   │   ├── README.md
│   │   │   ├── config/
│   │   │   │   ├── en.json
│   │   │   │   └── fr.json
│   │   │   ├── memory/
│   │   │   │   └── .gitkeep
│   │   │   ├── skill.json
│   │   │   └── test/
│   │   │       └── .gitkeep
│   │   ├── meaning_of_life/
│   │   │   ├── README.md
│   │   │   ├── config/
│   │   │   │   ├── en.json
│   │   │   │   └── fr.json
│   │   │   ├── memory/
│   │   │   │   └── .gitkeep
│   │   │   ├── skill.json
│   │   │   └── test/
│   │   │       └── .gitkeep
│   │   ├── random_number/
│   │   │   ├── README.md
│   │   │   ├── config/
│   │   │   │   ├── en.json
│   │   │   │   └── fr.json
│   │   │   ├── memory/
│   │   │   │   └── .gitkeep
│   │   │   ├── skill.json
│   │   │   ├── src/
│   │   │   │   ├── actions/
│   │   │   │   │   └── run.py
│   │   │   │   ├── lib/
│   │   │   │   │   └── .gitkeep
│   │   │   │   ├── settings.sample.json
│   │   │   │   └── widgets/
│   │   │   │       ├── .gitkeep
│   │   │   │       └── number_widget.py
│   │   │   └── test/
│   │   │       └── .gitkeep
│   │   └── thanks/
│   │       ├── README.md
│   │       ├── config/
│   │       │   ├── en.json
│   │       │   └── fr.json
│   │       ├── memory/
│   │       │   └── .gitkeep
│   │       ├── skill.json
│   │       └── test/
│   │           └── .gitkeep
│   ├── mbti_skill/
│   │   ├── README.md
│   │   ├── locales/
│   │   │   └── en.json
│   │   ├── memory/
│   │   │   └── .gitkeep
│   │   ├── skill.json
│   │   ├── src/
│   │   │   ├── actions/
│   │   │   │   ├── quiz.py
│   │   │   │   └── set_up.py
│   │   │   ├── lib/
│   │   │   │   ├── .gitkeep
│   │   │   │   └── memory.py
│   │   │   ├── settings.sample.json
│   │   │   └── widgets/
│   │   │       └── .gitkeep
│   │   └── test/
│   │       └── .gitkeep
│   ├── movies_tv/
│   │   └── domain.json
│   ├── music_audio/
│   │   └── domain.json
│   ├── music_audio_toolkit_skill/
│   │   ├── README.md
│   │   ├── locales/
│   │   │   └── en.json
│   │   ├── skill.json
│   │   └── src/
│   │       ├── actions/
│   │       │   ├── dub_audio.ts
│   │       │   ├── split_instrumental_vocal.ts
│   │       │   └── transcribe_audio.ts
│   │       └── settings.sample.json
│   ├── news/
│   │   ├── domain.json
│   │   ├── github_trends/
│   │   │   ├── README.md
│   │   │   ├── config/
│   │   │   │   ├── en.json
│   │   │   │   └── fr.json
│   │   │   ├── memory/
│   │   │   │   └── .gitkeep
│   │   │   ├── skill.json
│   │   │   ├── src/
│   │   │   │   ├── actions/
│   │   │   │   │   └── run.py
│   │   │   │   ├── lib/
│   │   │   │   │   ├── .gitkeep
│   │   │   │   │   └── github_lang.py
│   │   │   │   ├── settings.sample.json
│   │   │   │   └── widgets/
│   │   │   │       └── .gitkeep
│   │   │   └── test/
│   │   │       └── .gitkeep
│   │   └── product_hunt_trends/
│   │       ├── README.md
│   │       ├── config/
│   │       │   ├── en.json
│   │       │   └── fr.json
│   │       ├── memory/
│   │       │   └── .gitkeep
│   │       ├── skill.json
│   │       ├── src/
│   │       │   ├── actions/
│   │       │   │   └── run.py
│   │       │   ├── lib/
│   │       │   │   └── .gitkeep
│   │       │   ├── settings.sample.json
│   │       │   └── widgets/
│   │       │       └── .gitkeep
│   │       └── test/
│   │           └── .gitkeep
│   ├── partner_assistant_skill/
│   │   ├── README.md
│   │   ├── config/
│   │   │   ├── en.json
│   │   │   └── fr.json
│   │   ├── locales/
│   │   │   └── en.json
│   │   ├── memory/
│   │   │   └── .gitkeep
│   │   ├── skill.json
│   │   ├── src/
│   │   │   ├── actions/
│   │   │   │   └── tell_about_assistant.py
│   │   │   ├── lib/
│   │   │   │   └── .gitkeep
│   │   │   ├── settings.sample.json
│   │   │   └── widgets/
│   │   │       └── .gitkeep
│   │   └── test/
│   │       └── .gitkeep
│   ├── podcast_generator_skill/
│   │   ├── locales/
│   │   │   └── en.json
│   │   ├── skill.json
│   │   └── src/
│   │       ├── actions/
│   │       │   └── generate.ts
│   │       └── settings.sample.json
│   ├── productivity/
│   │   └── domain.json
│   ├── rochambeau_skill/
│   │   ├── README.md
│   │   ├── locales/
│   │   │   └── en.json
│   │   ├── memory/
│   │   │   └── .gitkeep
│   │   ├── skill.json
│   │   ├── src/
│   │   │   ├── actions/
│   │   │   │   ├── play.py
│   │   │   │   └── rematch.py
│   │   │   ├── lib/
│   │   │   │   └── .gitkeep
│   │   │   ├── settings.sample.json
│   │   │   └── widgets/
│   │   │       └── .gitkeep
│   │   └── test/
│   │       └── .gitkeep
│   ├── search_web_toolkit_skill/
│   │   ├── locales/
│   │   │   └── en.json
│   │   ├── skill.json
│   │   └── src/
│   │       ├── actions/
│   │       │   └── search.ts
│   │       └── settings.sample.json
│   ├── shopping/
│   │   └── domain.json
│   ├── skill_writer_skill/
│   │   ├── locales/
│   │   │   └── en.json
│   │   ├── skill.json
│   │   └── src/
│   │       ├── actions/
│   │       │   ├── create_skill.ts
│   │       │   └── modify_skill.ts
│   │       ├── lib/
│   │       │   ├── skill-plan-llm.ts
│   │       │   ├── skill-plan.ts
│   │       │   └── skill-prompt.ts
│   │       └── settings.sample.json
│   ├── smart_home/
│   │   └── domain.json
│   ├── social_communication/
│   │   ├── conversation/
│   │   │   ├── README.md
│   │   │   ├── config/
│   │   │   │   └── en.json
│   │   │   ├── memory/
│   │   │   │   └── .gitkeep
│   │   │   ├── skill.json
│   │   │   ├── src/
│   │   │   │   ├── actions/
│   │   │   │   │   ├── chit_chat.ts
│   │   │   │   │   └── converse.ts
│   │   │   │   ├── lib/
│   │   │   │   │   └── .gitkeep
│   │   │   │   ├── settings.sample.json
│   │   │   │   └── widgets/
│   │   │   │       └── .gitkeep
│   │   │   └── test/
│   │   │       └── .gitkeep
│   │   └── domain.json
│   ├── sport/
│   │   └── domain.json
│   ├── timer_skill/
│   │   ├── README.md
│   │   ├── locales/
│   │   │   └── en.json
│   │   ├── memory/
│   │   │   └── .gitkeep
│   │   ├── skill.json
│   │   ├── src/
│   │   │   ├── actions/
│   │   │   │   ├── cancel_timer.ts
│   │   │   │   ├── check_timer.ts
│   │   │   │   └── set_timer.ts
│   │   │   ├── lib/
│   │   │   │   ├── .gitkeep
│   │   │   │   └── memory.ts
│   │   │   ├── settings.sample.json
│   │   │   └── widgets/
│   │   │       ├── .gitkeep
│   │   │       ├── components/
│   │   │       │   └── timer.ts
│   │   │       └── timer-widget.ts
│   │   └── test/
│   │       └── .gitkeep
│   ├── todo_list_skill/
│   │   ├── README.md
│   │   ├── config/
│   │   │   ├── en.json
│   │   │   └── fr.json
│   │   ├── locales/
│   │   │   └── en.json
│   │   ├── memory/
│   │   │   └── .gitkeep
│   │   ├── skill.json
│   │   ├── src/
│   │   │   ├── actions/
│   │   │   │   ├── add_todos.py
│   │   │   │   ├── complete_items.py
│   │   │   │   ├── create_list.py
│   │   │   │   ├── delete_list.py
│   │   │   │   ├── get_all_lists.py
│   │   │   │   ├── get_list_items.py
│   │   │   │   ├── rename_list.py
│   │   │   │   └── uncomplete_items.py
│   │   │   ├── lib/
│   │   │   │   ├── .gitkeep
│   │   │   │   └── memory.py
│   │   │   ├── settings.sample.json
│   │   │   └── widgets/
│   │   │       ├── .gitkeep
│   │   │       ├── list_of_lists_widget.py
│   │   │       └── todos_list_widget.py
│   │   └── test/
│   │       └── .gitkeep
│   ├── translator_poc_skill/
│   │   ├── README.md
│   │   ├── config/
│   │   │   └── en.json
│   │   ├── locales/
│   │   │   └── en.json
│   │   ├── memory/
│   │   │   └── .gitkeep
│   │   ├── skill.json
│   │   ├── src/
│   │   │   ├── actions/
│   │   │   │   └── translate.ts
│   │   │   ├── lib/
│   │   │   │   └── .gitkeep
│   │   │   ├── settings.sample.json
│   │   │   └── widgets/
│   │   │       └── .gitkeep
│   │   └── test/
│   │       └── .gitkeep
│   ├── travel_transportation/
│   │   └── domain.json
│   ├── tsconfig.json
│   ├── unknown/
│   │   ├── domain.json
│   │   └── widget-playground/
│   │       ├── README.md
│   │       ├── config/
│   │       │   └── en.json
│   │       ├── memory/
│   │       │   └── .gitkeep
│   │       ├── skill.json
│   │       ├── src/
│   │       │   ├── actions/
│   │       │   │   └── run.ts
│   │       │   ├── lib/
│   │       │   │   └── .gitkeep
│   │       │   ├── settings.sample.json
│   │       │   └── widgets/
│   │       │       ├── .gitkeep
│   │       │       └── playground-test.ts
│   │       └── test/
│   │           └── .gitkeep
│   ├── utilities/
│   │   ├── date_time/
│   │   │   ├── README.md
│   │   │   ├── config/
│   │   │   │   └── en.json
│   │   │   ├── memory/
│   │   │   │   └── .gitkeep
│   │   │   ├── skill.json
│   │   │   ├── src/
│   │   │   │   ├── actions/
│   │   │   │   │   ├── current_date.ts
│   │   │   │   │   ├── current_date_time.ts
│   │   │   │   │   ├── current_date_time_with_time_zone.ts
│   │   │   │   │   ├── current_time.ts
│   │   │   │   │   ├── current_week_number.ts
│   │   │   │   │   └── days_countdown.ts
│   │   │   │   ├── lib/
│   │   │   │   │   ├── .gitkeep
│   │   │   │   │   ├── constants.ts
│   │   │   │   │   └── zeroPad.ts
│   │   │   │   ├── package.json
│   │   │   │   ├── settings.sample.json
│   │   │   │   └── widgets/
│   │   │   │       └── .gitkeep
│   │   │   └── test/
│   │   │       └── .gitkeep
│   │   ├── domain.json
│   │   ├── have_i_been_pwned/
│   │   │   ├── README.md
│   │   │   ├── config/
│   │   │   │   ├── en.json
│   │   │   │   └── fr.json
│   │   │   ├── memory/
│   │   │   │   └── .gitkeep
│   │   │   ├── skill.json
│   │   │   ├── src/
│   │   │   │   ├── actions/
│   │   │   │   │   └── run.py
│   │   │   │   ├── lib/
│   │   │   │   │   └── .gitkeep
│   │   │   │   ├── settings.sample.json
│   │   │   │   └── widgets/
│   │   │   │       └── .gitkeep
│   │   │   └── test/
│   │   │       └── .gitkeep
│   │   ├── is_it_down/
│   │   │   ├── README.md
│   │   │   ├── config/
│   │   │   │   ├── en.json
│   │   │   │   └── fr.json
│   │   │   ├── memory/
│   │   │   │   └── .gitkeep
│   │   │   ├── skill.json
│   │   │   ├── src/
│   │   │   │   ├── actions/
│   │   │   │   │   └── run.py
│   │   │   │   ├── lib/
│   │   │   │   │   └── .gitkeep
│   │   │   │   ├── settings.sample.json
│   │   │   │   └── widgets/
│   │   │   │       └── .gitkeep
│   │   │   └── test/
│   │   │       └── .gitkeep
│   │   ├── speed_test/
│   │   │   ├── README.md
│   │   │   ├── config/
│   │   │   │   ├── en.json
│   │   │   │   └── fr.json
│   │   │   ├── memory/
│   │   │   │   └── .gitkeep
│   │   │   ├── skill.json
│   │   │   ├── src/
│   │   │   │   ├── actions/
│   │   │   │   │   └── run.py
│   │   │   │   ├── lib/
│   │   │   │   │   ├── .gitkeep
│   │   │   │   │   └── speedtest.py
│   │   │   │   ├── settings.sample.json
│   │   │   │   └── widgets/
│   │   │   │       └── .gitkeep
│   │   │   └── test/
│   │   │       └── .gitkeep
│   │   ├── timer/
│   │   │   ├── README.md
│   │   │   ├── config/
│   │   │   │   └── en.json
│   │   │   ├── memory/
│   │   │   │   └── .gitkeep
│   │   │   ├── skill.json
│   │   │   ├── src/
│   │   │   │   ├── actions/
│   │   │   │   │   ├── cancel_timer.ts
│   │   │   │   │   ├── check_timer.ts
│   │   │   │   │   └── set_timer.ts
│   │   │   │   ├── lib/
│   │   │   │   │   ├── .gitkeep
│   │   │   │   │   └── memory.ts
│   │   │   │   ├── settings.sample.json
│   │   │   │   └── widgets/
│   │   │   │       ├── .gitkeep
│   │   │   │       ├── components/
│   │   │   │       │   └── timer.ts
│   │   │   │       └── timer-widget.ts
│   │   │   └── test/
│   │   │       └── .gitkeep
│   │   └── translator-poc/
│   │       ├── README.md
│   │       ├── config/
│   │       │   └── en.json
│   │       ├── memory/
│   │       │   └── .gitkeep
│   │       ├── skill.json
│   │       ├── src/
│   │       │   ├── actions/
│   │       │   │   └── translate.ts
│   │       │   ├── lib/
│   │       │   │   └── .gitkeep
│   │       │   ├── settings.sample.json
│   │       │   └── widgets/
│   │       │       └── .gitkeep
│   │       └── test/
│   │           └── .gitkeep
│   ├── video_summarizer_skill/
│   │   ├── locales/
│   │   │   └── en.json
│   │   ├── skill.json
│   │   └── src/
│   │       ├── actions/
│   │       │   ├── prepare_audio.ts
│   │       │   └── summarize_transcription.ts
│   │       └── settings.sample.json
│   ├── video_translator_skill/
│   │   ├── README.md
│   │   ├── locales/
│   │   │   └── en.json
│   │   ├── memory/
│   │   │   └── .gitkeep
│   │   ├── skill.json
│   │   └── src/
│   │       ├── actions/
│   │       │   ├── create_new_audio.ts
│   │       │   ├── detect_genders.ts
│   │       │   ├── download_video.ts
│   │       │   ├── extract_audio.ts
│   │       │   ├── get_speakers_references.ts
│   │       │   ├── merge_audio.ts
│   │       │   └── translate_transcription.ts
│   │       ├── lib/
│   │       │   └── memory.ts
│   │       ├── settings.sample.json
│   │       └── widgets/
│   │           └── download-progress-widget.ts
│   ├── voice_designer_skill/
│   │   ├── locales/
│   │   │   └── en.json
│   │   ├── skill.json
│   │   └── src/
│   │       ├── actions/
│   │       │   └── design_and_speak.ts
│   │       └── settings.sample.json
│   ├── weather/
│   │   └── domain.json
│   └── weather_forecast_skill/
│       ├── locales/
│       │   └── en.json
│       ├── skill.json
│       └── src/
│           ├── actions/
│           │   └── get_forecast.ts
│           ├── settings.sample.json
│           └── widgets/
│               └── weather-forecast-widget.ts
├── tcp_server/
│   ├── settings.json
│   └── src/
│       ├── Pipfile
│       ├── lib/
│       │   ├── asr/
│       │   │   └── api.py
│       │   ├── constants.py
│       │   ├── nlp.py
│       │   ├── tcp_server.py
│       │   ├── tmp/
│       │   │   └── .gitkeep
│       │   ├── tts/
│       │   │   ├── __init__.py
│       │   │   ├── api.py
│       │   │   ├── attentions.py
│       │   │   ├── commons.py
│       │   │   ├── models.py
│       │   │   ├── modules.py
│       │   │   ├── monotonic_align/
│       │   │   │   ├── __init__.py
│       │   │   │   └── core.py
│       │   │   ├── split_utils.py
│       │   │   ├── text/
│       │   │   │   ├── __init__.py
│       │   │   │   ├── cleaner.py
│       │   │   │   ├── cleaner_multiling.py
│       │   │   │   ├── cmudict.rep
│       │   │   │   ├── cmudict_cache.pickle
│       │   │   │   ├── english.py
│       │   │   │   ├── english_bert.py
│       │   │   │   ├── english_utils/
│       │   │   │   │   ├── __init__.py
│       │   │   │   │   ├── abbreviations.py
│       │   │   │   │   ├── number_norm.py
│       │   │   │   │   └── time_norm.py
│       │   │   │   ├── fr_phonemizer/
│       │   │   │   │   ├── __init__.py
│       │   │   │   │   ├── base.py
│       │   │   │   │   ├── cleaner.py
│       │   │   │   │   ├── en_symbols.json
│       │   │   │   │   ├── example_ipa.txt
│       │   │   │   │   ├── fr_symbols.json
│       │   │   │   │   ├── fr_to_ipa.py
│       │   │   │   │   ├── french_abbreviations.py
│       │   │   │   │   ├── french_symbols.txt
│       │   │   │   │   ├── gruut_wrapper.py
│       │   │   │   │   └── punctuation.py
│       │   │   │   ├── french.py
│       │   │   │   ├── french_bert.py
│       │   │   │   ├── opencpop-strict.txt
│       │   │   │   └── symbols.py
│       │   │   ├── transforms.py
│       │   │   └── utils.py
│       │   ├── utils.py
│       │   └── wake_word/
│       │       └── api.py
│       ├── main.py
│       ├── setup.py
│       └── version.py
├── test/
│   ├── agentic-loop/
│   │   ├── e2e/
│   │   │   ├── provider-matrix.ts
│   │   │   ├── react-provider-smoke.spec.ts
│   │   │   └── run-agentic-loop-provider-scenario.ts
│   │   └── unit/
│   │       └── react-llm-duty.spec.ts
│   ├── assets/
│   │   ├── broken-leon-model.nlp
│   │   └── expressions.json
│   ├── e2e/
│   │   ├── modules/
│   │   │   ├── e2e.modules.jest.json
│   │   │   └── e2e.modules.setup.js
│   │   ├── nlp-modules.spec.js
│   │   └── over-http.spec.js
│   ├── json/
│   │   ├── is-valid.spec.js
│   │   ├── json.jest.json
│   │   ├── no-punctuation.spec.js
│   │   └── punctuation.spec.js
│   ├── paths.setup.js
│   └── unit/
│       ├── server/
│       │   ├── core/
│       │   │   ├── asr.spec.js
│       │   │   ├── brain.spec.js
│       │   │   ├── ner.spec.js
│       │   │   ├── nlu.spec.js
│       │   │   ├── server.spec.js
│       │   │   └── synchronizer.spec.js
│       │   ├── helpers/
│       │   │   ├── date.spec.js
│       │   │   ├── loader.spec.js
│       │   │   ├── log.spec.js
│       │   │   ├── os.spec.js
│       │   │   └── string.spec.js
│       │   ├── stt/
│       │   │   ├── coqui/
│       │   │   │   └── parser.spec.js
│       │   │   └── stt.spec.js
│       │   └── tts/
│       │       ├── flite/
│       │       │   └── synthesizer.spec.js
│       │       └── tts.spec.js
│       ├── unit.jest.json
│       └── unit.setup.js
├── tsconfig.json
└── vitest.agentic-loop.config.ts
Download .txt
Showing preview only (337K chars total). Download the full file or copy to clipboard to get everything.
SYMBOL INDEX (3816 symbols across 398 files)

FILE: app/src/custom-aurora-components/timer/timer.tsx
  type TimerProps (line 4) | interface TimerProps {
  function formatTime (line 12) | function formatTime(seconds: number): string {
  function Timer (line 22) | function Timer({

FILE: app/src/js/chatbot.js
  constant WIDGETS_TO_FETCH (line 10) | const WIDGETS_TO_FETCH = []
  constant WIDGETS_FETCH_CACHE (line 11) | const WIDGETS_FETCH_CACHE = new Map()
  constant REPLACED_MESSAGES (line 12) | const REPLACED_MESSAGES = new Set()
  constant AUTO_SCROLL_BOTTOM_THRESHOLD_PX (line 13) | const AUTO_SCROLL_BOTTOM_THRESHOLD_PX = 24
  class Chatbot (line 15) | class Chatbot {
    method constructor (line 16) | constructor(socket, serverURL) {
    method init (line 37) | async init() {
    method sendTo (line 74) | sendTo(who, string) {
    method receivedFrom (line 80) | receivedFrom(who, string) {
    method isTyping (line 86) | isTyping(who, value) {
    method enableTyping (line 96) | enableTyping() {
    method disableTyping (line 102) | disableTyping() {
    method isElementNearBottom (line 108) | isElementNearBottom(element) {
    method handleFeedScroll (line 119) | handleFeedScroll() {
    method scrollDown (line 127) | scrollDown(options = {}) {
    method scrollReasoningContentToBottom (line 147) | scrollReasoningContentToBottom(reasoningBlock) {
    method getWidgetPayload (line 163) | getWidgetPayload(formattedString) {
    method getPlanWidgetInsertionPoint (line 178) | getPlanWidgetInsertionPoint(widgetPayload) {
    method isPlanWidgetData (line 190) | isPlanWidgetData(data) {
    method loadFeed (line 194) | loadFeed() {
    method createBubble (line 289) | createBubble(params) {
    method formatReasoningPhaseTitle (line 396) | formatReasoningPhaseTitle(phase) {
    method createOrUpdateReasoningBlock (line 405) | createOrUpdateReasoningBlock(generationId, token, phase) {
    method handleToolOutput (line 468) | handleToolOutput(data) {
    method saveBubble (line 490) | saveBubble(who, originalString, string, messageId, metrics = null) {
    method formatMessage (line 511) | formatMessage(message) {
    method formatMetrics (line 535) | formatMetrics(metrics) {
    method createMetricsElement (line 567) | createMetricsElement(metrics) {
    method updateBubbleMetrics (line 576) | updateBubbleMetrics(container, metrics) {
    method getLatestReasoningContainer (line 599) | getLatestReasoningContainer() {
    method replaceMessage (line 611) | replaceMessage(replaceMessageId, newData) {
    method openPath (line 665) | openPath(filePath) {

FILE: app/src/js/client.js
  class Client (line 8) | class Client {
    method constructor (line 9) | constructor(client, serverUrl, input) {
    method input (line 30) | set input(newInput) {
    method input (line 36) | get input() {
    method recorder (line 40) | set recorder(recorder) {
    method recorder (line 44) | get recorder() {
    method updateMood (line 48) | updateMood(mood) {
    method sendInitMessages (line 57) | async sendInitMessages() {
    method setInitStatus (line 75) | setInitStatus(statusName, statusType) {
    method asrStartRecording (line 86) | asrStartRecording() {
    method init (line 101) | init() {
    method send (line 438) | send(keyword) {
    method save (line 466) | save() {
    method enableVoiceMode (line 508) | enableVoiceMode() {
    method disableVoiceMode (line 526) | disableVoiceMode() {

FILE: app/src/js/constants.js
  constant INIT_MESSAGES (line 1) | const INIT_MESSAGES = [

FILE: app/src/js/init.jsx
  function Item (line 17) | function Item({ children, status }) {
  function LoadingListItem (line 34) | function LoadingListItem({ children }) {
  function ErrorListItem (line 44) | function ErrorListItem({ children }) {
  function WarningListItem (line 61) | function WarningListItem({ children }) {
  function SuccessListItem (line 78) | function SuccessListItem({ children }) {
  function Init (line 96) | function Init() {

FILE: app/src/js/recorder.js
  class Recorder (line 4) | class Recorder {
    method constructor (line 5) | constructor(stream, el, info) {
    method start (line 18) | start(playSound = true) {
    method stop (line 27) | stop(playSound = true) {
    method onstart (line 36) | onstart(cb) {
    method onstop (line 47) | onstop(cb) {
    method ondataavailable (line 58) | ondataavailable(cb) {

FILE: app/src/js/render-aurora-component.js
  function renderAuroraComponent (line 6) | function renderAuroraComponent(

FILE: app/src/js/suggestion-handler.js
  function handleSuggestions (line 5) | function handleSuggestions(data, chatbot, client) {

FILE: app/src/js/tool-ui-handler.js
  class ToolUIHandler (line 5) | class ToolUIHandler {
    method constructor (line 6) | constructor(feedElement, scrollDownCallback, formatMessageCallback) {
    method handleToolOutput (line 16) | handleToolOutput(data) {
    method createToolGroupContainer (line 66) | createToolGroupContainer(groupId, toolkitName, toolName, answerKey) {
    method addExpandCollapseHandler (line 114) | addExpandCollapseHandler(toolHeader, toolContent) {
    method addToolMessage (line 132) | addToolMessage(toolGroupContainer, message) {
    method replaceToolMessage (line 151) | replaceToolMessage(replaceMessageId, newData) {
    method getToolGroupInfo (line 170) | getToolGroupInfo(groupId, toolkitName, toolName, message) {
    method isToolOutputMarker (line 181) | static isToolOutputMarker(messageString) {
    method clearToolGroups (line 188) | clearToolGroups() {
    method getToolGroupCount (line 195) | getToolGroupCount() {
    method getToolGroup (line 202) | getToolGroup(groupId) {
    method removeToolGroup (line 209) | removeToolGroup(groupId) {

FILE: app/src/js/voice-energy.js
  constant STATUS (line 1) | const STATUS = {
  class VoiceEnergy (line 8) | class VoiceEnergy {
    method constructor (line 9) | constructor(client) {
    method status (line 19) | get status() {
    method status (line 23) | set status(newStatus) {
    method init (line 43) | init() {

FILE: bridges/nodejs/src/constants.ts
  constant INTENT_OBJ_FILE_PATH (line 19) | const INTENT_OBJ_FILE_PATH =
  constant LEON_VERSION (line 22) | const LEON_VERSION = process.env['npm_package_version']
  constant RUNTIME (line 24) | const RUNTIME = runtime
  constant BIN_PATH (line 26) | const BIN_PATH = path.join(process.cwd(), 'bin')
  constant BRIDGES_PATH (line 27) | const BRIDGES_PATH = path.join(process.cwd(), 'bridges')
  constant NODEJS_BRIDGE_ROOT_PATH (line 28) | const NODEJS_BRIDGE_ROOT_PATH = path.join(BRIDGES_PATH, 'nodejs')
  constant NODEJS_BRIDGE_SRC_PATH (line 29) | const NODEJS_BRIDGE_SRC_PATH = path.join(NODEJS_BRIDGE_ROOT_PATH, 'src')
  constant NODEJS_BRIDGE_VERSION_FILE_PATH (line 30) | const NODEJS_BRIDGE_VERSION_FILE_PATH = path.join(
  constant TOOLKITS_PATH (line 35) | const TOOLKITS_PATH = path.join(BRIDGES_PATH, 'toolkits')
  constant INTENT_OBJECT (line 51) | const INTENT_OBJECT: IntentObject = parsedIntentObject
  constant NVIDIA_LIBS_PATH (line 55) | const NVIDIA_LIBS_PATH = path.join(BIN_PATH, 'nvidia')
  constant PYTORCH_PATH (line 57) | const PYTORCH_PATH = path.join(BIN_PATH, 'pytorch')
  constant PYTORCH_TORCH_PATH (line 58) | const PYTORCH_TORCH_PATH = path.join(PYTORCH_PATH, 'torch')
  constant SKILLS_PATH (line 60) | const SKILLS_PATH = path.join(process.cwd(), 'skills')
  constant SKILL_PATH (line 61) | const SKILL_PATH =
  constant SKILL_LOCALE_CONFIG_CONTENT (line 65) | const SKILL_LOCALE_CONFIG_CONTENT =
  constant SKILL_LOCALE_CONFIG (line 86) | const SKILL_LOCALE_CONFIG: SkillLocaleConfigSchema &

FILE: bridges/nodejs/src/sdk/aurora/button.ts
  class Button (line 5) | class Button extends WidgetComponent<ButtonProps> {
    method constructor (line 6) | constructor(props: ButtonProps) {

FILE: bridges/nodejs/src/sdk/aurora/card.ts
  class Card (line 5) | class Card extends WidgetComponent<CardProps> {
    method constructor (line 6) | constructor(props: CardProps) {

FILE: bridges/nodejs/src/sdk/aurora/checkbox.ts
  class Checkbox (line 5) | class Checkbox extends WidgetComponent<CheckboxProps> {
    method constructor (line 6) | constructor(props: CheckboxProps) {

FILE: bridges/nodejs/src/sdk/aurora/circular-progress.ts
  class CircularProgress (line 5) | class CircularProgress extends WidgetComponent<CircularProgressProps> {
    method constructor (line 6) | constructor(props: CircularProgressProps) {

FILE: bridges/nodejs/src/sdk/aurora/flexbox.ts
  class Flexbox (line 5) | class Flexbox extends WidgetComponent<FlexboxProps> {
    method constructor (line 6) | constructor(props: FlexboxProps) {

FILE: bridges/nodejs/src/sdk/aurora/form.ts
  class Form (line 5) | class Form extends WidgetComponent<FormProps> {
    method constructor (line 6) | constructor(props: FormProps) {

FILE: bridges/nodejs/src/sdk/aurora/icon-button.ts
  class IconButton (line 5) | class IconButton extends WidgetComponent<IconButtonProps> {
    method constructor (line 6) | constructor(props: IconButtonProps) {

FILE: bridges/nodejs/src/sdk/aurora/icon.ts
  class Icon (line 5) | class Icon extends WidgetComponent<IconProps> {
    method constructor (line 6) | constructor(props: IconProps) {

FILE: bridges/nodejs/src/sdk/aurora/image.ts
  class Image (line 5) | class Image extends WidgetComponent<ImageProps> {
    method constructor (line 6) | constructor(props: ImageProps) {

FILE: bridges/nodejs/src/sdk/aurora/input.ts
  class Input (line 5) | class Input extends WidgetComponent<InputProps> {
    method constructor (line 6) | constructor(props: InputProps) {

FILE: bridges/nodejs/src/sdk/aurora/link.ts
  class Link (line 5) | class Link extends WidgetComponent<LinkProps> {
    method constructor (line 6) | constructor(props: LinkProps) {

FILE: bridges/nodejs/src/sdk/aurora/list-header.ts
  class ListHeader (line 5) | class ListHeader extends WidgetComponent<ListHeaderProps> {
    method constructor (line 6) | constructor(props: ListHeaderProps) {

FILE: bridges/nodejs/src/sdk/aurora/list-item.ts
  class ListItem (line 5) | class ListItem extends WidgetComponent<ListItemProps> {
    method constructor (line 6) | constructor(props: ListItemProps) {

FILE: bridges/nodejs/src/sdk/aurora/list.ts
  class List (line 5) | class List extends WidgetComponent<ListProps> {
    method constructor (line 6) | constructor(props: ListProps) {

FILE: bridges/nodejs/src/sdk/aurora/loader.ts
  class Loader (line 5) | class Loader extends WidgetComponent<LoaderProps> {
    method constructor (line 6) | constructor(props: LoaderProps) {

FILE: bridges/nodejs/src/sdk/aurora/progress.ts
  class Progress (line 5) | class Progress extends WidgetComponent<ProgressProps> {
    method constructor (line 6) | constructor(props: ProgressProps) {

FILE: bridges/nodejs/src/sdk/aurora/radio-group.ts
  class RadioGroup (line 5) | class RadioGroup extends WidgetComponent<RadioGroupProps> {
    method constructor (line 6) | constructor(props: RadioGroupProps) {

FILE: bridges/nodejs/src/sdk/aurora/radio.ts
  class Radio (line 5) | class Radio extends WidgetComponent<RadioProps> {
    method constructor (line 6) | constructor(props: RadioProps) {

FILE: bridges/nodejs/src/sdk/aurora/range-slider.ts
  class RangeSlider (line 5) | class RangeSlider extends WidgetComponent<RangeSliderProps> {
    method constructor (line 6) | constructor(props: RangeSliderProps) {

FILE: bridges/nodejs/src/sdk/aurora/scroll-container.ts
  class ScrollContainer (line 5) | class ScrollContainer extends WidgetComponent<ScrollContainerProps> {
    method constructor (line 6) | constructor(props: ScrollContainerProps) {

FILE: bridges/nodejs/src/sdk/aurora/select-option.ts
  class SelectOption (line 5) | class SelectOption extends WidgetComponent<SelectOptionProps> {
    method constructor (line 6) | constructor(props: SelectOptionProps) {

FILE: bridges/nodejs/src/sdk/aurora/select.ts
  class Select (line 5) | class Select extends WidgetComponent<SelectProps> {
    method constructor (line 6) | constructor(props: SelectProps) {

FILE: bridges/nodejs/src/sdk/aurora/status.ts
  class Status (line 5) | class Status extends WidgetComponent<StatusProps> {
    method constructor (line 6) | constructor(props: StatusProps) {

FILE: bridges/nodejs/src/sdk/aurora/switch.ts
  class Switch (line 5) | class Switch extends WidgetComponent<SwitchProps> {
    method constructor (line 6) | constructor(props: SwitchProps) {

FILE: bridges/nodejs/src/sdk/aurora/tab-content.ts
  class TabContent (line 5) | class TabContent extends WidgetComponent<TabContentProps> {
    method constructor (line 6) | constructor(props: TabContentProps) {

FILE: bridges/nodejs/src/sdk/aurora/tab-group.ts
  class TabGroup (line 5) | class TabGroup extends WidgetComponent<TabGroupProps> {
    method constructor (line 6) | constructor(props: TabGroupProps) {

FILE: bridges/nodejs/src/sdk/aurora/tab-list.ts
  class TabList (line 5) | class TabList extends WidgetComponent<TabListProps> {
    method constructor (line 6) | constructor(props: TabListProps) {

FILE: bridges/nodejs/src/sdk/aurora/tab.ts
  class Tab (line 5) | class Tab extends WidgetComponent<TabProps> {
    method constructor (line 6) | constructor(props: TabProps) {

FILE: bridges/nodejs/src/sdk/aurora/text.ts
  class Text (line 5) | class Text extends WidgetComponent<TextProps> {
    method constructor (line 6) | constructor(props: TextProps) {

FILE: bridges/nodejs/src/sdk/aurora/widget-wrapper.ts
  class WidgetWrapper (line 5) | class WidgetWrapper extends WidgetComponent<WidgetWrapperProps> {
    method constructor (line 6) | constructor(props: WidgetWrapperProps) {

FILE: bridges/nodejs/src/sdk/base-tool.ts
  type ProgressCallback (line 28) | type ProgressCallback = (progress: {
  type ExecuteCommandOptions (line 37) | interface ExecuteCommandOptions {
  method aliasToolName (line 109) | get aliasToolName(): string {
  method getSettingsPath (line 126) | protected getSettingsPath(toolName?: string): string {
  method checkRequiredSettings (line 139) | protected checkRequiredSettings(toolName?: string): void {
  method getMissingSettings (line 164) | getMissingSettings(): { missing: string[], settingsPath: string } | null {
  method getToolDir (line 171) | protected getToolDir(moduleUrl: string): string {
  method report (line 178) | protected async report(
  method escapeShellArg (line 212) | private escapeShellArg(arg: string): string {
  method executeCommand (line 243) | protected async executeCommand(
  method executeSyncCommand (line 308) | private executeSyncCommand(
  method executeAsyncCommand (line 371) | private executeAsyncCommand(
  method getBundledLibraryEnv (line 492) | private getBundledLibraryEnv(): NodeJS.ProcessEnv {
  method getBundledLibraryPaths (line 515) | private getBundledLibraryPaths(): string[] {
  method getBinaryPath (line 528) | async getBinaryPath(
  method formatCommandOutput (line 606) | private formatCommandOutput(output: string): string | null {
  method reportCommandOutput (line 620) | private async reportCommandOutput(
  method getResourcePath (line 645) | async getResourcePath(resourceName: string): Promise<string> {
  method isResourceComplete (line 764) | private isResourceComplete(
  method getResourceRelativePath (line 788) | private getResourceRelativePath(resourceUrl: string): string {
  method deleteOlderBinaryVersions (line 814) | private async deleteOlderBinaryVersions(
  method executeTerminalCommand (line 879) | private async executeTerminalCommand(
  method buildTerminalRunCommand (line 948) | private buildTerminalRunCommand(
  method buildBinaryCommand (line 967) | private buildBinaryCommand(binaryPath: string, args: string[]): string {
  method launchTerminal (line 973) | private launchTerminal(command: string): void {
  method waitForMarker (line 1024) | private async waitForMarker(
  method spawnDetached (line 1040) | private spawnDetached(command: string, args: string[]): void {
  method commandExists (line 1045) | private commandExists(command: string): boolean {
  method escapeWindowsArg (line 1051) | private escapeWindowsArg(value: string): string {
  method escapeForAppleScript (line 1055) | private escapeForAppleScript(value: string): string {
  method downloadBinaryOnDemand (line 1062) | private async downloadBinaryOnDemand(
  method isArchive (line 1110) | private isArchive(filePath: string): boolean {
  method downloadBinary (line 1127) | private async downloadBinary(url: string, outputPath: string): Promise<v...
  method log (line 1238) | protected log(message: string, ...args: unknown[]): void {
  method listenDownloadProgress (line 1255) | private listenDownloadProgress(
  method removeQuarantineAttribute (line 1338) | private async removeQuarantineAttribute(filePath: string): Promise<void> {

FILE: bridges/nodejs/src/sdk/leon.ts
  class Leon (line 14) | class Leon {
    method constructor (line 29) | constructor() {
    method injectVariables (line 41) | private injectVariables(
    method setAnswerData (line 85) | public setAnswerData(
    method answer (line 124) | public async answer(answerInput: AnswerInput): Promise<string | null> {

FILE: bridges/nodejs/src/sdk/memory.ts
  type MemoryOptions (line 6) | interface MemoryOptions<T> {
  class Memory (line 11) | class Memory<T = unknown> {
    method constructor (line 17) | constructor(options: MemoryOptions<T>) {
    method clear (line 43) | public async clear(): Promise<void> {
    method read (line 57) | public async read(): Promise<T> {
    method write (line 81) | public async write(memory: T): Promise<T> {

FILE: bridges/nodejs/src/sdk/network.ts
  type NetworkOptions (line 8) | interface NetworkOptions {
  type NetworkRequestOptions (line 13) | interface NetworkRequestOptions {
  type NetworkResponse (line 42) | interface NetworkResponse<ResponseData> {
  class NetworkError (line 65) | class NetworkError<ResponseErrorData = unknown> extends Error {
    method constructor (line 68) | constructor(response: NetworkResponse<ResponseErrorData>) {
  class Network (line 75) | class Network {
    method constructor (line 79) | constructor(options: NetworkOptions = {}) {
    method request (line 91) | public async request<ResponseData = unknown, ResponseErrorData = unkno...
    method isNetworkError (line 178) | public isNetworkError<ResponseErrorData = unknown>(
    method isNetworkAvailable (line 188) | public async isNetworkAvailable(): Promise<boolean> {

FILE: bridges/nodejs/src/sdk/params-helper.ts
  class ParamsHelper (line 4) | class ParamsHelper {
    method constructor (line 7) | constructor(params: ActionParams) {
    method getWidgetId (line 15) | getWidgetId(): string | null {
    method getActionArgument (line 26) | getActionArgument(name: string): string | undefined {
    method findEntity (line 34) | findEntity(entityName: string): NEREntity | undefined {
    method findLastEntity (line 43) | findLastEntity(entityName: string): NEREntity | undefined {
    method findAllEntities (line 53) | findAllEntities(entityName: string): NEREntity[] {
    method findActionArgumentFromContext (line 61) | findActionArgumentFromContext(name: string): string | undefined {
    method findLastActionArgumentFromContext (line 76) | findLastActionArgumentFromContext(name: string): string | undefined {
    method findLastEntityFromContext (line 98) | findLastEntityFromContext(entityName: string): NEREntity | undefined {
    method findAllEntitiesFromContext (line 109) | findAllEntitiesFromContext(entityName: string): NEREntity[] {
    method getContextData (line 119) | getContextData<T = unknown>(key: string): T | undefined {

FILE: bridges/nodejs/src/sdk/settings.ts
  class Settings (line 6) | class Settings<T extends Record<string, unknown>> {
    method constructor (line 10) | constructor() {
    method isSettingSet (line 24) | public async isSettingSet(key: string): Promise<boolean> {
    method clear (line 38) | public async clear(): Promise<void> {
    method getSettingsSample (line 44) | private async getSettingsSample(): Promise<T> {
    method get (line 67) | public async get<Key extends keyof T>(key?: Key): Promise<T | T[Key]> {
    method set (line 99) | public async set<Key extends keyof T>(

FILE: bridges/nodejs/src/sdk/tool-manager.ts
  class MissingToolSettingsError (line 5) | class MissingToolSettingsError extends Error {
    method constructor (line 9) | constructor(missing: string[], settingsPath: string) {
  class ToolManager (line 23) | class ToolManager {
    method initTool (line 24) | static async initTool<TTool extends Tool>(

FILE: bridges/nodejs/src/sdk/tool-reporter.ts
  type ToolReporter (line 1) | type ToolReporter = (input: Record<string, unknown>) => Promise<void>

FILE: bridges/nodejs/src/sdk/toolkit-config.ts
  type ToolConfig (line 7) | interface ToolConfig {
  type ToolkitConfigData (line 20) | interface ToolkitConfigData {
  class ToolkitConfig (line 26) | class ToolkitConfig {
    method load (line 35) | static load(toolkitName: string, toolName: string): ToolConfig {
    method loadToolSettings (line 72) | static loadToolSettings(
    method getBinaryUrl (line 119) | static getBinaryUrl(config: ToolConfig): string | undefined {

FILE: bridges/nodejs/src/sdk/tools/assemblyai_audio/assemblyai_audio-tool.ts
  constant ASSEMBLYAI_AUDIO_API_KEY (line 9) | const ASSEMBLYAI_AUDIO_API_KEY: string | null = null
  constant DEFAULT_SETTINGS (line 10) | const DEFAULT_SETTINGS: Record<string, unknown> = {
  constant REQUIRED_SETTINGS (line 13) | const REQUIRED_SETTINGS = ['ASSEMBLYAI_AUDIO_API_KEY']
  type AssemblyAIUploadResponse (line 15) | interface AssemblyAIUploadResponse {
  type AssemblyAITranscriptionResponse (line 19) | interface AssemblyAITranscriptionResponse {
  class AssemblyAIAudioTool (line 47) | class AssemblyAIAudioTool extends Tool {
    method constructor (line 52) | constructor() {
    method toolName (line 71) | get toolName(): string {
    method toolkit (line 75) | get toolkit(): string {
    method description (line 79) | get description(): string {
    method transcribeToFile (line 90) | async transcribeToFile(
    method parseTranscription (line 185) | private parseTranscription(

FILE: bridges/nodejs/src/sdk/tools/bash/bash-tool.ts
  constant DEFAULT_SETTINGS (line 7) | const DEFAULT_SETTINGS: Record<string, unknown> = {}
  constant REQUIRED_SETTINGS (line 8) | const REQUIRED_SETTINGS: string[] = []
  type BashResult (line 10) | interface BashResult {
  type ExecuteOptions (line 18) | interface ExecuteOptions {
  constant CRITICAL_COMMAND_SEQUENCES (line 24) | const CRITICAL_COMMAND_SEQUENCES = [
  constant CRITICAL_COMMAND_TOKENS (line 30) | const CRITICAL_COMMAND_TOKENS = ['mkfs', 'format', 'fdisk'] as const
  constant HIGH_RISK_DD_TOKENS (line 31) | const HIGH_RISK_DD_TOKENS = ['dd'] as const
  constant HIGH_RISK_EVAL_DOWNLOAD_TOKENS (line 32) | const HIGH_RISK_EVAL_DOWNLOAD_TOKENS = ['curl', 'wget'] as const
  constant ELEVATED_COMMAND_TOKENS (line 33) | const ELEVATED_COMMAND_TOKENS = ['sudo', 'doas', 'pkexec', 'su'] as const
  constant PERMISSION_COMMAND_TOKENS (line 34) | const PERMISSION_COMMAND_TOKENS = ['chmod', 'chown'] as const
  constant PACKAGE_MANAGER_COMMAND_TOKENS (line 35) | const PACKAGE_MANAGER_COMMAND_TOKENS = [
  constant MEDIUM_RISK_COMMAND_PATTERNS (line 44) | const MEDIUM_RISK_COMMAND_PATTERNS: string[] = []
  constant UNSAFE_COMMAND_PATTERNS (line 46) | const UNSAFE_COMMAND_PATTERNS = [
  constant TERMINAL_AUTH_COMMANDS (line 51) | const TERMINAL_AUTH_COMMANDS = new Set(ELEVATED_COMMAND_TOKENS)
  constant TERMINAL_AUTH_WRAPPERS (line 52) | const TERMINAL_AUTH_WRAPPERS = new Set([
  class BashTool (line 60) | class BashTool extends Tool {
    method constructor (line 64) | constructor() {
    method toolName (line 77) | get toolName(): string {
    method toolkit (line 81) | get toolkit(): string {
    method description (line 85) | get description(): string {
    method executeBashCommand (line 89) | async executeBashCommand(
    method isSafeCommand (line 200) | async isSafeCommand(command: string): Promise<boolean> {
    method getCommandRiskLevel (line 226) | async getCommandRiskLevel(command: string): Promise<string> {
    method getRiskDescription (line 264) | async getRiskDescription(command: string): Promise<string> {
    method resolveCommandForSafetyAnalysis (line 296) | private async resolveCommandForSafetyAnalysis(command: string): Promis...
    method isDownloadPipedToShell (line 321) | private isDownloadPipedToShell(commandLower: string): boolean {
    method tokenizeCommand (line 330) | private tokenizeCommand(command: string): string[] {
    method hasTokenSequence (line 394) | private hasTokenSequence(tokens: string[], sequence: string[]): boolean {
    method hasCommandToken (line 411) | private hasCommandToken(tokens: string[], commands: string[]): boolean {
    method hasDangerousDdPattern (line 421) | private hasDangerousDdPattern(tokens: string[]): boolean {
    method hasEvalDownloadPattern (line 429) | private hasEvalDownloadPattern(tokens: string[]): boolean {
    method normalizeCommandToken (line 448) | private normalizeCommandToken(token: string): string {
    method hasAnyTokenSequence (line 457) | private hasAnyTokenSequence(
    method requiresVisibleTerminal (line 466) | private requiresVisibleTerminal(command: string): boolean {
    method isShellAssignment (line 536) | private isShellAssignment(token: string): boolean {

FILE: bridges/nodejs/src/sdk/tools/cerebras/cerebras-tool.ts
  constant CEREBRAS_API_KEY (line 6) | const CEREBRAS_API_KEY: string | null = null
  constant CEREBRAS_MODEL (line 7) | const CEREBRAS_MODEL = 'zai-glm-4.7'
  constant DEFAULT_SETTINGS (line 8) | const DEFAULT_SETTINGS: Record<string, unknown> = {
  constant REQUIRED_SETTINGS (line 12) | const REQUIRED_SETTINGS = ['CEREBRAS_API_KEY']
  type ChatMessage (line 14) | interface ChatMessage {
  type ChatCompletionOptions (line 19) | interface ChatCompletionOptions {
  type CompletionOptions (line 30) | interface CompletionOptions {
  type StructuredCompletionOptions (line 41) | interface StructuredCompletionOptions {
  type ApiResponse (line 51) | interface ApiResponse {
  class CerebrasTool (line 60) | class CerebrasTool extends Tool {
    method constructor (line 74) | constructor(apiKey?: string) {
    method toolName (line 100) | get toolName(): string {
    method toolkit (line 104) | get toolkit(): string {
    method description (line 108) | get description(): string {
    method setApiKey (line 115) | setApiKey(apiKey: string): void {
    method getAvailableModels (line 122) | getAvailableModels(): string[] {
    method getModelId (line 129) | getModelId(modelName: string): string {
    method chatCompletion (line 139) | async chatCompletion(options: ChatCompletionOptions): Promise<ApiRespo...
    method completion (line 220) | async completion(options: CompletionOptions): Promise<ApiResponse> {
    method structuredCompletion (line 267) | async structuredCompletion(
    method listModels (line 323) | async listModels(): Promise<ApiResponse> {

FILE: bridges/nodejs/src/sdk/tools/chatterbox_onnx/chatterbox_onnx-tool.ts
  constant MODEL_NAME (line 10) | const MODEL_NAME = 'chatterbox-multilingual-onnx'
  constant DEFAULT_MAX_CHARS (line 11) | const DEFAULT_MAX_CHARS = 272 // Character limit to avoid hallucination
  constant DEFAULT_SETTINGS (line 12) | const DEFAULT_SETTINGS: Record<string, unknown> = {}
  constant REQUIRED_SETTINGS (line 13) | const REQUIRED_SETTINGS: string[] = []
  type SynthesisTask (line 15) | interface SynthesisTask {
  function splitTextAtPunctuation (line 39) | function splitTextAtPunctuation(
  class ChatterboxONNXTool (line 90) | class ChatterboxONNXTool extends Tool {
    method constructor (line 94) | constructor() {
    method toolName (line 108) | get toolName(): string {
    method toolkit (line 113) | get toolkit(): string {
    method description (line 117) | get description(): string {
    method synthesizeSpeechToFiles (line 132) | async synthesizeSpeechToFiles(

FILE: bridges/nodejs/src/sdk/tools/context/context-tool.ts
  constant ROOT_DIR (line 7) | const ROOT_DIR = process.cwd()
  constant CONTEXT_DIR (line 8) | const CONTEXT_DIR = path.join(ROOT_DIR, 'core', 'context')
  constant DEFAULT_LIST_LIMIT (line 9) | const DEFAULT_LIST_LIMIT = 24
  constant DEFAULT_TOP_K (line 10) | const DEFAULT_TOP_K = 8
  constant DEFAULT_SNIPPET_CHARS (line 11) | const DEFAULT_SNIPPET_CHARS = Number.MAX_SAFE_INTEGER
  type ContextListEntry (line 13) | interface ContextListEntry {
  type SearchHit (line 20) | interface SearchHit {
  class ContextTool (line 27) | class ContextTool extends Tool {
    method constructor (line 31) | constructor() {
    method toolName (line 43) | get toolName(): string {
    method toolkit (line 47) | get toolkit(): string {
    method description (line 51) | get description(): string {
    method listContextFiles (line 55) | public async listContextFiles(
    method readContextFile (line 86) | public async readContextFile(
    method searchContext (line 157) | public async searchContext(
    method ensureContextDir (line 270) | private async ensureContextDir(): Promise<void> {
    method resolveFilename (line 274) | private resolveFilename(filename: string): string | null {
    method readContextEntries (line 289) | private async readContextEntries(): Promise<Array<{
    method extractSummary (line 331) | private extractSummary(content: string): string {
    method tokenize (line 349) | private tokenize(value: string): string[] {
    method clampNumber (line 355) | private clampNumber(
    method buildSnippet (line 368) | private buildSnippet(content: string, center: number, maxChars: number...

FILE: bridges/nodejs/src/sdk/tools/ecapa/ecapa-tool.ts
  constant MODEL_NAME (line 6) | const MODEL_NAME = 'ecapa-voice_gender_classifier'
  constant DEFAULT_SETTINGS (line 7) | const DEFAULT_SETTINGS: Record<string, unknown> = {}
  constant REQUIRED_SETTINGS (line 8) | const REQUIRED_SETTINGS: string[] = []
  class ECAPATool (line 10) | class ECAPATool extends Tool {
    method constructor (line 14) | constructor() {
    method toolName (line 28) | get toolName(): string {
    method toolkit (line 33) | get toolkit(): string {
    method description (line 37) | get description(): string {
    method detectGender (line 47) | async detectGender(inputPath: string, device = 'cpu'): Promise<string> {
    method parseGenderOutput (line 88) | private parseGenderOutput(rawOutput: string): string {

FILE: bridges/nodejs/src/sdk/tools/elevenlabs_audio/elevenlabs_audio-tool.ts
  constant ELEVENLABS_AUDIO_API_KEY (line 11) | const ELEVENLABS_AUDIO_API_KEY: string | null = null
  constant ELEVENLABS_AUDIO_MODEL (line 12) | const ELEVENLABS_AUDIO_MODEL = 'scribe_v1'
  constant DEFAULT_SETTINGS (line 13) | const DEFAULT_SETTINGS: Record<string, unknown> = {
  constant REQUIRED_SETTINGS (line 17) | const REQUIRED_SETTINGS = ['ELEVENLABS_AUDIO_API_KEY']
  type ElevenLabsWord (line 19) | interface ElevenLabsWord {
  type ElevenLabsTranscriptionResponse (line 27) | interface ElevenLabsTranscriptionResponse {
  type ElevenLabsDubbingCreateResponse (line 34) | interface ElevenLabsDubbingCreateResponse {
  type ElevenLabsDubbingStatusResponse (line 39) | interface ElevenLabsDubbingStatusResponse {
  class ElevenLabsAudioTool (line 49) | class ElevenLabsAudioTool extends Tool {
    method constructor (line 55) | constructor() {
    method toolName (line 77) | get toolName(): string {
    method toolkit (line 81) | get toolkit(): string {
    method description (line 85) | get description(): string {
    method transcribeToFile (line 97) | async transcribeToFile(
    method createDubbing (line 153) | async createDubbing(
    method getDubbingStatus (line 193) | async getDubbingStatus(
    method downloadDubbedFile (line 221) | async downloadDubbedFile(
    method parseTranscription (line 250) | private parseTranscription(

FILE: bridges/nodejs/src/sdk/tools/faster_whisper/faster_whisper-tool.ts
  type FasterWhisperTranscriptionOutput (line 18) | type FasterWhisperTranscriptionOutput = string
  constant MODEL_NAME (line 20) | const MODEL_NAME = 'faster-whisper-large-v3'
  constant DEFAULT_SETTINGS (line 21) | const DEFAULT_SETTINGS: Record<string, unknown> = {}
  constant REQUIRED_SETTINGS (line 22) | const REQUIRED_SETTINGS: string[] = []
  class FasterWhisperTool (line 24) | class FasterWhisperTool extends Tool {
    method constructor (line 28) | constructor() {
    method toolName (line 42) | get toolName(): string {
    method toolkit (line 47) | get toolkit(): string {
    method description (line 51) | get description(): string {
    method transcribeToFile (line 65) | async transcribeToFile(
    method parseTranscription (line 129) | private parseTranscription(

FILE: bridges/nodejs/src/sdk/tools/ffmpeg/ffmpeg-tool.ts
  constant DEFAULT_SETTINGS (line 4) | const DEFAULT_SETTINGS: Record<string, unknown> = {}
  constant REQUIRED_SETTINGS (line 5) | const REQUIRED_SETTINGS: string[] = []
  class FfmpegTool (line 7) | class FfmpegTool extends Tool {
    method constructor (line 11) | constructor() {
    method toolName (line 25) | get toolName(): string {
    method toolkit (line 29) | get toolkit(): string {
    method description (line 33) | get description(): string {
    method getGlobalArgs (line 40) | private getGlobalArgs(): string[] {
    method convertVideoFormat (line 50) | async convertVideoFormat(
    method extractAudio (line 73) | async extractAudio(videoPath: string, audioPath: string): Promise<stri...
    method trimMedia (line 133) | async trimMedia(
    method resizeVideo (line 171) | async resizeVideo(
    method combineVideoAndAudio (line 204) | async combineVideoAndAudio(
    method replaceVideoAudio (line 245) | async replaceVideoAudio(
    method compressVideo (line 293) | async compressVideo(
    method adjustTempo (line 327) | async adjustTempo(
    method mergeAudio (line 394) | async mergeAudio(
    method assembleAudioSegments (line 432) | async assembleAudioSegments(

FILE: bridges/nodejs/src/sdk/tools/ffprobe/ffprobe-tool.ts
  constant DEFAULT_SETTINGS (line 4) | const DEFAULT_SETTINGS: Record<string, unknown> = {}
  constant REQUIRED_SETTINGS (line 5) | const REQUIRED_SETTINGS: string[] = []
  type MediaFormatInfo (line 10) | interface MediaFormatInfo {
  type StreamInfo (line 26) | interface StreamInfo {
  type FrameInfo (line 42) | interface FrameInfo {
  class FfprobeTool (line 58) | class FfprobeTool extends Tool {
    method constructor (line 62) | constructor() {
    method toolName (line 75) | get toolName(): string {
    method toolkit (line 79) | get toolkit(): string {
    method description (line 83) | get description(): string {
    method getMediaFormatInfo (line 92) | async getMediaFormatInfo(filePath: string): Promise<MediaFormatInfo> {
    method listStreams (line 135) | async listStreams(filePath: string): Promise<StreamInfo[]> {
    method getVideoSteamInfo (line 179) | async getVideoSteamInfo(filePath: string): Promise<StreamInfo[]> {
    method getAudioStreamInfo (line 195) | async getAudioStreamInfo(filePath: string): Promise<StreamInfo[]> {
    method countFrames (line 211) | async countFrames(filePath: string): Promise<number> {
    method getFramesInfo (line 271) | async getFramesInfo(filePath: string): Promise<FrameInfo[]> {
    method getDuration (line 319) | async getDuration(filePath: string): Promise<number> {

FILE: bridges/nodejs/src/sdk/tools/grok/grok-tool.ts
  constant GROK_API_KEY (line 11) | const GROK_API_KEY: string | null = null
  constant GROK_MODEL (line 12) | const GROK_MODEL = 'grok-4-1-fast-reasoning'
  constant DEFAULT_SETTINGS (line 13) | const DEFAULT_SETTINGS: Record<string, unknown> = {
  constant REQUIRED_SETTINGS (line 17) | const REQUIRED_SETTINGS = ['GROK_API_KEY']
  type GrokMessage (line 19) | interface GrokMessage {
  type WebSearchTool (line 25) | interface WebSearchTool {
  type XSearchTool (line 32) | interface XSearchTool {
  type GrokChatOptions (line 42) | interface GrokChatOptions {
  type Annotation (line 51) | interface Annotation {
  type ContentItem (line 59) | interface ContentItem {
  type MessageOutput (line 66) | interface MessageOutput {
  type ToolCallOutput (line 74) | interface ToolCallOutput {
  type OutputItem (line 86) | type OutputItem = MessageOutput | ToolCallOutput
  type GrokResponse (line 88) | interface GrokResponse {
  class GrokTool (line 108) | class GrokTool extends Tool {
    method constructor (line 115) | constructor() {
    method toolName (line 133) | get toolName(): string {
    method toolkit (line 137) | get toolkit(): string {
    method description (line 141) | get description(): string {
    method setApiKey (line 148) | setApiKey(apiKey: string): void {
    method listModels (line 156) | async listModels(): Promise<{
    method chatCompletion (line 210) | async chatCompletion(
    method searchWeb (line 316) | async searchWeb(
    method searchX (line 347) | async searchX(
    method search (line 381) | async search(
    method deepResearch (line 433) | async deepResearch(
    method getTrendingOnX (line 468) | async getTrendingOnX(

FILE: bridges/nodejs/src/sdk/tools/memory/memory-tool.ts
  constant QMD_INDEX_NAME (line 42) | const QMD_INDEX_NAME = 'leon-memory'
  constant DEFAULT_TOP_K (line 43) | const DEFAULT_TOP_K = 12
  constant DEFAULT_TOKEN_BUDGET (line 44) | const DEFAULT_TOKEN_BUDGET = 480
  constant CONTEXT_FULL_CONTENT_CAP (line 45) | const CONTEXT_FULL_CONTENT_CAP = 8_000
  constant BRIDGE_SOURCE_CONTENT_CAP (line 46) | const BRIDGE_SOURCE_CONTENT_CAP = 96_000
  constant MIN_HIT_TOKEN_BUDGET (line 47) | const MIN_HIT_TOKEN_BUDGET = 48
  constant INDEX_UPDATE_MIN_INTERVAL_MS (line 48) | const INDEX_UPDATE_MIN_INTERVAL_MS = 10_000
  type MemoryScope (line 50) | type MemoryScope = 'persistent' | 'daily' | 'discussion'
  type MemoryKind (line 51) | type MemoryKind =
  type MemorySourceType (line 59) | type MemorySourceType =
  type KnowledgeNamespace (line 65) | type KnowledgeNamespace =
  type MemoryReadOptions (line 72) | interface MemoryReadOptions {
  type MemoryWriteOptions (line 81) | interface MemoryWriteOptions {
  type QMDHit (line 96) | interface QMDHit {
  constant ROOT_DIR (line 105) | const ROOT_DIR = process.cwd()
  constant MEMORY_ROOT (line 106) | const MEMORY_ROOT = path.join(ROOT_DIR, 'core', 'memory')
  constant MEMORY_DB_PATH (line 107) | const MEMORY_DB_PATH = path.join(MEMORY_ROOT, 'index.sqlite')
  constant CONTEXT_PATH (line 108) | const CONTEXT_PATH = path.join(ROOT_DIR, 'core', 'context')
  constant MEMORY_PERSISTENT_PATH (line 109) | const MEMORY_PERSISTENT_PATH = path.join(MEMORY_ROOT, 'persistent')
  constant MEMORY_DAILY_PATH (line 110) | const MEMORY_DAILY_PATH = path.join(MEMORY_ROOT, 'daily')
  constant MEMORY_DISCUSSION_PATH (line 111) | const MEMORY_DISCUSSION_PATH = path.join(MEMORY_ROOT, 'discussion')
  constant MEMORY_SCHEMA_PATH (line 112) | const MEMORY_SCHEMA_PATH = path.join(
  type QMDSearchMode (line 122) | type QMDSearchMode = 'query' | 'search'
  constant COLLECTIONS (line 124) | const COLLECTIONS: Record<KnowledgeNamespace, { name: string, dir: strin...
  constant SDK_COLLECTIONS (line 147) | const SDK_COLLECTIONS: QMDCollectionDefinition[] = [
  function toFactKeySegment (line 154) | function toFactKeySegment(value: string): string {
  function toDayKey (line 163) | function toDayKey(timestamp: number): string {
  function clipWithTokenBudget (line 167) | function clipWithTokenBudget(
  class MemoryTool (line 195) | class MemoryTool extends Tool {
    method constructor (line 204) | constructor() {
    method toolName (line 216) | get toolName(): string {
    method toolkit (line 220) | get toolkit(): string {
    method description (line 224) | get description(): string {
    method read (line 228) | public async read(
    method write (line 758) | public async write(
    method normalizePositiveInt (line 897) | private normalizePositiveInt(value: unknown, fallback: number): number {
    method normalizeScope (line 905) | private normalizeScope(value: unknown): MemoryScope {
    method normalizeKind (line 912) | private normalizeKind(value: unknown): MemoryKind {
    method normalizeSourceType (line 925) | private normalizeSourceType(value: unknown): MemorySourceType {
    method buildStructuredFactRecord (line 938) | private buildStructuredFactRecord(input: {
    method normalizeScore (line 977) | private normalizeScore(value: unknown, fallback: number): number {
    method normalizeNamespaces (line 986) | private normalizeNamespaces(
    method getDb (line 1014) | private getDb(): SQLiteDatabase {
    method ensureStorage (line 1022) | private async ensureStorage(): Promise<void> {
    method ensureCollections (line 1044) | private async ensureCollections(): Promise<void> {
    method updateIndex (line 1059) | private async updateIndex(): Promise<void> {
    method runSearchMode (line 1086) | private async runSearchMode(
    method readFacts (line 1115) | private readFacts(limit: number): Array<{ key: string, text: string }> {
    method upsertFact (line 1133) | private upsertFact(input: {
    method writeMarkdownMirror (line 1191) | private async writeMarkdownMirror(input: {
    method dispose (line 1240) | public static dispose(): void {

FILE: bridges/nodejs/src/sdk/tools/memory/qmd-embed-worker.mjs
  function writeDiagnostics (line 8) | async function writeDiagnostics(partial) {
  function reportFatal (line 37) | async function reportFatal(kind, error) {

FILE: bridges/nodejs/src/sdk/tools/memory/qmd-retrieval.ts
  type QMDCollectionSpec (line 5) | interface QMDCollectionSpec {
  type RetrievedHit (line 10) | interface RetrievedHit<TNamespace extends string = string> {
  type RankedRetrievedHit (line 19) | interface RankedRetrievedHit<TNamespace extends string = string> {
  constant DEFAULT_QMD_NAMESPACE_WEIGHTS (line 25) | const DEFAULT_QMD_NAMESPACE_WEIGHTS = {
  function normalizeContent (line 33) | function normalizeContent(content: string): string {
  function normalizeFilename (line 37) | function normalizeFilename(filePath: string): string {
  function normalizePath (line 41) | function normalizePath(value: string): string {
  function resolveRequestedCollectionName (line 57) | function resolveRequestedCollectionName(
  function tokenizeQuery (line 73) | function tokenizeQuery(value: string): string[] {
  function tokenLength (line 84) | function tokenLength(token: string): number {
  function sanitizeQmdQueryLine (line 88) | function sanitizeQmdQueryLine(value: string): string {
  function dedupeStable (line 95) | function dedupeStable(values: string[]): string[] {
  function trimDoubledConsonant (line 99) | function trimDoubledConsonant(value: string): string {
  function restoreTrailingE (line 105) | function restoreTrailingE(value: string): string {
  function buildTokenVariants (line 113) | function buildTokenVariants(token: string): string[] {
  function splitQuerySegments (line 167) | function splitQuerySegments(value: string): string[] {
  function normalizeSegmentTerms (line 174) | function normalizeSegmentTerms(value: string): string {
  function buildExpansionQuery (line 188) | function buildExpansionQuery(
  function buildLexicalSearchQuery (line 228) | function buildLexicalSearchQuery(
  function parsePendingEmbeddingCount (line 245) | function parsePendingEmbeddingCount(statusOutput: string): number {
  function parseRows (line 255) | function parseRows(raw: string): Array<Record<string, unknown>> {
  function pickStringDeep (line 298) | function pickStringDeep(
  function pickNumberDeep (line 339) | function pickNumberDeep(
  function extractContent (line 386) | function extractContent(row: Record<string, unknown>): string {
  function extractScore (line 434) | function extractScore(row: Record<string, unknown>): number {
  function buildHitText (line 453) | function buildHitText<TNamespace extends string>(
  function canHydrateBridgeSource (line 460) | function canHydrateBridgeSource(namespace: string): boolean {
  function canBacktrackTemporalSource (line 469) | function canBacktrackTemporalSource(namespace: string): boolean {
  function buildQmdSourcePath (line 477) | function buildQmdSourcePath(collectionName: string, relativePath: string...
  function isLikelyPersistentMetadataLine (line 481) | function isLikelyPersistentMetadataLine(line: string): boolean {
  function buildSemanticLines (line 504) | function buildSemanticLines<TNamespace extends string>(
  function computeQuestionPenalty (line 524) | function computeQuestionPenalty<TNamespace extends string>(
  function focusCandidateTextAroundQuery (line 547) | function focusCandidateTextAroundQuery(
  function buildQueryTokenSet (line 578) | function buildQueryTokenSet(query: string): Set<string> {
  function buildRankingContent (line 591) | function buildRankingContent<TNamespace extends string>(
  function buildRankingHitText (line 606) | function buildRankingHitText<TNamespace extends string>(
  function extractOverlapCount (line 620) | function extractOverlapCount<TNamespace extends string>(
  function buildAdaptiveQueryTokenSet (line 648) | function buildAdaptiveQueryTokenSet<TNamespace extends string>(
  function computeLexicalBoost (line 691) | function computeLexicalBoost<TNamespace extends string>(
  function computeRecencyBoost (line 724) | function computeRecencyBoost<TNamespace extends string>(
  function rankRetrievedHits (line 758) | function rankRetrievedHits<TNamespace extends string>(
  function clipBridgeSourceContent (line 811) | function clipBridgeSourceContent(content: string, maxChars: number): str...
  function resolveBridgeSourceFilePath (line 820) | function resolveBridgeSourceFilePath<TNamespace extends string>(
  function readBridgeSourceContent (line 866) | function readBridgeSourceContent(sourceFilePath: string): string {
  function hydrateBridgeSeedHit (line 876) | function hydrateBridgeSeedHit<TNamespace extends string>(
  function buildBridgeCandidateTexts (line 906) | function buildBridgeCandidateTexts<TNamespace extends string>(
  function isInformativeBridgeToken (line 962) | function isInformativeBridgeToken(token: string, queryTokens: Set<string...
  function buildBridgeQueryTokens (line 970) | function buildBridgeQueryTokens<TNamespace extends string>(
  function buildHydratedRescueBridgeTokens (line 1061) | function buildHydratedRescueBridgeTokens<TNamespace extends string>(
  function buildBacktrackTemporalHits (line 1097) | function buildBacktrackTemporalHits<TNamespace extends string>(
  function buildHydratedBacktrackCandidates (line 1168) | function buildHydratedBacktrackCandidates<TNamespace extends string>(
  function shouldRunAdaptiveSecondPass (line 1246) | function shouldRunAdaptiveSecondPass<TNamespace extends string>(
  function buildDiscriminativeSecondPass (line 1289) | function buildDiscriminativeSecondPass<TNamespace extends string>(
  function buildFinalSupportTokens (line 1327) | function buildFinalSupportTokens<TNamespace extends string>(
  function buildSupportTokensFromHits (line 1357) | function buildSupportTokensFromHits<TNamespace extends string>(
  function buildFocusedHitContent (line 1394) | function buildFocusedHitContent<TNamespace extends string>(

FILE: bridges/nodejs/src/sdk/tools/memory/qmd-store.ts
  type QMDCollectionDefinition (line 18) | interface QMDCollectionDefinition {
  type QMDSearchMode (line 24) | type QMDSearchMode = 'query' | 'search'
  type QMDStoreRow (line 26) | type QMDStoreRow = Record<string, unknown>
  class QMDWriteLockTimeoutError (line 28) | class QMDWriteLockTimeoutError extends Error {
    method constructor (line 29) | public constructor(operation: string, lockPath: string) {
  constant DEFAULT_PATTERN (line 35) | const DEFAULT_PATTERN = '**/*.md'
  constant QMD_WRITE_LOCK_RETRY_MS (line 38) | const QMD_WRITE_LOCK_RETRY_MS = 250
  constant QMD_WRITE_LOCK_TIMEOUT_MS (line 39) | const QMD_WRITE_LOCK_TIMEOUT_MS = 60_000
  constant QMD_WRITE_LOCK_STALE_MS (line 40) | const QMD_WRITE_LOCK_STALE_MS = 15 * 60 * 1_000
  constant QMD_EMBED_SUBPROCESS_TIMEOUT_MS (line 41) | const QMD_EMBED_SUBPROCESS_TIMEOUT_MS = 15 * 60 * 1_000
  constant QMD_EMBED_SUBPROCESS_MAX_BUFFER (line 42) | const QMD_EMBED_SUBPROCESS_MAX_BUFFER = 4 * 1024 * 1024
  constant QMD_EMBED_WORKER_PATH (line 45) | const QMD_EMBED_WORKER_PATH = path.join(
  type QMDEmbedWorkerDiagnostics (line 50) | interface QMDEmbedWorkerDiagnostics {
  function wait (line 68) | function wait(ms: number): Promise<void> {
  function getQMDDbPath (line 72) | function getQMDDbPath(indexName: string): string {
  function getQMDWriteLockPath (line 80) | function getQMDWriteLockPath(indexName: string): string {
  function buildStoreConfig (line 84) | function buildStoreConfig(
  function ensureCollectionDirectories (line 100) | async function ensureCollectionDirectories(
  function ensureStoreRoot (line 109) | async function ensureStoreRoot(indexName: string): Promise<void> {
  function applyStoreDbPragmas (line 115) | function applyStoreDbPragmas(store: QMDStore): void {
  function storeHasRequiredCollections (line 128) | async function storeHasRequiredCollections(
  function closeStoreQuietly (line 152) | async function closeStoreQuietly(store: QMDStore | null): Promise<void> {
  function maybeClearStaleWriteLock (line 164) | async function maybeClearStaleWriteLock(lockPath: string): Promise<boole...
  function acquireQMDWriteLock (line 178) | async function acquireQMDWriteLock(
  function withQMDWriteLock (line 224) | async function withQMDWriteLock<T>(
  function openExistingStore (line 252) | async function openExistingStore(indexName: string): Promise<QMDStore> {
  function runQMDStoreEmbedInSubprocess (line 260) | async function runQMDStoreEmbedInSubprocess(params: {
  function openConfiguredStore (line 354) | async function openConfiguredStore(
  function inferCollectionName (line 366) | function inferCollectionName(
  function toStoreRow (line 379) | function toStoreRow(result: SearchResult | HybridQueryResult): QMDStoreR...
  function getQMDStore (line 410) | async function getQMDStore(
  function runQMDStoreSearch (line 461) | async function runQMDStoreSearch(params: {
  function updateQMDStore (line 503) | async function updateQMDStore(params: {
  function getQMDStoreStatus (line 519) | async function getQMDStoreStatus(params: {
  function embedQMDStore (line 527) | async function embedQMDStore(params: {
  function closeQMDStore (line 541) | async function closeQMDStore(indexName: string): Promise<void> {

FILE: bridges/nodejs/src/sdk/tools/open-meteo/open-meteo-tool.ts
  constant DEFAULT_SETTINGS (line 5) | const DEFAULT_SETTINGS: Record<string, unknown> = {}
  constant REQUIRED_SETTINGS (line 6) | const REQUIRED_SETTINGS: string[] = []
  type GeocodingResult (line 8) | interface GeocodingResult {
  type GeocodingResponse (line 17) | interface GeocodingResponse {
  type CurrentWeather (line 21) | interface CurrentWeather {
  type HourlyWeather (line 31) | interface HourlyWeather {
  type WeatherResponse (line 41) | interface WeatherResponse {
  type WeatherConditions (line 56) | interface WeatherConditions {
  type WeatherResponseResult (line 70) | interface WeatherResponseResult {
  constant WMO_CODE_DESCRIPTIONS (line 77) | const WMO_CODE_DESCRIPTIONS: Record<number, string> = {
  constant WIND_DIRECTIONS (line 108) | const WIND_DIRECTIONS = [
  function degreesToCompass (line 127) | function degreesToCompass(degrees: number): string {
  function celsiusToFahrenheit (line 132) | function celsiusToFahrenheit(celsius: number): string {
  function getWeatherDescription (line 136) | function getWeatherDescription(code: number): string {
  function mapHourlyToCurrent (line 140) | function mapHourlyToCurrent(hourly: HourlyWeather): CurrentWeather | null {
  class OpenMeteoTool (line 178) | class OpenMeteoTool extends Tool {
    method constructor (line 184) | constructor() {
    method toolName (line 201) | get toolName(): string {
    method toolkit (line 205) | get toolkit(): string {
    method description (line 209) | get description(): string {
    method getCurrentConditions (line 213) | async getCurrentConditions(
    method geocode (line 282) | private async geocode(location: string): Promise<{
    method fetchWeather (line 314) | private async fetchWeather(

FILE: bridges/nodejs/src/sdk/tools/openai_audio/openai_audio-tool.ts
  constant OPENAI_AUDIO_API_KEY (line 11) | const OPENAI_AUDIO_API_KEY: string | null = null
  constant OPENAI_AUDIO_MODEL (line 12) | const OPENAI_AUDIO_MODEL = 'whisper-1'
  constant DEFAULT_SETTINGS (line 13) | const DEFAULT_SETTINGS: Record<string, unknown> = {
  constant REQUIRED_SETTINGS (line 17) | const REQUIRED_SETTINGS = ['OPENAI_AUDIO_API_KEY']
  type OpenAITranscriptionOutput (line 19) | interface OpenAITranscriptionOutput {
  class OpenAIAudioTool (line 37) | class OpenAIAudioTool extends Tool {
    method constructor (line 43) | constructor() {
    method toolName (line 63) | get toolName(): string {
    method toolkit (line 68) | get toolkit(): string {
    method description (line 72) | get description(): string {
    method transcribeToFile (line 83) | async transcribeToFile(
    method parseTranscription (line 129) | private parseTranscription(

FILE: bridges/nodejs/src/sdk/tools/opencode/opencode-tool.ts
  constant OPENCODE_OPENROUTER_API_KEY (line 9) | const OPENCODE_OPENROUTER_API_KEY: string | null = null
  constant OPENCODE_OPENROUTER_MODEL (line 10) | const OPENCODE_OPENROUTER_MODEL = 'openrouter/openai/gpt-5.2-codex'
  constant DEFAULT_SETTINGS (line 11) | const DEFAULT_SETTINGS: Record<string, unknown> = {
  constant REQUIRED_SETTINGS (line 15) | const REQUIRED_SETTINGS = ['OPENCODE_OPENROUTER_API_KEY']
  constant OPENCODE_CONFIG_CONTENT (line 16) | const OPENCODE_CONFIG_CONTENT = {
  type OpenCodeProvider (line 28) | interface OpenCodeProvider {
  type GenerateSkillOptions (line 34) | interface GenerateSkillOptions {
  type OpenCodeResult (line 46) | interface OpenCodeResult {
  class OpenCodeTool (line 57) | class OpenCodeTool extends Tool {
    method constructor (line 70) | constructor() {
    method loadProvidersFromSettings (line 103) | private loadProvidersFromSettings(
    method toolName (line 139) | get toolName(): string {
    method toolkit (line 143) | get toolkit(): string {
    method description (line 147) | get description(): string {
    method configureProvider (line 154) | configureProvider(provider: string, apiKey: string, model?: string): v...
    method getConfiguredProviders (line 172) | getConfiguredProviders(): string[] {
    method getAvailableProviders (line 179) | getAvailableProviders(): string[] {
    method getDefaultModel (line 186) | getDefaultModel(provider: string): string {
    method setupProviderAuth (line 200) | private async setupProviderAuth(
    method generateSkill (line 233) | async generateSkill(options: GenerateSkillOptions): Promise<OpenCodeRe...
    method getExistingSkills (line 329) | private async getExistingSkills(skillsDir: string): Promise<Set<string...
    method getCreatedFiles (line 346) | private async getCreatedFiles(
    method getAllFilesRecursive (line 374) | private async getAllFilesRecursive(dir: string): Promise<string[]> {
    method analyzeRelevantToolkits (line 395) | private async analyzeRelevantToolkits(
    method scanAvailableToolkits (line 461) | private async scanAvailableToolkits(
    method toPascalCase (line 548) | private toPascalCase(str: string): string {
    method parseAuroraInterface (line 558) | private async parseAuroraInterface(componentName: string): Promise<str...
    method scanAuroraComponents (line 637) | private async scanAuroraComponents(): Promise<string> {
    method getToolCreationGuidelines (line 707) | private getToolCreationGuidelines(bridge: 'nodejs' | 'python'): string {
    method getToolMethods (line 857) | private async getToolMethods(toolName: string): Promise<
    method buildLeonContext (line 955) | private async buildLeonContext(
    method loadPromptTemplate (line 1011) | private async loadPromptTemplate(): Promise<string> {
    method applyTemplate (line 1016) | private applyTemplate(
    method buildBridgeSpecificGuidelines (line 1028) | private buildBridgeSpecificGuidelines(
    method buildSettingsUsageExample (line 1055) | private buildSettingsUsageExample(bridge: 'nodejs' | 'python'): string {
    method buildBatchProcessingExample (line 1105) | private buildBatchProcessingExample(bridge: 'nodejs' | 'python'): stri...
    method buildLeonAnswerBasicExample (line 1154) | private buildLeonAnswerBasicExample(bridge: 'nodejs' | 'python'): stri...
    method buildContextDataExample (line 1184) | private buildContextDataExample(bridge: 'nodejs' | 'python'): string {
    method buildActionParamsExample (line 1232) | private buildActionParamsExample(bridge: 'nodejs' | 'python'): string {
    method buildReferenceFilesSection (line 1270) | private async buildReferenceFilesSection(
    method buildRepoSnapshot (line 1285) | private async buildRepoSnapshot(contextFiles: string[]): Promise<strin...
    method formatSnapshotDate (line 1334) | private formatSnapshotDate(value: number | null): string {
    method getLatestMtime (line 1338) | private async getLatestMtime(dirPath: string): Promise<number | null> {
    method getContextFileSnapshot (line 1357) | private async getContextFileSnapshot(
    method buildLeonContextLegacy (line 1375) | private async buildLeonContextLegacy(

FILE: bridges/nodejs/src/sdk/tools/openrouter/openrouter-tool.ts
  constant OPENROUTER_API_KEY (line 6) | const OPENROUTER_API_KEY: string | null = null
  constant OPENROUTER_MODEL (line 7) | const OPENROUTER_MODEL = 'google/gemini-3-flash-preview'
  constant DEFAULT_SETTINGS (line 8) | const DEFAULT_SETTINGS: Record<string, unknown> = {
  constant REQUIRED_SETTINGS (line 12) | const REQUIRED_SETTINGS = ['OPENROUTER_API_KEY']
  type ChatMessage (line 14) | interface ChatMessage {
  type ChatCompletionOptions (line 19) | interface ChatCompletionOptions {
  type CompletionOptions (line 30) | interface CompletionOptions {
  type StructuredCompletionOptions (line 41) | interface StructuredCompletionOptions {
  type ApiResponse (line 51) | interface ApiResponse {
  class OpenRouterTool (line 60) | class OpenRouterTool extends Tool {
    method constructor (line 67) | constructor(apiKey?: string) {
    method toolName (line 94) | get toolName(): string {
    method toolkit (line 98) | get toolkit(): string {
    method description (line 102) | get description(): string {
    method setApiKey (line 109) | setApiKey(apiKey: string): void {
    method chatCompletion (line 116) | async chatCompletion(options: ChatCompletionOptions): Promise<ApiRespo...
    method completion (line 198) | async completion(options: CompletionOptions): Promise<ApiResponse> {
    method structuredCompletion (line 245) | async structuredCompletion(
    method listModels (line 311) | async listModels(): Promise<ApiResponse> {

FILE: bridges/nodejs/src/sdk/tools/qwen3_asr/qwen3_asr-tool.ts
  type Qwen3ASRTranscriptionOutput (line 10) | type Qwen3ASRTranscriptionOutput = string
  constant MODEL_NAME (line 12) | const MODEL_NAME = 'qwen3-asr-1.7b'
  constant FORCED_ALIGNER_MODEL_NAME (line 13) | const FORCED_ALIGNER_MODEL_NAME = 'qwen3-forcedaligner-0.6b'
  constant DEFAULT_SETTINGS (line 14) | const DEFAULT_SETTINGS: Record<string, unknown> = {}
  constant REQUIRED_SETTINGS (line 15) | const REQUIRED_SETTINGS: string[] = []
  type Qwen3ASRTask (line 17) | interface Qwen3ASRTask {
  class Qwen3ASRTool (line 22) | class Qwen3ASRTool extends Tool {
    method constructor (line 26) | constructor() {
    method toolName (line 40) | get toolName(): string {
    method toolkit (line 45) | get toolkit(): string {
    method description (line 49) | get description(): string {
    method transcribeToFile (line 68) | async transcribeToFile(
    method parseTranscription (line 170) | private parseTranscription(

FILE: bridges/nodejs/src/sdk/tools/qwen3_tts/qwen3_tts-tool.ts
  constant MODEL_BASE_NAME (line 9) | const MODEL_BASE_NAME = 'Qwen3-TTS-12Hz-1.7B-Base'
  constant MODEL_DESIGN_NAME (line 10) | const MODEL_DESIGN_NAME = 'Qwen3-TTS-12Hz-1.7B-VoiceDesign'
  constant MODEL_CUSTOM_NAME (line 11) | const MODEL_CUSTOM_NAME = 'Qwen3-TTS-12Hz-1.7B-CustomVoice'
  constant DEFAULT_SETTINGS (line 12) | const DEFAULT_SETTINGS: Record<string, unknown> = {}
  constant REQUIRED_SETTINGS (line 13) | const REQUIRED_SETTINGS: string[] = []
  type SupportedLanguage (line 15) | type SupportedLanguage =
  type SynthesizeSpeechTask (line 28) | interface SynthesizeSpeechTask {
  type DesignVoiceTask (line 51) | interface DesignVoiceTask {
  type CustomVoiceTask (line 71) | interface CustomVoiceTask {
  type DesignThenSynthesizeTask (line 106) | interface DesignThenSynthesizeTask {
  class Qwen3TTSTool (line 136) | class Qwen3TTSTool extends Tool {
    method constructor (line 140) | constructor() {
    method toolName (line 154) | get toolName(): string {
    method toolkit (line 159) | get toolkit(): string {
    method description (line 163) | get description(): string {
    method synthesizeSpeech (line 170) | async synthesizeSpeech(
    method designVoice (line 189) | async designVoice(
    method customVoice (line 208) | async customVoice(
    method designThenSynthesize (line 227) | async designThenSynthesize(
    method resolveResourceRoot (line 243) | private async resolveResourceRoot(modelNames: string[]): Promise<strin...
    method runTasks (line 260) | private async runTasks<T extends Record<string, unknown>>(

FILE: bridges/nodejs/src/sdk/tools/transcription-schema.ts
  type TranscriptionSegment (line 1) | interface TranscriptionSegment {
  type TranscriptionOutput (line 15) | interface TranscriptionOutput {

FILE: bridges/nodejs/src/sdk/tools/ultimate_vocal_remover_onnx/ultimate_vocal_remover_onnx-tool.ts
  constant MODEL_NAME (line 10) | const MODEL_NAME = 'ultimate-vocal-remover-onnx'
  constant DEFAULT_SETTINGS (line 11) | const DEFAULT_SETTINGS: Record<string, unknown> = {}
  constant REQUIRED_SETTINGS (line 12) | const REQUIRED_SETTINGS: string[] = []
  type VocalSeparationTask (line 14) | interface VocalSeparationTask {
  class UltimateVocalRemoverONNXTool (line 21) | class UltimateVocalRemoverONNXTool extends Tool {
    method constructor (line 25) | constructor() {
    method toolName (line 42) | get toolName(): string {
    method toolkit (line 47) | get toolkit(): string {
    method description (line 51) | get description(): string {
    method separateVocals (line 61) | async separateVocals(

FILE: bridges/nodejs/src/sdk/tools/ytdlp/ytdlp-tool.ts
  constant DEFAULT_SETTINGS (line 7) | const DEFAULT_SETTINGS: Record<string, unknown> = {}
  constant REQUIRED_SETTINGS (line 8) | const REQUIRED_SETTINGS: string[] = []
  class YtdlpTool (line 10) | class YtdlpTool extends Tool {
    method constructor (line 14) | constructor() {
    method toolName (line 29) | get toolName(): string {
    method toolkit (line 33) | get toolkit(): string {
    method description (line 37) | get description(): string {
    method getConfigArgs (line 41) | private getConfigArgs(): string[] {
    method downloadVideo (line 52) | async downloadVideo(videoUrl: string, outputPath: string): Promise<str...
    method downloadAudioOnly (line 94) | async downloadAudioOnly(
    method downloadPlaylist (line 147) | async downloadPlaylist(
    method downloadVideoByQuality (line 180) | async downloadVideoByQuality(
    method downloadSubtitles (line 290) | async downloadSubtitles(
    method downloadVideoWithThumbnail (line 333) | async downloadVideoWithThumbnail(

FILE: bridges/nodejs/src/sdk/types.ts
  type ActionFunction (line 19) | type ActionFunction = (
  type Answer (line 27) | interface Answer {
  type TextAnswer (line 34) | interface TextAnswer extends Answer {
  type WidgetAnswer (line 37) | interface WidgetAnswer extends Answer {
  type AnswerData (line 41) | type AnswerData = Record<string, string | number> | null
  type AnswerInput (line 42) | type AnswerInput = TextAnswer | WidgetAnswer | Answer
  type AnswerOutput (line 43) | type AnswerOutput = SkillAnswerOutput
  type AnswerConfig (line 44) | type AnswerConfig = SkillAnswerConfigSchema

FILE: bridges/nodejs/src/sdk/utils.ts
  constant HUGGING_FACE_URL (line 8) | const HUGGING_FACE_URL = 'https://huggingface.co'
  constant HUGGING_FACE_MIRROR_URL (line 9) | const HUGGING_FACE_MIRROR_URL = 'https://hf-mirror.com'
  function formatFilePath (line 17) | function formatFilePath(filePath: string): string {
  function formatFilePaths (line 27) | function formatFilePaths(filePaths: string[]): string {
  function getPlatformName (line 40) | function getPlatformName(): string {
  function isWindows (line 75) | function isWindows(): boolean {
  function isMacOS (line 84) | function isMacOS(): boolean {
  function isLinux (line 93) | function isLinux(): boolean {
  function canAccessHuggingFace (line 101) | async function canAccessHuggingFace(): Promise<boolean> {
  function setHuggingFaceURL (line 116) | async function setHuggingFaceURL(url: string): Promise<string> {
  function formatBytes (line 137) | function formatBytes(bytes: number): string {
  function formatSpeed (line 156) | function formatSpeed(speed: string | number): string {
  function formatETA (line 181) | function formatETA(eta: string | number): string {
  function extractArchive (line 217) | async function extractArchive(

FILE: bridges/nodejs/src/sdk/widget-component.ts
  type SupportedWidgetEvent (line 1) | type SupportedWidgetEvent = (typeof SUPPORTED_WIDGET_EVENTS)[number]
  type WidgetEvent (line 2) | interface WidgetEvent {
  constant SUPPORTED_WIDGET_EVENTS (line 7) | const SUPPORTED_WIDGET_EVENTS = [
  function generateId (line 15) | function generateId(): string {
  method constructor (line 25) | protected constructor(props: T) {
  method parseEvents (line 32) | private parseEvents(): WidgetEvent[] {

FILE: bridges/nodejs/src/sdk/widget.ts
  type UtteranceSender (line 6) | type UtteranceSender = 'leon' | 'owner'
  type SendUtteranceWidgetEventMethodParams (line 8) | interface SendUtteranceWidgetEventMethodParams {
  type RunSkillActionWidgetEventMethodParams (line 12) | interface RunSkillActionWidgetEventMethodParams {
  type SendUtteranceOptions (line 16) | interface SendUtteranceOptions {
  type WidgetEventMethod (line 21) | interface WidgetEventMethod {
  type WidgetOptions (line 27) | interface WidgetOptions<T = unknown> {
  method constructor (line 44) | protected constructor(options: WidgetOptions<T>) {
  method sendUtterance (line 75) | protected sendUtterance(
  method runSkillAction (line 97) | protected runSkillAction(
  method content (line 117) | protected content(key: string, data?: Record<string, unknown>): string {

FILE: bridges/nodejs/src/tool-runtime.ts
  type ToolRuntimeCliInput (line 11) | interface ToolRuntimeCliInput {

FILE: bridges/nodejs/src/version.ts
  constant VERSION (line 1) | const VERSION = '1.3.0'

FILE: bridges/python/src/main.py
  function main (line 10) | def main():

FILE: bridges/python/src/sdk/aurora/button.py
  class Button (line 4) | class Button(WidgetComponent[dict]):
    method __init__ (line 5) | def __init__(self, props: dict):

FILE: bridges/python/src/sdk/aurora/card.py
  class Card (line 4) | class Card(WidgetComponent[dict]):
    method __init__ (line 5) | def __init__(self, props: dict):

FILE: bridges/python/src/sdk/aurora/checkbox.py
  class Checkbox (line 4) | class Checkbox(WidgetComponent[dict]):
    method __init__ (line 5) | def __init__(self, props: dict):

FILE: bridges/python/src/sdk/aurora/circular_progress.py
  class CircularProgress (line 4) | class CircularProgress(WidgetComponent[dict]):
    method __init__ (line 5) | def __init__(self, props: dict):

FILE: bridges/python/src/sdk/aurora/flexbox.py
  class Flexbox (line 4) | class Flexbox(WidgetComponent[dict]):
    method __init__ (line 5) | def __init__(self, props: dict):

FILE: bridges/python/src/sdk/aurora/form.py
  class Form (line 4) | class Form(WidgetComponent[dict]):
    method __init__ (line 5) | def __init__(self, props: dict):

FILE: bridges/python/src/sdk/aurora/icon.py
  class Icon (line 4) | class Icon(WidgetComponent[dict]):
    method __init__ (line 5) | def __init__(self, props: dict):

FILE: bridges/python/src/sdk/aurora/icon_button.py
  class IconButton (line 4) | class IconButton(WidgetComponent[dict]):
    method __init__ (line 5) | def __init__(self, props: dict):

FILE: bridges/python/src/sdk/aurora/image.py
  class Image (line 4) | class Image(WidgetComponent[dict]):
    method __init__ (line 5) | def __init__(self, props: dict):

FILE: bridges/python/src/sdk/aurora/input.py
  class Input (line 4) | class Input(WidgetComponent[dict]):
    method __init__ (line 5) | def __init__(self, props: dict):

FILE: bridges/python/src/sdk/aurora/link.py
  class Link (line 4) | class Link(WidgetComponent[dict]):
    method __init__ (line 5) | def __init__(self, props: dict):

FILE: bridges/python/src/sdk/aurora/list.py
  class List (line 4) | class List(WidgetComponent[dict]):
    method __init__ (line 5) | def __init__(self, props: dict):

FILE: bridges/python/src/sdk/aurora/list_header.py
  class ListHeader (line 4) | class ListHeader(WidgetComponent[dict]):
    method __init__ (line 5) | def __init__(self, props: dict):

FILE: bridges/python/src/sdk/aurora/list_item.py
  class ListItem (line 4) | class ListItem(WidgetComponent[dict]):
    method __init__ (line 5) | def __init__(self, props: dict):

FILE: bridges/python/src/sdk/aurora/loader.py
  class Loader (line 4) | class Loader(WidgetComponent[dict]):
    method __init__ (line 5) | def __init__(self, props: dict):

FILE: bridges/python/src/sdk/aurora/progress.py
  class Progress (line 4) | class Progress(WidgetComponent[dict]):
    method __init__ (line 5) | def __init__(self, props: dict):

FILE: bridges/python/src/sdk/aurora/radio.py
  class Radio (line 4) | class Radio(WidgetComponent[dict]):
    method __init__ (line 5) | def __init__(self, props: dict):

FILE: bridges/python/src/sdk/aurora/radio_group.py
  class RadioGroup (line 4) | class RadioGroup(WidgetComponent[dict]):
    method __init__ (line 5) | def __init__(self, props: dict):

FILE: bridges/python/src/sdk/aurora/range_slider.py
  class RangeSlider (line 4) | class RangeSlider(WidgetComponent[dict]):
    method __init__ (line 5) | def __init__(self, props: dict):

FILE: bridges/python/src/sdk/aurora/scroll_container.py
  class ScrollContainer (line 4) | class ScrollContainer(WidgetComponent[dict]):
    method __init__ (line 5) | def __init__(self, props: dict):

FILE: bridges/python/src/sdk/aurora/select.py
  class Select (line 4) | class Select(WidgetComponent[dict]):
    method __init__ (line 5) | def __init__(self, props: dict):

FILE: bridges/python/src/sdk/aurora/select_option.py
  class SelectOption (line 4) | class SelectOption(WidgetComponent[dict]):
    method __init__ (line 5) | def __init__(self, props: dict):

FILE: bridges/python/src/sdk/aurora/status.py
  class Status (line 4) | class Status(WidgetComponent[dict]):
    method __init__ (line 5) | def __init__(self, props: dict):

FILE: bridges/python/src/sdk/aurora/switch.py
  class Switch (line 4) | class Switch(WidgetComponent[dict]):
    method __init__ (line 5) | def __init__(self, props: dict):

FILE: bridges/python/src/sdk/aurora/tab.py
  class Tab (line 4) | class Tab(WidgetComponent[dict]):
    method __init__ (line 5) | def __init__(self, props: dict):

FILE: bridges/python/src/sdk/aurora/tab_content.py
  class TabContent (line 4) | class TabContent(WidgetComponent[dict]):
    method __init__ (line 5) | def __init__(self, props: dict):

FILE: bridges/python/src/sdk/aurora/tab_group.py
  class TabGroup (line 4) | class TabGroup(WidgetComponent[dict]):
    method __init__ (line 5) | def __init__(self, props: dict):

FILE: bridges/python/src/sdk/aurora/tab_list.py
  class TabList (line 4) | class TabList(WidgetComponent[dict]):
    method __init__ (line 5) | def __init__(self, props: dict):

FILE: bridges/python/src/sdk/aurora/text.py
  class Text (line 4) | class Text(WidgetComponent[dict]):
    method __init__ (line 5) | def __init__(self, props: dict):

FILE: bridges/python/src/sdk/aurora/widget_wrapper.py
  class WidgetWrapper (line 4) | class WidgetWrapper(WidgetComponent[dict]):
    method __init__ (line 5) | def __init__(self, props: dict):

FILE: bridges/python/src/sdk/base_tool.py
  class ExecuteCommandOptions (line 44) | class ExecuteCommandOptions:
    method __init__ (line 45) | def __init__(
  class BaseTool (line 62) | class BaseTool(ABC):
    method __init__ (line 65) | def __init__(self):
    method tool_name (line 74) | def tool_name(self) -> str:
    method toolkit (line 80) | def toolkit(self) -> str:
    method description (line 86) | def description(self) -> str:
    method alias_tool_name (line 91) | def alias_tool_name(self) -> str:
    method _get_settings_path (line 99) | def _get_settings_path(self, tool_name: Optional[str] = None) -> str:
    method _check_required_settings (line 108) | def _check_required_settings(self, tool_name: Optional[str] = None) ->...
    method get_missing_settings (line 131) | def get_missing_settings(self) -> Optional[Dict[str, Any]]:
    method _escape_shell_arg (line 134) | def _escape_shell_arg(self, arg: str) -> str:
    method _get_tool_dir (line 160) | def _get_tool_dir(self, module_file: str) -> str:
    method _format_command_output (line 163) | def _format_command_output(self, output: str) -> Optional[str]:
    method _report_command_output (line 174) | def _report_command_output(
    method _get_bundled_library_paths (line 187) | def _get_bundled_library_paths(self) -> List[str]:
    method _get_command_env (line 195) | def _get_command_env(self) -> Dict[str, str]:
    method execute_command (line 216) | def execute_command(self, options: ExecuteCommandOptions) -> str:
    method _execute_sync_command (line 263) | def _execute_sync_command(
    method _execute_async_command (line 335) | def _execute_async_command(
    method _execute_terminal_command (line 422) | def _execute_terminal_command(
    method _build_terminal_run_command (line 487) | def _build_terminal_run_command(
    method _build_binary_command (line 501) | def _build_binary_command(self, binary_path: str, args: List[str]) -> ...
    method _launch_terminal (line 506) | def _launch_terminal(self, command: str) -> None:
    method _wait_for_marker (line 551) | def _wait_for_marker(self, marker_file: str, timeout_seconds: int) -> ...
    method _escape_applescript (line 564) | def _escape_applescript(self, value: str) -> str:
    method _escape_windows_arg (line 567) | def _escape_windows_arg(self, value: str) -> str:
    method _command_exists (line 570) | def _command_exists(self, command: str) -> bool:
    method get_binary_path (line 573) | def get_binary_path(
    method get_resource_path (line 637) | def get_resource_path(self, resource_name: str) -> str:
    method _is_resource_complete (line 776) | def _is_resource_complete(self, resource_path: str, resource_urls: lis...
    method _get_resource_relative_path (line 801) | def _get_resource_relative_path(self, resource_url: str) -> str:
    method _delete_older_binary_versions (line 821) | def _delete_older_binary_versions(
    method _download_binary_on_demand (line 884) | def _download_binary_on_demand(
    method _remove_quarantine_attribute (line 923) | def _remove_quarantine_attribute(self, file_path: str) -> None:
    method _is_archive (line 953) | def _is_archive(self, file_path: str) -> bool:
    method _download_binary (line 966) | def _download_binary(self, url: str, output_path: str) -> None:
    method log (line 1076) | def log(self, message: str, *args: Any) -> None:
    method _handle_download_progress (line 1092) | def _handle_download_progress(self, dl: "Pypdl", file_name: str) -> None:
    method report (line 1158) | def report(

FILE: bridges/python/src/sdk/leon.py
  class Leon (line 15) | class Leon:
    method __init__ (line 19) | def __init__(self) -> None:
    method _load_global_answers (line 24) | def _load_global_answers(self) -> None:
    method _inject_variables (line 39) | def _inject_variables(answer: AnswerConfig, data_to_inject: Union[Dict...
    method set_answer_data (line 55) | def set_answer_data(self, answer_key: str, data: Union[AnswerData, Non...
    method answer (line 85) | def answer(self, answer_input: AnswerInput) -> Optional[str]:

FILE: bridges/python/src/sdk/memory.py
  class MemoryOptions (line 8) | class MemoryOptions(TypedDict, total=False):
  class Memory (line 13) | class Memory:
    method __init__ (line 14) | def __init__(self, options: MemoryOptions):
    method clear (line 35) | def clear(self) -> None:
    method read (line 44) | def read(self):
    method write (line 61) | def write(self, memory):

FILE: bridges/python/src/sdk/network.py
  class NetworkOptions (line 10) | class NetworkOptions(TypedDict, total=False):
  class NetworkResponse (line 14) | class NetworkResponse(TypedDict):
  class NetworkError (line 20) | class NetworkError(Exception):
    method __init__ (line 21) | def __init__(self, response: NetworkResponse) -> None:
    method _format_error_data (line 26) | def _format_error_data(data: Any) -> str:
  class NetworkRequestOptions (line 36) | class NetworkRequestOptions(TypedDict, total=False):
  class Network (line 45) | class Network:
    method __init__ (line 46) | def __init__(self, options: NetworkOptions = {'base_url': None}) -> None:
    method request (line 49) | def request(self, options: NetworkRequestOptions) -> NetworkResponse:
    method is_network_error (line 139) | def is_network_error(self, error: Exception) -> bool:
    method is_network_available (line 142) | def is_network_available(self) -> bool:

FILE: bridges/python/src/sdk/params_helper.py
  class ParamsHelper (line 9) | class ParamsHelper:
    method __init__ (line 14) | def __init__(self, params: ActionParams):
    method get_widget_id (line 17) | def get_widget_id(self) -> Optional[str]:
    method get_action_argument (line 27) | def get_action_argument(self, name: str) -> Optional[Any]:
    method find_entity (line 36) | def find_entity(self, entity_name: str) -> Optional[NEREntity]:
    method find_last_entity (line 48) | def find_last_entity(self, entity_name: str) -> Optional[NEREntity]:
    method find_all_entities (line 61) | def find_all_entities(self, entity_name: str) -> List[NEREntity]:
    method find_action_argument_from_context (line 72) | def find_action_argument_from_context(self, name: str) -> Optional[Any]:
    method find_last_action_argument_from_context (line 86) | def find_last_action_argument_from_context(self, name: str) -> Optiona...
    method find_last_entity_from_context (line 101) | def find_last_entity_from_context(self, entity_name: str) -> Optional[...
    method find_all_entities_from_context (line 113) | def find_all_entities_from_context(self, entity_name: str) -> List[NER...
    method get_context_data (line 124) | def get_context_data(self, key: str) -> Optional[Any]:

FILE: bridges/python/src/sdk/settings.py
  class Settings (line 9) | class Settings:
    method __init__ (line 10) | def __init__(self):
    method is_setting_set (line 14) | def is_setting_set(self, key: str) -> bool:
    method clear (line 24) | def clear(self) -> None:
    method get_settings_sample (line 31) | def get_settings_sample(self) -> dict[str, Any]:
    method get (line 40) | def get(self, key: str) -> Any: ...
    method get (line 43) | def get(self, key: None = None) -> dict[str, Any]: ...
    method get (line 45) | def get(self, key: Union[str, None] = None) -> Union[dict[str, Any], A...
    method set (line 66) | def set(self, key_or_settings: dict[str, Any]) -> dict[str, Any]: ...
    method set (line 69) | def set(self, key_or_settings: str, value: Any) -> dict[str, Any]: ...
    method set (line 71) | def set(self, key_or_settings: Union[str, dict[str, Any]], value: Any ...

FILE: bridges/python/src/sdk/tool_manager.py
  class MissingToolSettingsError (line 8) | class MissingToolSettingsError(Exception):
    method __init__ (line 9) | def __init__(self, missing: list[str], settings_path: str):
  class ToolManager (line 15) | class ToolManager:
    method init_tool (line 17) | def init_tool(tool_class: Type[BaseTool]) -> BaseTool:
  function is_missing_tool_settings_error (line 45) | def is_missing_tool_settings_error(error: Exception) -> bool:

FILE: bridges/python/src/sdk/toolkit_config.py
  class ToolkitConfig (line 9) | class ToolkitConfig:
    method load (line 16) | def load(cls, toolkit_name: str, tool_name: str) -> Dict[str, Any]:
    method load_tool_settings (line 64) | def load_tool_settings(
    method get_binary_url (line 117) | def get_binary_url(cls, config: Dict[str, Any]) -> Optional[str]:

FILE: bridges/python/src/sdk/tools/assemblyai_audio/assemblyai_audio_tool.py
  class AssemblyAIAudioTool (line 18) | class AssemblyAIAudioTool(BaseTool):
    method __init__ (line 21) | def __init__(self):
    method tool_name (line 40) | def tool_name(self) -> str:
    method toolkit (line 44) | def toolkit(self) -> str:
    method description (line 48) | def description(self) -> str:
    method transcribe_to_file (line 51) | def transcribe_to_file(
    method _parse_transcription (line 155) | def _parse_transcription(self, raw_output: Dict[str, Any]) -> Transcri...

FILE: bridges/python/src/sdk/tools/bash/bash_tool.py
  class BashTool (line 43) | class BashTool(BaseTool):
    method __init__ (line 46) | def __init__(self):
    method tool_name (line 56) | def tool_name(self) -> str:
    method toolkit (line 60) | def toolkit(self) -> str:
    method description (line 64) | def description(self) -> str:
    method execute_bash_command (line 67) | def execute_bash_command(
    method is_safe_command (line 176) | def is_safe_command(self, command: str) -> bool:
    method get_command_risk_level (line 197) | def get_command_risk_level(self, command: str) -> str:
    method get_risk_description (line 225) | def get_risk_description(self, command: str) -> str:
    method _resolve_command_for_safety_analysis (line 253) | def _resolve_command_for_safety_analysis(self, command: str) -> str:
    method _is_download_piped_to_shell (line 272) | def _is_download_piped_to_shell(self, command_lower: str) -> bool:
    method _tokenize_command (line 279) | def _tokenize_command(self, command: str) -> List[str]:
    method _has_token_sequence (line 323) | def _has_token_sequence(
    method _has_command_token (line 339) | def _has_command_token(
    method _has_dangerous_dd_pattern (line 351) | def _has_dangerous_dd_pattern(self, tokens: Sequence[str]) -> bool:
    method _has_eval_download_pattern (line 357) | def _has_eval_download_pattern(self, tokens: Sequence[str]) -> bool:
    method _normalize_command_token (line 371) | def _normalize_command_token(self, token: str) -> str:
    method _has_any_token_sequence (line 377) | def _has_any_token_sequence(
    method _requires_visible_terminal (line 382) | def _requires_visible_terminal(self, command: str) -> bool:
    method _is_shell_assignment (line 438) | def _is_shell_assignment(self, token: str) -> bool:

FILE: bridges/python/src/sdk/tools/cerebras/cerebras_tool.py
  class CerebrasTool (line 18) | class CerebrasTool(BaseTool):
    method __init__ (line 23) | def __init__(self, api_key: Optional[str] = None):
    method tool_name (line 52) | def tool_name(self) -> str:
    method toolkit (line 56) | def toolkit(self) -> str:
    method description (line 60) | def description(self) -> str:
    method set_api_key (line 63) | def set_api_key(self, api_key: str) -> None:
    method get_available_models (line 67) | def get_available_models(self) -> List[str]:
    method get_model_id (line 71) | def get_model_id(self, model_name: str) -> str:
    method chat_completion (line 75) | def chat_completion(
    method completion (line 156) | def completion(
    method structured_completion (line 209) | def structured_completion(
    method list_models (line 266) | def list_models(self) -> Dict[str, Any]:

FILE: bridges/python/src/sdk/tools/chatterbox_onnx/chatterbox_onnx_tool.py
  function split_text_at_punctuation (line 18) | def split_text_at_punctuation(
  class SynthesisTask (line 78) | class SynthesisTask(TypedDict, total=False):
  class ChatterboxONNXTool (line 94) | class ChatterboxONNXTool(BaseTool):
    method __init__ (line 102) | def __init__(self):
    method tool_name (line 113) | def tool_name(self) -> str:
    method toolkit (line 118) | def toolkit(self) -> str:
    method description (line 122) | def description(self) -> str:
    method synthesize_speech_to_files (line 125) | def synthesize_speech_to_files(

FILE: bridges/python/src/sdk/tools/ecapa/ecapa_tool.py
  class ECAPATool (line 11) | class ECAPATool(BaseTool):
    method __init__ (line 21) | def __init__(self):
    method tool_name (line 32) | def tool_name(self) -> str:
    method toolkit (line 37) | def toolkit(self) -> str:
    method description (line 41) | def description(self) -> str:
    method detect_gender (line 44) | def detect_gender(self, input_path: str, device: str = "cpu") -> str:
    method _parse_gender_output (line 89) | def _parse_gender_output(self, raw_output: str) -> str:

FILE: bridges/python/src/sdk/tools/elevenlabs_audio/elevenlabs_audio_tool.py
  class ElevenLabsAudioTool (line 19) | class ElevenLabsAudioTool(BaseTool):
    method __init__ (line 22) | def __init__(self):
    method tool_name (line 42) | def tool_name(self) -> str:
    method toolkit (line 46) | def toolkit(self) -> str:
    method description (line 50) | def description(self) -> str:
    method transcribe_to_file (line 53) | def transcribe_to_file(
    method _parse_transcription (line 109) | def _parse_transcription(self, raw_output: Dict[str, Any]) -> Transcri...

FILE: bridges/python/src/sdk/tools/faster_whisper/faster_whisper_tool.py
  class FasterWhisperTool (line 14) | class FasterWhisperTool(BaseTool):
    method __init__ (line 29) | def __init__(self):
    method tool_name (line 40) | def tool_name(self) -> str:
    method toolkit (line 45) | def toolkit(self) -> str:
    method description (line 49) | def description(self) -> str:
    method transcribe_to_file (line 52) | def transcribe_to_file(
    method _parse_transcription (line 119) | def _parse_transcription(self, raw_output: str) -> TranscriptionOutput:

FILE: bridges/python/src/sdk/tools/ffmpeg/ffmpeg_tool.py
  class FfmpegTool (line 9) | class FfmpegTool(BaseTool):
    method __init__ (line 12) | def __init__(self):
    method tool_name (line 22) | def tool_name(self) -> str:
    method toolkit (line 26) | def toolkit(self) -> str:
    method description (line 30) | def description(self) -> str:
    method _get_global_args (line 33) | def _get_global_args(self) -> List[str]:
    method convert_video_format (line 37) | def convert_video_format(self, input_path: str, output_path: str) -> str:
    method extract_audio (line 61) | def extract_audio(self, video_path: str, audio_path: str) -> str:
    method trim_media (line 118) | def trim_media(
    method resize_video (line 157) | def resize_video(
    method combine_video_and_audio (line 186) | def combine_video_and_audio(
    method compress_video (line 226) | def compress_video(self, input_path: str, output_path: str, bitrate: s...
    method adjust_tempo (line 252) | def adjust_tempo(
    method assemble_audio_segments (line 316) | def assemble_audio_segments(

FILE: bridges/python/src/sdk/tools/ffprobe/ffprobe_tool.py
  class MediaFormatInfo (line 10) | class MediaFormatInfo:
    method __init__ (line 11) | def __init__(self, data: Dict[str, Any]):
    method to_dict (line 23) | def to_dict(self) -> Dict[str, Any]:
  class StreamInfo (line 38) | class StreamInfo:
    method __init__ (line 39) | def __init__(self, data: Dict[str, Any]):
    method __getitem__ (line 52) | def __getitem__(self, key: str) -> Any:
    method to_dict (line 55) | def to_dict(self) -> Dict[str, Any]:
  class FrameInfo (line 59) | class FrameInfo:
    method __init__ (line 60) | def __init__(self, data: Dict[str, Any]):
    method __getitem__ (line 75) | def __getitem__(self, key: str) -> Any:
    method to_dict (line 78) | def to_dict(self) -> Dict[str, Any]:
  class FfprobeTool (line 82) | class FfprobeTool(BaseTool):
    method __init__ (line 85) | def __init__(self):
    method tool_name (line 96) | def tool_name(self) -> str:
    method toolkit (line 100) | def toolkit(self) -> str:
    method description (line 104) | def description(self) -> str:
    method get_media_format_info (line 107) | def get_media_format_info(self, file_path: str) -> MediaFormatInfo:
    method list_streams (line 142) | def list_streams(self, file_path: str) -> List[StreamInfo]:
    method get_video_stream_info (line 177) | def get_video_stream_info(self, file_path: str) -> List[StreamInfo]:
    method get_audio_stream_info (line 194) | def get_audio_stream_info(self, file_path: str) -> List[StreamInfo]:
    method count_frames (line 211) | def count_frames(self, file_path: str) -> int:
    method get_frames_info (line 277) | def get_frames_info(self, file_path: str) -> List[FrameInfo]:
    method get_duration (line 314) | def get_duration(self, file_path: str) -> int:

FILE: bridges/python/src/sdk/tools/grok/grok_tool.py
  class GrokTool (line 23) | class GrokTool(BaseTool):
    method __init__ (line 37) | def __init__(self):
    method tool_name (line 54) | def tool_name(self) -> str:
    method toolkit (line 58) | def toolkit(self) -> str:
    method description (line 62) | def description(self) -> str:
    method set_api_key (line 65) | def set_api_key(self, api_key: str) -> None:
    method list_models (line 69) | def list_models(self) -> Dict[str, Any]:
    method chat_completion (line 100) | def chat_completion(
    method search_web (line 191) | def search_web(
    method search_x (line 225) | def search_x(
    method search (line 271) | def search(
    method deep_research (line 308) | def deep_research(
    method get_trending_on_x (line 349) | def get_trending_on_x(

FILE: bridges/python/src/sdk/tools/open_meteo/open_meteo_tool.py
  function _degrees_to_compass (line 62) | def _degrees_to_compass(degrees: float) -> str:
  function _celsius_to_fahrenheit (line 67) | def _celsius_to_fahrenheit(celsius: float) -> str:
  function _get_weather_description (line 71) | def _get_weather_description(code: int) -> str:
  function _map_hourly_to_current (line 75) | def _map_hourly_to_current(hourly: Dict[str, Any]) -> Optional[Dict[str,...
  class OpenMeteoTool (line 118) | class OpenMeteoTool(BaseTool):
    method __init__ (line 121) | def __init__(self) -> None:
    method tool_name (line 135) | def tool_name(self) -> str:
    method toolkit (line 139) | def toolkit(self) -> str:
    method description (line 143) | def description(self) -> str:
    method get_current_conditions (line 146) | def get_current_conditions(
    method _geocode (line 209) | def _geocode(self, location: str) -> Optional[Dict[str, Any]]:
    method _fetch_weather (line 246) | def _fetch_weather(

FILE: bridges/python/src/sdk/tools/openai_audio/openai_audio_tool.py
  class OpenAIAudioTool (line 19) | class OpenAIAudioTool(BaseTool):
    method __init__ (line 22) | def __init__(self):
    method tool_name (line 40) | def tool_name(self) -> str:
    method toolkit (line 45) | def toolkit(self) -> str:
    method description (line 49) | def description(self) -> str:
    method transcribe_to_file (line 52) | def transcribe_to_file(
    method _parse_transcription (line 105) | def _parse_transcription(self, raw_output: Dict[str, Any]) -> Transcri...

FILE: bridges/python/src/sdk/tools/opencode/opencode_tool.py
  class OpenCodeTool (line 27) | class OpenCodeTool(BaseTool):
    method __init__ (line 32) | def __init__(self):
    method _load_providers_from_settings (line 62) | def _load_providers_from_settings(self, tool_settings: Dict[str, Any])...
    method tool_name (line 85) | def tool_name(self) -> str:
    method toolkit (line 89) | def toolkit(self) -> str:
    method description (line 93) | def description(self) -> str:
    method configure_provider (line 96) | def configure_provider(
    method get_configured_providers (line 110) | def get_configured_providers(self) -> List[str]:
    method get_available_providers (line 114) | def get_available_providers(self) -> List[str]:
    method get_default_model (line 118) | def get_default_model(self, provider: str) -> str:
    method _setup_provider_auth (line 125) | def _setup_provider_auth(self, provider: str, api_key: str) -> None:
    method _analyze_relevant_toolkits (line 146) | def _analyze_relevant_toolkits(self, description: str) -> set:
    method _scan_available_toolkits (line 208) | def _scan_available_toolkits(self, relevant_toolkits: Optional[set] = ...
    method _get_tool_methods (line 284) | def _get_tool_methods(self, tool_name: str) -> List[Dict[str, str]]:
    method _scan_aurora_components (line 331) | def _scan_aurora_components(self) -> str:
    method _get_tool_creation_guidelines (line 435) | def _get_tool_creation_guidelines(self, bridge: str) -> str:
    method _build_leon_context (line 586) | def _build_leon_context(
    method _load_prompt_template (line 647) | def _load_prompt_template(self) -> str:
    method _apply_template (line 651) | def _apply_template(self, template: str, values: Dict[str, str]) -> str:
    method _build_bridge_specific_guidelines (line 657) | def _build_bridge_specific_guidelines(
    method _build_settings_usage_example (line 681) | def _build_settings_usage_example(self, bridge: str) -> str:
    method _build_batch_processing_example (line 729) | def _build_batch_processing_example(self, bridge: str) -> str:
    method _build_leon_answer_basic_example (line 776) | def _build_leon_answer_basic_example(self, bridge: str) -> str:
    method _build_context_data_example (line 804) | def _build_context_data_example(self, bridge: str) -> str:
    method _build_action_params_example (line 850) | def _build_action_params_example(self, bridge: str) -> str:
    method _build_reference_files_section (line 886) | def _build_reference_files_section(self, context_files: List[str]) -> ...
    method _build_repo_snapshot (line 893) | def _build_repo_snapshot(self, context_files: List[str]) -> str:
    method _format_snapshot_date (line 931) | def _format_snapshot_date(self, value: Optional[float]) -> str:
    method _get_latest_mtime (line 936) | def _get_latest_mtime(self, dir_path: Path) -> Optional[float]:
    method _get_context_file_snapshot (line 946) | def _get_context_file_snapshot(self, context_files: List[str]) -> List...
    method _build_leon_context_legacy (line 959) | def _build_leon_context_legacy(
    method generate_skill (line 1714) | def generate_skill(
    method _get_existing_skills (line 1813) | def _get_existing_skills(self, skills_dir: Path) -> set:
    method _get_created_files (line 1825) | def _get_created_files(self, skills_dir: Path, existing_skills: set) -...
    method _get_all_files_recursive (line 1844) | def _get_all_files_recursive(self, dir_path: Path) -> List[Path]:

FILE: bridges/python/src/sdk/tools/openrouter/openrouter_tool.py
  class OpenRouterTool (line 17) | class OpenRouterTool(BaseTool):
    method __init__ (line 22) | def __init__(self, api_key: Optional[str] = None):
    method tool_name (line 44) | def tool_name(self) -> str:
    method toolkit (line 48) | def toolkit(self) -> str:
    method description (line 52) | def description(self) -> str:
    method set_api_key (line 55) | def set_api_key(self, api_key: str) -> None:
    method chat_completion (line 59) | def chat_completion(
    method completion (line 139) | def completion(
    method structured_completion (line 192) | def structured_completion(
    method list_models (line 250) | def list_models(self) -> Dict[str, Any]:

FILE: bridges/python/src/sdk/tools/qwen3_asr/qwen3_asr_tool.py
  class Qwen3ASRTool (line 18) | class Qwen3ASRTool(BaseTool):
    method __init__ (line 29) | def __init__(self):
    method tool_name (line 40) | def tool_name(self) -> str:
    method toolkit (line 45) | def toolkit(self) -> str:
    method description (line 49) | def description(self) -> str:
    method transcribe_to_file (line 52) | def transcribe_to_file(
    method parse_transcription (line 160) | def parse_transcription(self, raw_output: str) -> TranscriptionOutput:

FILE: bridges/python/src/sdk/tools/qwen3_tts/qwen3_tts_tool.py
  class SynthesizeSpeechTask (line 45) | class SynthesizeSpeechTask(TypedDict, total=False):
  class DesignVoiceTask (line 67) | class DesignVoiceTask(TypedDict, total=False):
  class CustomVoiceTask (line 86) | class CustomVoiceTask(TypedDict, total=False):
  class DesignThenSynthesizeTask (line 121) | class DesignThenSynthesizeTask(TypedDict, total=False):
  class Qwen3TTSTool (line 150) | class Qwen3TTSTool(BaseTool):
    method __init__ (line 157) | def __init__(self):
    method tool_name (line 168) | def tool_name(self) -> str:
    method toolkit (line 173) | def toolkit(self) -> str:
    method description (line 177) | def description(self) -> str:
    method synthesize_speech (line 180) | def synthesize_speech(
    method design_voice (line 196) | def design_voice(
    method custom_voice (line 212) | def custom_voice(
    method design_then_synthesize (line 228) | def design_then_synthesize(
    method _resolve_resource_root (line 244) | def _resolve_resource_root(self, model_names: List[str]) -> str:
    method _run_tasks (line 255) | def _run_tasks(

FILE: bridges/python/src/sdk/tools/transcription_schema.py
  class TranscriptionMetadata (line 15) | class TranscriptionMetadata(TypedDict):
  class TranscriptionOutput (line 20) | class TranscriptionOutput(TypedDict):

FILE: bridges/python/src/sdk/tools/ultimate_vocal_remover_onnx/ultimate_vocal_remover_onnx_tool.py
  class VocalSeparationTask (line 16) | class VocalSeparationTask(TypedDict, total=False):
  class UltimateVocalRemoverONNXTool (line 25) | class UltimateVocalRemoverONNXTool(BaseTool):
    method __init__ (line 32) | def __init__(self):
    method tool_name (line 43) | def tool_name(self) -> str:
    method toolkit (line 48) | def toolkit(self) -> str:
    method description (line 52) | def description(self) -> str:
    method separate_vocals (line 55) | def separate_vocals(

FILE: bridges/python/src/sdk/tools/ytdlp/ytdlp_tool.py
  class YtdlpTool (line 10) | class YtdlpTool(BaseTool):
    method __init__ (line 13) | def __init__(self):
    method tool_name (line 23) | def tool_name(self) -> str:
    method toolkit (line 27) | def toolkit(self) -> str:
    method description (line 31) | def description(self) -> str:
    method _get_config_args (line 34) | def _get_config_args(self):
    method download_video (line 38) | def download_video(self, video_url: str, output_path: str) -> str:
    method download_audio_only (line 87) | def download_audio_only(
    method download_playlist (line 146) | def download_playlist(self, playlist_url: str, output_path: str) -> str:
    method download_video_by_quality (line 177) | def download_video_by_quality(
    method download_subtitles (line 282) | def download_subtitles(
    method download_video_with_thumbnail (line 324) | def download_video_with_thumbnail(self, video_url: str, output_path: s...

FILE: bridges/python/src/sdk/types.py
  class NLUResultSentiment (line 6) | class NLUResultSentiment(TypedDict):
  class Context (line 11) | class Context(TypedDict):
  class SkillConfig (line 19) | class SkillConfig(TypedDict):
  class ExtraContext (line 26) | class ExtraContext(TypedDict):
  class ActionParams (line 35) | class ActionParams(TypedDict):
  class Answer (line 53) | class Answer(TypedDict, total=False):
  class TextAnswer (line 61) | class TextAnswer(Answer):
  class WidgetAnswer (line 65) | class WidgetAnswer(Answer):
  class AnswerInput (line 70) | class AnswerInput(TypedDict, total=False):
  class AnswerConfig (line 78) | class AnswerConfig(TypedDict, total=False):

FILE: bridges/python/src/sdk/utils.py
  function can_access_hugging_face (line 14) | def can_access_hugging_face() -> bool:
  function set_hugging_face_url (line 31) | def set_hugging_face_url(url: str) -> str:
  function format_file_path (line 54) | def format_file_path(file_path: str) -> str:
  function format_file_paths (line 69) | def format_file_paths(file_paths: List[str]) -> str:
  function get_platform_name (line 84) | def get_platform_name() -> str:
  function is_windows (line 118) | def is_windows() -> bool:
  function is_macos (line 130) | def is_macos() -> bool:
  function is_linux (line 142) | def is_linux() -> bool:
  function format_bytes (line 154) | def format_bytes(bytes_val: float) -> str:
  function format_speed (line 176) | def format_speed(speed: Union[float, str]) -> str:
  function format_eta (line 207) | def format_eta(eta_str: str) -> str:
  function extract_archive (line 244) | def extract_archive(

FILE: bridges/python/src/sdk/widget.py
  class SendUtteranceWidgetEventMethodParams (line 15) | class SendUtteranceWidgetEventMethodParams(TypedDict):
  class RunSkillActionWidgetEventMethodParams (line 20) | class RunSkillActionWidgetEventMethodParams(TypedDict):
  class SendUtteranceOptions (line 25) | class SendUtteranceOptions(TypedDict, total=False):
  class WidgetEventMethod (line 30) | class WidgetEventMethod(TypedDict):
  class WidgetOptions (line 39) | class WidgetOptions(Generic[T]):
  class Widget (line 45) | class Widget(ABC, Generic[T]):
    method __init__ (line 46) | def __init__(self, options: WidgetOptions[T]):
    method render (line 65) | def render(self) -> WidgetComponent:
    method send_utterance (line 68) | def send_utterance(self, key: str, options: Optional[Dict[str, Any]] =...
    method run_skill_action (line 85) | def run_skill_action(self, action_name: str, params: Dict[str, Any]) -...
    method content (line 99) | def content(self, key: str, data: Optional[Dict[str, Any]] = None) -> ...

FILE: bridges/python/src/sdk/widget_component.py
  function generate_id (line 16) | def generate_id() -> str:
  class WidgetEvent (line 20) | class WidgetEvent(TypedDict):
  class WidgetComponent (line 26) | class WidgetComponent(Generic[T]):
    method __init__ (line 27) | def __init__(self, props: T):
    method parse_events (line 33) | def parse_events(self) -> List[WidgetEvent]:
    method __dict__ (line 48) | def __dict__(self):

FILE: scripts/build-binaries.js
  constant BUILD_TARGETS (line 33) | const BUILD_TARGETS = new Map()

FILE: scripts/generate/generate-prompt.js
  constant TOOL_ALIAS_NAME (line 15) | const TOOL_ALIAS_NAME = 'Qwen3-TTS'
  constant TOOL_NAME (line 16) | const TOOL_NAME = 'qwen3_tts'
  constant TOOL_TS_FILE_NAME (line 17) | const TOOL_TS_FILE_NAME = `${TOOL_NAME}-tool.ts`
  constant TOOL_PYTHON_FILE_NAME (line 18) | const TOOL_PYTHON_FILE_NAME = `${TOOL_NAME}_tool.py`
  constant TOOL_TOOLKIT_NAME (line 19) | const TOOL_TOOLKIT_NAME = 'music_audio'
  constant TOOL_DESCRIPTION (line 20) | const TOOL_DESCRIPTION = `${TOOL_ALIAS_NAME} is a tool designed to facil...
  constant TOOL_PURPOSE_REQUIREMENT (line 21) | const TOOL_PURPOSE_REQUIREMENT = `The goal of this tool is to bind the f...
  constant TEMPLATE_CONFIGS (line 29) | const TEMPLATE_CONFIGS = {

FILE: scripts/release/pre-release-binaries.js
  constant BUILD_TARGETS (line 20) | const BUILD_TARGETS = new Map()

FILE: scripts/run-agentic-loop-vitest.ts
  type AgenticLoopSuite (line 4) | type AgenticLoopSuite = 'unit' | 'e2e'
  function extractTestNamePattern (line 6) | function extractTestNamePattern(args: string[]): string | null {
  function resolveSuitePath (line 34) | function resolveSuitePath(suite: AgenticLoopSuite): string {

FILE: scripts/setup/setup-binaries.js
  constant TARGETS (line 30) | const TARGETS = new Map()

FILE: scripts/setup/setup-cmake.js
  function readManifest (line 26) | function readManifest() {
  function cleanInstallDirectory (line 38) | async function cleanInstallDirectory() {
  function getDownloadURL (line 57) | function getDownloadURL() {
  function setupCMake (line 69) | async function setupCMake() {

FILE: scripts/setup/setup-llama-cpp.js
  constant LLAMA_SERVER_BINARY_NAME (line 32) | const LLAMA_SERVER_BINARY_NAME = SystemHelper.isWindows()
  constant LLAMACPP_SOURCE_DOWNLOAD_MAX_ATTEMPTS (line 35) | const LLAMACPP_SOURCE_DOWNLOAD_MAX_ATTEMPTS = 2
  constant LLAMACPP_SOURCE_ARCHIVE_SETTLE_DELAY_MS (line 36) | const LLAMACPP_SOURCE_ARCHIVE_SETTLE_DELAY_MS = 500
  constant LLAMACPP_SOURCE_ARCHIVE_SETTLE_POLL_DELAY_MS (line 37) | const LLAMACPP_SOURCE_ARCHIVE_SETTLE_POLL_DELAY_MS = 250
  constant LLAMACPP_SOURCE_ARCHIVE_SETTLE_MAX_POLLS (line 38) | const LLAMACPP_SOURCE_ARCHIVE_SETTLE_MAX_POLLS = 6
  constant LLAMACPP_RELEASE_BASE_URL (line 39) | const LLAMACPP_RELEASE_BASE_URL = `https://github.com/ggml-org/llama.cpp...
  constant LLAMACPP_SOURCE_URL (line 40) | const LLAMACPP_SOURCE_URL = `https://github.com/ggml-org/llama.cpp/archi...
  function readManifest (line 42) | function readManifest() {
  function removePath (line 85) | async function removePath(targetPath) {
  function wait (line 89) | function wait(delayMs) {
  function movePath (line 95) | async function movePath(sourcePath, destinationPath) {
  function getBinaryPath (line 117) | function getBinaryPath(directoryPath) {
  function isExistingInstallationHealthy (line 121) | async function isExistingInstallationHealthy(runtimeDirectoryPath) {
  function findDirectoryContainingBinary (line 143) | async function findDirectoryContainingBinary(rootPath, binaryName) {
  function cleanInstallDirectory (line 166) | async function cleanInstallDirectory() {
  function writeManifest (line 180) | async function writeManifest(
  function pruneSourceTree (line 201) | async function pruneSourceTree() {
  function waitForArchiveToSettle (line 215) | async function waitForArchiveToSettle(archivePath) {
  function downloadAndExtractSourceArchive (line 234) | async function downloadAndExtractSourceArchive(sourceArchivePath) {
  function getLinuxVulkanAssetName (line 277) | function getLinuxVulkanAssetName() {
  function getPrebuiltAssetName (line 281) | function getPrebuiltAssetName(graphicsComputeAPI, hasGPU) {
  function installPrebuilt (line 303) | async function installPrebuilt(assetName, extraData = {}) {
  function buildFromSource (line 355) | async function buildFromSource() {
  function setupLlamaCPP (line 409) | async function setupLlamaCPP() {

FILE: scripts/setup/setup-local-llm.js
  constant DEFAULT_LLM_OPTIONS (line 25) | const DEFAULT_LLM_OPTIONS = [
  function readManifest (line 44) | function readManifest() {
  function toRelativeModelPath (line 56) | function toRelativeModelPath(modelPath) {
  function removePreviousDefaultModel (line 60) | async function removePreviousDefaultModel(previousModelPath, nextModelPa...
  function getSelectedModel (line 75) | function getSelectedModel(totalVRAM) {
  function inspectHardware (line 83) | async function inspectHardware() {
  function canInstallDefaultLLM (line 108) | async function canInstallDefaultLLM(hardware) {
  function downloadLLM (line 125) | async function downloadLLM(selectedModel) {
  function setupLocalLLM (line 171) | async function setupLocalLLM() {

FILE: scripts/setup/setup-ninja.js
  function readManifest (line 26) | function readManifest() {
  function cleanInstallDirectory (line 38) | async function cleanInstallDirectory() {
  function getDownloadURL (line 57) | function getDownloadURL() {
  function setupNinja (line 69) | async function setupNinja() {

FILE: scripts/setup/setup-nvidia-libs.js
  function mapToNvidiaArch (line 48) | function mapToNvidiaArch(cpuArch) {
  function ensureDirectoryLink (line 60) | async function ensureDirectoryLink(linkPath, targetPath) {
  function ensureCompatibilityLinks (line 74) | async function ensureCompatibilityLinks() {
  function readManifest (line 89) | function readManifest(manifestPath) {
  function getNVIDIADownloadURL (line 106) | function getNVIDIADownloadURL(library, version) {
  function installNVIDIALibrary (line 145) | async function installNVIDIALibrary(
  function setupNVIDIALibs (line 226) | async function setupNVIDIALibs() {

FILE: scripts/setup/setup-python-dev-env.js
  function getModelInstallationFileUrl (line 30) | function getModelInstallationFileUrl(model, mirror = undefined) {
  constant SETUP_TARGETS (line 46) | const SETUP_TARGETS = new Map()
  constant SPACY_MODELS (line 47) | const SPACY_MODELS = new Map()

FILE: scripts/setup/setup-pytorch.js
  function ensureDirectoryLink (line 19) | async function ensureDirectoryLink(linkPath, targetPath) {
  function getPyTorchPlatform (line 36) | function getPyTorchPlatform() {
  function getPyTorchDownloadURL (line 63) | function getPyTorchDownloadURL(version) {
  function readManifest (line 86) | function readManifest(manifestPath) {
  function installPyTorch (line 103) | async function installPyTorch(requiredVersion, targetPath, manifestPath) {
  function setupPyTorch (line 180) | async function setupPyTorch() {

FILE: scripts/setup/setup-qmd-llm.js
  constant QMD_MODELS_DIR_PATH (line 9) | const QMD_MODELS_DIR_PATH = path.join(homedir(), '.cache', 'qmd', 'models')
  constant QMD_MODELS (line 11) | const QMD_MODELS = [
  function getModelFilenameFromURL (line 30) | function getModelFilenameFromURL(modelURL) {
  function downloadModel (line 36) | async function downloadModel(model) {

FILE: scripts/setup/setup-tcp-server-models.js
  constant ASR_MODEL_FILES (line 18) | const ASR_MODEL_FILES = [
  constant TTS_BERT_BASE_MODEL_FILES (line 31) | const TTS_BERT_BASE_MODEL_FILES = [
  function installTTSModel (line 39) | async function installTTSModel() {
  function installASRModel (line 60) | async function installASRModel() {
  function installTTSBERTBaseModel (line 112) | async function installTTSBERTBaseModel() {

FILE: scripts/train/train-llm-actions-classifier.js
  constant LANG (line 9) | const LANG = 'en'

FILE: server/src/constants.ts
  constant PRODUCTION_ENV (line 11) | const PRODUCTION_ENV = 'production'
  constant DEVELOPMENT_ENV (line 12) | const DEVELOPMENT_ENV = 'development'
  constant TESTING_ENV (line 13) | const TESTING_ENV = 'testing'
  constant GITHUB_URL (line 15) | const GITHUB_URL = 'https://github.com/leon-ai/leon'
  constant API_VERSION (line 16) | const API_VERSION = 'v1'
  constant LEON_NODE_ENV (line 25) | const LEON_NODE_ENV = process.env['LEON_NODE_ENV'] || PRODUCTION_ENV
  constant IS_PRODUCTION_ENV (line 26) | const IS_PRODUCTION_ENV = LEON_NODE_ENV === PRODUCTION_ENV
  constant IS_DEVELOPMENT_ENV (line 27) | const IS_DEVELOPMENT_ENV = LEON_NODE_ENV === DEVELOPMENT_ENV
  constant IS_TESTING_ENV (line 28) | const IS_TESTING_ENV = LEON_NODE_ENV === TESTING_ENV
  constant BIN_PATH (line 33) | const BIN_PATH = path.join(process.cwd(), 'bin')
  constant LOGS_PATH (line 34) | const LOGS_PATH = path.join(process.cwd(), 'logs')
  constant SKILLS_PATH (line 35) | const SKILLS_PATH = path.join(process.cwd(), 'skills')
  constant GLOBAL_CORE_PATH (line 36) | const GLOBAL_CORE_PATH = path.join(process.cwd(), 'core')
  constant GLOBAL_DATA_PATH (line 37) | const GLOBAL_DATA_PATH = path.join(GLOBAL_CORE_PATH, 'data')
  constant CONTEXT_PATH (line 38) | const CONTEXT_PATH = path.join(GLOBAL_CORE_PATH, 'context')
  constant MEMORY_PATH (line 39) | const MEMORY_PATH = path.join(GLOBAL_CORE_PATH, 'memory')
  constant MEMORY_DB_PATH (line 40) | const MEMORY_DB_PATH = path.join(MEMORY_PATH, 'index.sqlite')
  constant MODELS_PATH (line 41) | const MODELS_PATH = path.join(GLOBAL_DATA_PATH, 'models')
  constant AUDIO_MODELS_PATH (line 42) | const AUDIO_MODELS_PATH = path.join(MODELS_PATH, 'audio')
  constant VOICE_CONFIG_PATH (line 43) | const VOICE_CONFIG_PATH = path.join(
  constant SERVER_PATH (line 48) | const SERVER_PATH = path.join(
  constant TMP_PATH (line 53) | const TMP_PATH = path.join(SERVER_PATH, 'tmp')
  constant SERVER_CORE_PATH (line 54) | const SERVER_CORE_PATH = path.join(SERVER_PATH, 'core')
  constant LEON_FILE_PATH (line 55) | const LEON_FILE_PATH = path.join(process.cwd(), 'leon.json')
  constant NVIDIA_LIBS_PATH (line 65) | const NVIDIA_LIBS_PATH = path.join(BIN_PATH, 'nvidia')
  constant NVIDIA_CUBLAS_PATH (line 66) | const NVIDIA_CUBLAS_PATH = path.join(NVIDIA_LIBS_PATH, 'cublas')
  constant NVIDIA_CUDNN_PATH (line 67) | const NVIDIA_CUDNN_PATH = path.join(NVIDIA_LIBS_PATH, 'cudnn')
  constant NVIDIA_CUDA_CUDART_PATH (line 68) | const NVIDIA_CUDA_CUDART_PATH = path.join(
  constant NVIDIA_CUDA_CUPTI_PATH (line 72) | const NVIDIA_CUDA_CUPTI_PATH = path.join(
  constant NVIDIA_CUSPARSE_PATH (line 76) | const NVIDIA_CUSPARSE_PATH = path.join(NVIDIA_LIBS_PATH, 'cusparse')
  constant NVIDIA_CUSPARSELT_PATH (line 77) | const NVIDIA_CUSPARSELT_PATH = path.join(NVIDIA_LIBS_PATH, 'cusparselt')
  constant NVIDIA_CUSPARSE_FULL_PATH (line 78) | const NVIDIA_CUSPARSE_FULL_PATH = path.join(
  constant NVIDIA_NCCL_PATH (line 82) | const NVIDIA_NCCL_PATH = path.join(NVIDIA_LIBS_PATH, 'nccl')
  constant NVIDIA_NVSHMEM_PATH (line 83) | const NVIDIA_NVSHMEM_PATH = path.join(NVIDIA_LIBS_PATH, 'nvshmem')
  constant NVIDIA_NVJITLINK_PATH (line 84) | const NVIDIA_NVJITLINK_PATH = path.join(NVIDIA_LIBS_PATH, 'nvjitlink')
  constant NVIDIA_VERSIONS_PATH (line 85) | const NVIDIA_VERSIONS_PATH = path.join(NVIDIA_LIBS_PATH, 'versions.json')
  constant NVIDIA_CUBLAS_MANIFEST_PATH (line 86) | const NVIDIA_CUBLAS_MANIFEST_PATH = path.join(
  constant NVIDIA_CUDNN_MANIFEST_PATH (line 90) | const NVIDIA_CUDNN_MANIFEST_PATH = path.join(
  constant NVIDIA_CUDA_CUDART_MANIFEST_PATH (line 94) | const NVIDIA_CUDA_CUDART_MANIFEST_PATH = path.join(
  constant NVIDIA_CUDA_CUPTI_MANIFEST_PATH (line 98) | const NVIDIA_CUDA_CUPTI_MANIFEST_PATH = path.join(
  constant NVIDIA_CUSPARSE_MANIFEST_PATH (line 102) | const NVIDIA_CUSPARSE_MANIFEST_PATH = path.join(
  constant NVIDIA_CUSPARSE_FULL_MANIFEST_PATH (line 106) | const NVIDIA_CUSPARSE_FULL_MANIFEST_PATH = path.join(
  constant NVIDIA_NCCL_MANIFEST_PATH (line 110) | const NVIDIA_NCCL_MANIFEST_PATH = path.join(
  constant NVIDIA_NVSHMEM_MANIFEST_PATH (line 114) | const NVIDIA_NVSHMEM_MANIFEST_PATH = path.join(
  constant NVIDIA_NVJITLINK_MANIFEST_PATH (line 118) | const NVIDIA_NVJITLINK_MANIFEST_PATH = path.join(
  constant NVIDIA_VERSIONS (line 122) | const NVIDIA_VERSIONS = JSON.parse(
  constant NVIDIA_CUDA_VERSION (line 125) | const NVIDIA_CUDA_VERSION = NVIDIA_VERSIONS.cuda
  constant NVIDIA_CUDNN_VERSION (line 126) | const NVIDIA_CUDNN_VERSION = NVIDIA_VERSIONS.cudnn
  constant NVIDIA_CUBLAS_VERSION (line 127) | const NVIDIA_CUBLAS_VERSION = NVIDIA_VERSIONS.cublas
  constant NVIDIA_CUDA_CUDART_VERSION (line 128) | const NVIDIA_CUDA_CUDART_VERSION = NVIDIA_VERSIONS.cuda_cudart
  constant NVIDIA_CUDA_CUPTI_VERSION (line 129) | const NVIDIA_CUDA_CUPTI_VERSION = NVIDIA_VERSIONS.cuda_cupti
  constant NVIDIA_CUSPARSE_VERSION (line 130) | const NVIDIA_CUSPARSE_VERSION = NVIDIA_VERSIONS.cusparse
  constant NVIDIA_CUSPARSE_FULL_VERSION (line 131) | const NVIDIA_CUSPARSE_FULL_VERSION = NVIDIA_VERSIONS.cusparse_full
  constant NVIDIA_NCCL_VERSION (line 132) | const NVIDIA_NCCL_VERSION = NVIDIA_VERSIONS.nccl
  constant NVIDIA_NVSHMEM_VERSION (line 133) | const NVIDIA_NVSHMEM_VERSION = NVIDIA_VERSIONS.nvshmem
  constant NVIDIA_NVJITLINK_VERSION (line 134) | const NVIDIA_NVJITLINK_VERSION = NVIDIA_VERSIONS.nvjitlink
  constant CMAKE_PATH (line 140) | const CMAKE_PATH = path.join(BIN_PATH, 'cmake')
  constant CMAKE_VERSIONS_PATH (line 141) | const CMAKE_VERSIONS_PATH = path.join(CMAKE_PATH, 'versions.json')
  constant CMAKE_INSTALL_PATH (line 142) | const CMAKE_INSTALL_PATH = path.join(CMAKE_PATH, 'cmake')
  constant CMAKE_MANIFEST_PATH (line 143) | const CMAKE_MANIFEST_PATH = path.join(CMAKE_INSTALL_PATH, 'manifest.json')
  constant CMAKE_VERSIONS (line 144) | const CMAKE_VERSIONS = JSON.parse(fs.readFileSync(CMAKE_VERSIONS_PATH, '...
  constant CMAKE_VERSION (line 145) | const CMAKE_VERSION = CMAKE_VERSIONS.cmake
  constant CMAKE_BIN_PATH (line 146) | const CMAKE_BIN_PATH = path.join(CMAKE_INSTALL_PATH, 'bin', 'cmake')
  constant NINJA_PATH (line 152) | const NINJA_PATH = path.join(BIN_PATH, 'ninja')
  constant NINJA_VERSIONS_PATH (line 153) | const NINJA_VERSIONS_PATH = path.join(NINJA_PATH, 'versions.json')
  constant NINJA_INSTALL_PATH (line 154) | const NINJA_INSTALL_PATH = path.join(NINJA_PATH, 'ninja')
  constant NINJA_MANIFEST_PATH (line 155) | const NINJA_MANIFEST_PATH = path.join(NINJA_INSTALL_PATH, 'manifest.json')
  constant NINJA_VERSIONS (line 156) | const NINJA_VERSIONS = JSON.parse(fs.readFileSync(NINJA_VERSIONS_PATH, '...
  constant NINJA_VERSION (line 157) | const NINJA_VERSION = NINJA_VERSIONS.ninja
  constant NINJA_BIN_PATH (line 158) | const NINJA_BIN_PATH = path.join(NINJA_INSTALL_PATH, 'ninja')
  constant LLAMACPP_PATH (line 164) | const LLAMACPP_PATH = path.join(BIN_PATH, 'llama.cpp')
  constant LLAMACPP_VERSIONS_PATH (line 165) | const LLAMACPP_VERSIONS_PATH = path.join(LLAMACPP_PATH, 'versions.json')
  constant LLAMACPP_BUILD_PATH (line 166) | const LLAMACPP_BUILD_PATH = path.join(LLAMACPP_PATH, 'build')
  constant LLAMACPP_SOURCE_PATH (line 167) | const LLAMACPP_SOURCE_PATH = path.join(LLAMACPP_PATH, 'llama.cpp')
  constant LLAMACPP_SOURCE_BUILD_PATH (line 168) | const LLAMACPP_SOURCE_BUILD_PATH = path.join(
  constant LLAMACPP_ROOT_MANIFEST_PATH (line 173) | const LLAMACPP_ROOT_MANIFEST_PATH = path.join(LLAMACPP_PATH, 'manifest.j...
  constant LLAMACPP_BUILD_MANIFEST_PATH (line 174) | const LLAMACPP_BUILD_MANIFEST_PATH = path.join(
  constant LLAMACPP_SOURCE_MANIFEST_PATH (line 178) | const LLAMACPP_SOURCE_MANIFEST_PATH = path.join(
  constant LLAMACPP_VERSIONS (line 182) | const LLAMACPP_VERSIONS = JSON.parse(
  constant LLAMACPP_RELEASE_VERSION (line 185) | const LLAMACPP_RELEASE_VERSION = LLAMACPP_VERSIONS['llama.cpp']
  constant PYTORCH_PATH (line 191) | const PYTORCH_PATH = path.join(BIN_PATH, 'pytorch')
  constant PYTORCH_TORCH_PATH (line 192) | const PYTORCH_TORCH_PATH = path.join(PYTORCH_PATH, 'torch')
  constant PYTORCH_NVIDIA_PATH (line 193) | const PYTORCH_NVIDIA_PATH = path.join(PYTORCH_TORCH_PATH, 'nvidia')
  constant PYTORCH_VERSIONS_PATH (line 194) | const PYTORCH_VERSIONS_PATH = path.join(PYTORCH_PATH, 'versions.json')
  constant PYTORCH_MANIFEST_PATH (line 195) | const PYTORCH_MANIFEST_PATH = path.join(
  constant PYTORCH_VERSIONS (line 199) | const PYTORCH_VERSIONS = JSON.parse(
  constant PYTORCH_VERSION (line 202) | const PYTORCH_VERSION = PYTORCH_VERSIONS.torch
  constant BINARIES_FOLDER_NAME (line 207) | const BINARIES_FOLDER_NAME = SystemHelper.getBinariesFolderName()
  constant BRIDGES_PATH (line 208) | const BRIDGES_PATH = path.join(process.cwd(), 'bridges')
  constant TOOLKITS_PATH (line 209) | const TOOLKITS_PATH = path.join(BRIDGES_PATH, 'toolkits')
  constant NODEJS_BRIDGE_ROOT_PATH (line 210) | const NODEJS_BRIDGE_ROOT_PATH = path.join(BRIDGES_PATH, 'nodejs')
  constant PYTHON_BRIDGE_ROOT_PATH (line 211) | const PYTHON_BRIDGE_ROOT_PATH = path.join(BRIDGES_PATH, 'python')
  constant PYTHON_TCP_SERVER_ROOT_PATH (line 212) | const PYTHON_TCP_SERVER_ROOT_PATH = path.join(
  constant NODEJS_BRIDGE_DIST_PATH (line 217) | const NODEJS_BRIDGE_DIST_PATH = path.join(
  constant PYTHON_BRIDGE_DIST_PATH (line 221) | const PYTHON_BRIDGE_DIST_PATH = path.join(
  constant PYTHON_TCP_SERVER_DIST_PATH (line 225) | const PYTHON_TCP_SERVER_DIST_PATH = path.join(
  constant NODEJS_BRIDGE_SRC_PATH (line 230) | const NODEJS_BRIDGE_SRC_PATH = path.join(NODEJS_BRIDGE_ROOT_PATH, 'src')
  constant NODEJS_BRIDGE_TOOL_RUNTIME_SRC_PATH (line 231) | const NODEJS_BRIDGE_TOOL_RUNTIME_SRC_PATH = path.join(
  constant NODEJS_BRIDGE_TOOL_RUNTIME_DIST_PATH (line 235) | const NODEJS_BRIDGE_TOOL_RUNTIME_DIST_PATH = path.join(
  constant PYTHON_BRIDGE_SRC_PATH (line 239) | const PYTHON_BRIDGE_SRC_PATH = path.join(PYTHON_BRIDGE_ROOT_PATH, 'src')
  constant PYTHON_TCP_SERVER_SRC_PATH (line 240) | const PYTHON_TCP_SERVER_SRC_PATH = path.join(
  constant PYTHON_TCP_SERVER_SETTINGS_PATH (line 244) | const PYTHON_TCP_SERVER_SETTINGS_PATH = path.join(
  constant PYTHON_TCP_SERVER_SETTINGS (line 248) | const PYTHON_TCP_SERVER_SETTINGS = JSON.parse(
  constant PYTHON_TCP_SERVER_TTS_MODEL_FILE_NAME (line 251) | const PYTHON_TCP_SERVER_TTS_MODEL_FILE_NAME =
  constant PYTHON_TCP_SERVER_TTS_MODEL_DIR_PATH (line 253) | const PYTHON_TCP_SERVER_TTS_MODEL_DIR_PATH = path.join(
  constant PYTHON_TCP_SERVER_TTS_MODEL_PATH (line 257) | const PYTHON_TCP_SERVER_TTS_MODEL_PATH = path.join(
  constant PYTHON_TCP_SERVER_TTS_BERT_FRENCH_DIR_PATH (line 261) | const PYTHON_TCP_SERVER_TTS_BERT_FRENCH_DIR_PATH = path.join(
  constant PYTHON_TCP_SERVER_TTS_BERT_BASE_DIR_PATH (line 265) | const PYTHON_TCP_SERVER_TTS_BERT_BASE_DIR_PATH = path.join(
  constant PYTHON_TCP_SERVER_ASR_MODEL_DIR_PATH (line 269) | const PYTHON_TCP_SERVER_ASR_MODEL_DIR_PATH = path.join(
  constant PYTHON_TCP_SERVER_TTS_MODEL_HF_DOWNLOAD_URL (line 273) | const PYTHON_TCP_SERVER_TTS_MODEL_HF_DOWNLOAD_URL = `https://huggingface...
  constant PYTHON_TCP_SERVER_ASR_MODEL_HF_PREFIX_DOWNLOAD_URL (line 274) | const PYTHON_TCP_SERVER_ASR_MODEL_HF_PREFIX_DOWNLOAD_URL =
  constant PYTHON_TCP_SERVER_TTS_BERT_FRENCH_MODEL_HF_PREFIX_DOWNLOAD_URL (line 276) | const PYTHON_TCP_SERVER_TTS_BERT_FRENCH_MODEL_HF_PREFIX_DOWNLOAD_URL =
  constant PYTHON_TCP_SERVER_TTS_BERT_BASE_MODEL_HF_PREFIX_DOWNLOAD_URL (line 278) | const PYTHON_TCP_SERVER_TTS_BERT_BASE_MODEL_HF_PREFIX_DOWNLOAD_URL =
  constant NODEJS_BRIDGE_VERSION_FILE_PATH (line 281) | const NODEJS_BRIDGE_VERSION_FILE_PATH = path.join(
  constant PYTHON_BRIDGE_VERSION_FILE_PATH (line 285) | const PYTHON_BRIDGE_VERSION_FILE_PATH = path.join(
  constant PYTHON_TCP_SERVER_VERSION_FILE_PATH (line 289) | const PYTHON_TCP_SERVER_VERSION_FILE_PATH = path.join(
  constant NODEJS_BRIDGE_BIN_NAME (line 303) | const NODEJS_BRIDGE_BIN_NAME = 'leon-nodejs-bridge.cjs'
  constant PYTHON_BRIDGE_BIN_NAME (line 304) | const PYTHON_BRIDGE_BIN_NAME = 'leon-python-bridge'
  constant PYTHON_TCP_SERVER_BIN_NAME (line 305) | const PYTHON_TCP_SERVER_BIN_NAME = 'leon-tcp-server'
  constant PYTHON_TCP_SERVER_BIN_PATH (line 307) | const PYTHON_TCP_SERVER_BIN_PATH = path.join(
  constant PYTHON_BRIDGE_BIN_PATH (line 312) | const PYTHON_BRIDGE_BIN_PATH = path.join(
  constant NODEJS_BRIDGE_BIN_PATH (line 317) | const NODEJS_BRIDGE_BIN_PATH = `${path.join(
  constant TSX_CLI_PATH (line 324) | const TSX_CLI_PATH = path.join(
  constant LEON_VERSION (line 332) | const LEON_VERSION = process.env['npm_package_version']
  constant EN_SPACY_MODEL_NAME (line 338) | const EN_SPACY_MODEL_NAME = 'en_core_web_trf'
  constant EN_SPACY_MODEL_VERSION (line 339) | const EN_SPACY_MODEL_VERSION = '3.4.0'
  constant FR_SPACY_MODEL_NAME (line 340) | const FR_SPACY_MODEL_NAME = 'fr_core_news_md'
  constant FR_SPACY_MODEL_VERSION (line 341) | const FR_SPACY_MODEL_VERSION = '3.4.0'
  constant LANG (line 346) | const LANG = process.env['LEON_LANG'] as LongLanguageCode
  constant HOST (line 348) | const HOST = process.env['LEON_HOST']
  constant PORT (line 349) | const PORT = Number(process.env['LEON_PORT'])
  constant TIME_ZONE (line 351) | const TIME_ZONE = process.env['LEON_TIME_ZONE']
  constant HAS_AFTER_SPEECH (line 353) | const HAS_AFTER_SPEECH = process.env['LEON_AFTER_SPEECH'] === 'true'
  constant HAS_STT (line 355) | const HAS_STT = process.env['LEON_STT'] === 'true'
  constant STT_PROVIDER (line 356) | const STT_PROVIDER = process.env['LEON_STT_PROVIDER']
  constant HAS_TTS (line 357) | const HAS_TTS = process.env['LEON_TTS'] === 'true'
  constant TTS_PROVIDER (line 358) | const TTS_PROVIDER = process.env['LEON_TTS_PROVIDER']
  constant HAS_WARM_UP_LLM_DUTIES (line 360) | const HAS_WARM_UP_LLM_DUTIES =
  constant HAS_OVER_HTTP (line 362) | const HAS_OVER_HTTP = process.env['LEON_OVER_HTTP'] === 'true'
  constant HTTP_API_KEY (line 363) | const HTTP_API_KEY = process.env['LEON_HTTP_API_KEY']
  constant HTTP_API_LANG (line 364) | const HTTP_API_LANG = process.env['LEON_HTTP_API_LANG']
  constant PYTHON_TCP_SERVER_HOST (line 366) | const PYTHON_TCP_SERVER_HOST = process.env['LEON_PY_TCP_SERVER_HOST']
  constant PYTHON_TCP_SERVER_PORT (line 367) | const PYTHON_TCP_SERVER_PORT = Number(
  constant IS_TELEMETRY_ENABLED (line 371) | const IS_TELEMETRY_ENABLED = process.env['LEON_TELEMETRY'] === 'true'
  constant MAIN_NLP_MODEL_PATH (line 376) | const MAIN_NLP_MODEL_PATH = path.join(MODELS_PATH, 'leon-main-model.nlp')
  constant GLOBAL_RESOLVERS_NLP_MODEL_PATH (line 377) | const GLOBAL_RESOLVERS_NLP_MODEL_PATH = path.join(
  constant SKILLS_RESOLVERS_NLP_MODEL_PATH (line 381) | const SKILLS_RESOLVERS_NLP_MODEL_PATH = path.join(
  constant LLM_ACTIONS_CLASSIFIER_PATH (line 385) | const LLM_ACTIONS_CLASSIFIER_PATH = path.join(
  constant LLM_SKILL_ROUTER_DUTY_SKILL_LIST_PATH (line 389) | const LLM_SKILL_ROUTER_DUTY_SKILL_LIST_PATH = path.join(
  constant HAS_LLM (line 398) | const HAS_LLM = process.env['LEON_LLM'] === 'true'
  constant HAS_LLM_NLG (line 399) | const HAS_LLM_NLG = process.env['LEON_LLM_NLG'] === 'true' && HAS_LLM
  constant HAS_LLM_ACTION_RECOGNITION (line 400) | const HAS_LLM_ACTION_RECOGNITION =
  constant LEON_ROUTING_MODE (line 402) | const LEON_ROUTING_MODE = process.env['LEON_ROUTING_MODE'] || 'smart'
  constant LEON_PULSE_ENABLED (line 403) | const LEON_PULSE_ENABLED = true
  constant LEON_PULSE_INTERVAL_MS (line 404) | const LEON_PULSE_INTERVAL_MS = 30 * 60 * 1_000
  constant SHOULD_START_PYTHON_TCP_SERVER (line 405) | const SHOULD_START_PYTHON_TCP_SERVER = !(
  constant LEON_DISABLED_CONTEXT_FILES (line 410) | const LEON_DISABLED_CONTEXT_FILES =
  constant LLM_PROVIDER (line 412) | const LLM_PROVIDER = process.env['LEON_LLM_PROVIDER'] || 'llamacpp'
  constant WORKFLOW_LLM_PROVIDER (line 413) | const WORKFLOW_LLM_PROVIDER =
  constant AGENT_LLM_PROVIDER (line 415) | const AGENT_LLM_PROVIDER =
  constant LLM_DIR_PATH (line 462) | const LLM_DIR_PATH = path.join(MODELS_PATH, 'llm')
  constant LLM_MANIFEST_PATH (line 463) | const LLM_MANIFEST_PATH = path.join(LLM_DIR_PATH, 'manifest.json')
  constant LLM_MANIFEST (line 464) | const LLM_MANIFEST = fs.existsSync(LLM_MANIFEST_PATH)
  constant DEFAULT_INSTALLED_LLM_PATH (line 469) | const DEFAULT_INSTALLED_LLM_PATH =
  constant CONFIGURED_LLAMACPP_MODEL_PATH (line 473) | const CONFIGURED_LLAMACPP_MODEL_PATH =
  constant LLM_NAME (line 475) | const LLM_NAME = LLM_MANIFEST?.name || 'Local LLM'
  constant LLM_VERSION (line 476) | const LLM_VERSION = LLM_MANIFEST?.version || 'unknown'
  constant LLM_FILE_NAME (line 477) | const LLM_FILE_NAME = CONFIGURED_LLAMACPP_MODEL_PATH
  constant LLM_NAME_WITH_VERSION (line 480) | const LLM_NAME_WITH_VERSION = `${LLM_NAME} (${LLM_VERSION})`
  constant LLM_PATH (line 481) | const LLM_PATH = CONFIGURED_LLAMACPP_MODEL_PATH
  constant LLM_MINIMUM_TOTAL_VRAM (line 484) | const LLM_MINIMUM_TOTAL_VRAM = 6
  constant LLM_HIGH_TIER_MINIMUM_TOTAL_VRAM (line 485) | const LLM_HIGH_TIER_MINIMUM_TOTAL_VRAM = 18
  constant LLM_MINIMUM_FREE_VRAM (line 486) | const LLM_MINIMUM_FREE_VRAM = 6
  constant MINIMUM_REQUIRED_RAM (line 531) | const MINIMUM_REQUIRED_RAM = 4
  constant INSTANCE_ID (line 532) | const INSTANCE_ID = fs.existsSync(LEON_FILE_PATH)
  constant IS_GITHUB_ACTIONS (line 535) | const IS_GITHUB_ACTIONS = process.env['GITHUB_ACTIONS'] !== undefined
  constant IS_GITPOD (line 536) | const IS_GITPOD = process.env['GITPOD_WORKSPACE_URL'] !== undefined

FILE: server/src/conversation-logger.ts
  type ConversationLoggerSettings (line 8) | interface ConversationLoggerSettings {
  type LoadParams (line 15) | interface LoadParams {
  class ConversationLogger (line 26) | class ConversationLogger {
    method loggerName (line 30) | get loggerName(): string {
    method constructor (line 34) | constructor(settings: ConversationLoggerSettings) {
    method createConversationLogFile (line 42) | private async createConversationLogFile(): Promise<void> {
    method getAllLogs (line 53) | private async getAllLogs(): Promise<MessageLog[]> {
    method push (line 74) | public async push(newRecord: Omit<MessageLog, 'sentAt'>): Promise<void> {
    method load (line 98) | public async load(params?: LoadParams): Promise<MessageLog[]> {
    method loadAll (line 113) | public async loadAll(): Promise<MessageLog[]> {
    method clear (line 124) | public async clear(): Promise<void> {

FILE: server/src/core/asr/asr.ts
  class ASR (line 11) | class ASR {
    method constructor (line 19) | constructor() {
    method encode (line 32) | public encode(blob: Buffer): Promise<void> {

FILE: server/src/core/asr/types.ts
  type ASRAudioFormat (line 1) | type ASRAudioFormat = 'wav' | 'webm'

FILE: server/src/core/brain/answer-queue.ts
  class AnswerQueue (line 10) | class AnswerQueue<T> {
    method constructor (line 14) | constructor() {
    method push (line 19) | public push(answer: T): void {
    method pop (line 25) | public pop(): T | undefined {
    method clear (line 34) | public clear(): void {
    method isEmpty (line 40) | public isEmpty(): boolean {

FILE: server/src/core/brain/brain.ts
  type SkillProcess (line 27) | type SkillProcess = ChildProcessWithoutNullStreams | undefined
  type IsTalkingWithVoiceOptions (line 28) | interface IsTalkingWithVoiceOptions {
  type LLMAnswerMetrics (line 32) | interface LLMAnswerMetrics {
  type QueuedAnswer (line 56) | type QueuedAnswer =
  constant MIN_NB_OF_WORDS_TO_USE_LLM_NLG (line 64) | const MIN_NB_OF_WORDS_TO_USE_LLM_NLG = 5
  class Brain (line 66) | class Brain {
    method constructor (line 83) | constructor() {
    method skillFriendlyName (line 106) | public get skillFriendlyName(): string {
    method skillFriendlyName (line 110) | public set skillFriendlyName(newSkillFriendlyName: string) {
    method skillProcess (line 114) | public get skillProcess(): SkillProcess {
    method skillProcess (line 118) | public set skillProcess(newSkillProcess: SkillProcess) {
    method isTalkingWithVoice (line 122) | public get isTalkingWithVoice(): boolean {
    method setIsTalkingWithVoice (line 126) | public setIsTalkingWithVoice(
    method lang (line 159) | public get lang(): ShortLanguageCode {
    method lang (line 163) | public set lang(newLang: ShortLanguageCode) {
    method cleanUpAnswerQueueTimer (line 181) | private cleanUpAnswerQueueTimer(intervalId?: NodeJS.Timeout): void {
    method processAnswerQueue (line 196) | private async processAnswerQueue(end = false): Promise<void> {
    method updateTTSLang (line 367) | private async updateTTSLang(newLang: ShortLanguageCode): Promise<void> {
    method talk (line 377) | public async talk(
    method wernicke (line 408) | public wernicke(
    method runSkillAction (line 459) | public async runSkillAction(
    method speakSkillError (line 524) | public speakSkillError(): void {

FILE: server/src/core/brain/dialog-action-skill-handler.ts
  constant PLACEHOLDER_REGEX (line 8) | const PLACEHOLDER_REGEX = /{{(.*?)}}/
  class DialogActionSkillHandler (line 10) | class DialogActionSkillHandler {
    method handle (line 11) | public static async handle(
    method getDialogAnswer (line 75) | private static getDialogAnswer(
    method mapAnswerPlaceholders (line 86) | private static mapAnswerPlaceholders(
    method answerHasPlaceholders (line 131) | private static answerHasPlaceholders(
    method getFallbackAnswer (line 152) | private static getFallbackAnswer(
    method getDataToMap (line 177) | private static getDataToMap(

FILE: server/src/core/brain/logic-action-skill-handler.ts
  class LogicActionSkillHandler (line 21) | class LogicActionSkillHandler {
    method handle (line 22) | public static async handle(
    method handleLogicActionSkillProcessOutput (line 126) | private static handleLogicActionSkillProcessOutput(
    method handleLogicActionSkillProcessError (line 215) | private static handleLogicActionSkillProcessError(
    method executeLogicActionSkill (line 236) | private static async executeLogicActionSkill(
    method createIntentObject (line 278) | private static createIntentObject(
    method deleteIntentObjFile (line 323) | private static deleteIntentObjFile(intentObjectPath: string): void {

FILE: server/src/core/brain/types.ts
  type SkillResult (line 18) | interface SkillResult {
  type SkillBridges (line 40) | enum SkillBridges {
  type SkillActionTypes (line 44) | enum SkillActionTypes {
  type ActionParams (line 55) | interface ActionParams {
  type IntentObject (line 100) | interface IntentObject {
  type SkillAnswerCoreData (line 134) | interface SkillAnswerCoreData {
  type SkillAnswerOutput (line 146) | interface SkillAnswerOutput extends IntentObject {
  type BrainProcessResult (line 166) | interface BrainProcessResult extends NLUProcessResult {

FILE: server/src/core/context-manager/context-file-factory.ts
  constant DEFAULT_CONTEXT_REFRESH_TTL_MS (line 23) | const DEFAULT_CONTEXT_REFRESH_TTL_MS = 10 * 60 * 1_000
  type LeonRuntimeContextResolvers (line 25) | interface LeonRuntimeContextResolvers {
  function createContextFiles (line 31) | function createContextFiles(

FILE: server/src/core/context-manager/context-files/activity-context-file.ts
  type AppActivityAggregate (line 14) | interface AppActivityAggregate {
  type ActivityLogFileEntry (line 23) | interface ActivityLogFileEntry {
  type ActivityTrackingState (line 30) | interface ActivityTrackingState {
  constant MAX_PROCESS_ENTRIES (line 36) | const MAX_PROCESS_ENTRIES = 96
  constant MAX_APP_LINES (line 37) | const MAX_APP_LINES = 16
  constant MAX_LOG_LINES (line 38) | const MAX_LOG_LINES = 20
  constant MAX_LOG_LINES_PER_APP (line 39) | const MAX_LOG_LINES_PER_APP = 2
  constant MAX_OBSERVED_APP_LINES (line 40) | const MAX_OBSERVED_APP_LINES = 16
  constant MAX_LOG_DIR_DEPTH (line 41) | const MAX_LOG_DIR_DEPTH = 3
  constant MAX_LOG_DIRECTORIES_SCANNED (line 42) | const MAX_LOG_DIRECTORIES_SCANNED = 600
  constant MAX_LOG_CANDIDATE_FILES (line 43) | const MAX_LOG_CANDIDATE_FILES = 2_400
  constant MAX_WINDOWS_ROOT_CHILDREN (line 44) | const MAX_WINDOWS_ROOT_CHILDREN = 140
  constant ACTIVITY_STATE_FILENAME (line 45) | const ACTIVITY_STATE_FILENAME = '.activity-state.json'
  constant MAX_ACTIVITY_STATE_APP_ENTRIES (line 46) | const MAX_ACTIVITY_STATE_APP_ENTRIES = 256
  class ActivityContextFile (line 48) | class ActivityContextFile extends ContextFile {
    method constructor (line 52) | public constructor(
    method generate (line 60) | public generate(): string {
    method formatDateTime (line 118) | private formatDateTime(value: string | number | Date): string {
    method aggregateAppActivity (line 122) | private aggregateAppActivity(
    method probeRecentAppLogs (line 165) | private probeRecentAppLogs(appNames: string[]): ActivityLogFileEntry[] {
    method getCandidateLogRoots (line 263) | private getCandidateLogRoots(): string[] {
    method discoverNestedLogRoots (line 295) | private discoverNestedLogRoots(baseDirectory: string): string[] {
    method shouldSkipLogDirectory (line 331) | private shouldSkipLogDirectory(directoryName: string): boolean {
    method isLikelyLogDirectoryName (line 348) | private isLikelyLogDirectoryName(directoryName: string): boolean {
    method isLikelyLogFileName (line 359) | private isLikelyLogFileName(fileName: string): boolean {
    method inferAppHint (line 371) | private inferAppHint(filePath: string, appTerms: string[]): string {
    method normalizeAppHint (line 381) | private normalizeAppHint(rawAppHint: string): string {
    method balanceRecentLogEntries (line 407) | private balanceRecentLogEntries(entries: ActivityLogFileEntry[]): Acti...
    method normalizeProcessName (line 433) | private normalizeProcessName(rawProcessName: string): string {
    method formatCpu (line 442) | private formatCpu(value: number, metric: RunningProcessEntry['cpuMetri...
    method loadTrackingState (line 454) | private loadTrackingState(): ActivityTrackingState {
    method updateTrackingState (line 490) | private updateTrackingState(
    method saveTrackingState (line 522) | private saveTrackingState(state: ActivityTrackingState): void {
    method formatObservedAppLines (line 533) | private formatObservedAppLines(
    method computeStateDeltaSeconds (line 550) | private computeStateDeltaSeconds(previousSampleAt: string, now: Date):...
    method getStateFilePath (line 565) | private getStateFilePath(): string {

FILE: server/src/core/context-manager/context-files/architecture-context-file.ts
  class ArchitectureContextFile (line 4) | class ArchitectureContextFile extends ContextFile {
    method generate (line 8) | public generate(): string {

FILE: server/src/core/context-manager/context-files/browser-history-context-file.ts
  type BrowserHistoryFlavor (line 10) | type BrowserHistoryFlavor = 'chromium' | 'firefox' | 'safari'
  type BrowserHistoryDatabase (line 12) | interface BrowserHistoryDatabase {
  type BrowserHistoryEntry (line 19) | interface BrowserHistoryEntry {
  type BrowserHistoryProbeResult (line 27) | interface BrowserHistoryProbeResult {
  constant MAX_DATABASES_TO_QUERY (line 35) | const MAX_DATABASES_TO_QUERY = 6
  constant MAX_OUTPUT_ENTRIES (line 36) | const MAX_OUTPUT_ENTRIES = 64
  constant MAX_URL_CHARS (line 37) | const MAX_URL_CHARS = 128
  class BrowserHistoryContextFile (line 39) | class BrowserHistoryContextFile extends ContextFile {
    method constructor (line 43) | public constructor(
    method generate (line 51) | public generate(): string {
    method probeBrowserHistory (line 80) | private probeBrowserHistory(): BrowserHistoryProbeResult {
    method queryHistoryEntries (line 153) | private queryHistoryEntries(
    method getBrowserHistoryDatabases (line 368) | private getBrowserHistoryDatabases(): BrowserHistoryDatabase[] {
    method getChromiumHistoryDatabases (line 376) | private getChromiumHistoryDatabases(): BrowserHistoryDatabase[] {
    method getFirefoxHistoryDatabases (line 508) | private getFirefoxHistoryDatabases(): BrowserHistoryDatabase[] {
    method formatDateTimeInUserTimezone (line 558) | private formatDateTimeInUserTimezone(value: string): string {
    method getSafariHistoryDatabases (line 566) | private getSafariHistoryDatabases(): BrowserHistoryDatabase[] {

FILE: server/src/core/context-manager/context-files/gpu-compute-context-file.ts
  class GpuComputeContextFile (line 20) | class GpuComputeContextFile extends ContextFile {
    method constructor (line 24) | public constructor(
    method generate (line 32) | public generate(): string {

FILE: server/src/core/context-manager/context-files/habits-context-file.ts
  type DayBucket (line 11) | type DayBucket =
  type TimeBucket (line 19) | type TimeBucket = 'night' | 'morning' | 'afternoon' | 'evening'
  type HabitsState (line 21) | interface HabitsState {
  constant EMPTY_TIME_BUCKETS (line 28) | const EMPTY_TIME_BUCKETS: Record<TimeBucket, Record<string, number>> = {
  constant EMPTY_DAY_BUCKETS (line 34) | const EMPTY_DAY_BUCKETS: Record<DayBucket, Record<string, number>> = {
  constant FALLBACK_STATE (line 43) | const FALLBACK_STATE: HabitsState = {
  constant MAX_APP_LINES (line 50) | const MAX_APP_LINES = 20
  constant MAX_BUCKET_LINES (line 51) | const MAX_BUCKET_LINES = 16
  constant MAX_STATE_APPS_PER_BUCKET (line 52) | const MAX_STATE_APPS_PER_BUCKET = 250
  class HabitsContextFile (line 54) | class HabitsContextFile extends ContextFile {
    method constructor (line 63) | public constructor(
    method generate (line 71) | public generate(): string {
    method aggregateActiveApps (line 148) | private aggregateActiveApps(entries: RunningProcessEntry[]): string[] {
    method normalizeState (line 152) | private normalizeState(state: HabitsState, nowIso: string): HabitsState {
    method updateState (line 163) | private updateState(
    method compactBucket (line 204) | private compactBucket(bucket: Record<string, number>): Record<string, ...
    method getTopAppsFromBuckets (line 218) | private getTopAppsFromBuckets(
    method getTopAppsFromSingleBucket (line 234) | private getTopAppsFromSingleBucket(
    method normalizeBuckets (line 242) | private normalizeBuckets<TBucket extends string>(
    method getTimeBucket (line 257) | private getTimeBucket(now: Date): TimeBucket {
    method getDayBucket (line 271) | private getDayBucket(now: Date): DayBucket {
    method computeDeltaSeconds (line 286) | private computeDeltaSeconds(lastSampleAt: string, now: Date): number {
    method normalizeProcessName (line 300) | private normalizeProcessName(rawName: string): string {
    method isValidDate (line 309) | private isValidDate(value: string): boolean {

FILE: server/src/core/context-manager/context-files/home-context-file.ts
  class HomeContextFile (line 16) | class HomeContextFile extends ContextFile {
    method constructor (line 20) | public constructor(ttlMs: number) {
    method generate (line 25) | public generate(): string {

FILE: server/src/core/context-manager/context-files/host-system-context-file.ts
  class HostSystemContextFile (line 8) | class HostSystemContextFile extends ContextFile {
    method constructor (line 12) | public constructor(
    method generate (line 20) | public generate(): string {

FILE: server/src/core/context-manager/context-files/leon-context-file.ts
  class LeonContextFile (line 4) | class LeonContextFile extends ContextFile {
    method generate (line 8) | public generate(): string {

FILE: server/src/core/context-manager/context-files/leon-runtime-context-file.ts
  type LeonRuntimeContextResolvers (line 14) | interface LeonRuntimeContextResolvers {
  class LeonRuntimeContextFile (line 20) | class LeonRuntimeContextFile extends ContextFile {
    method constructor (line 24) | public constructor(
    method generate (line 33) | public generate(): string {

FILE: server/src/core/context-manager/context-files/local-inventory-context-file.ts
  type LocalInventoryAppStateEntry (line 14) | interface LocalInventoryAppStateEntry {
  type LocalInventoryState (line 20) | interface LocalInventoryState {
  type ActiveAppAggregate (line 26) | interface ActiveAppAggregate {
  type PeripheralsSnapshot (line 35) | interface PeripheralsSnapshot {
  constant MAX_RUNNING_APPS (line 46) | const MAX_RUNNING_APPS = 32
  constant MAX_INSTALLED_APPS (line 47) | const MAX_INSTALLED_APPS = 80
  constant MAX_CATEGORY_LINES (line 48) | const MAX_CATEGORY_LINES = 14
  constant MAX_PERIPHERAL_ITEMS (line 49) | const MAX_PERIPHERAL_ITEMS = 8
  constant MAX_STATE_APPS (line 50) | const MAX_STATE_APPS = 500
  constant FALLBACK_STATE (line 52) | const FALLBACK_STATE: LocalInventoryState = {
  class LocalInventoryContextFile (line 58) | class LocalInventoryContextFile extends ContextFile {
    method constructor (line 67) | public constructor(
    method generate (line 75) | public generate(): string {
    method aggregateActiveApps (line 142) | private aggregateActiveApps(entries: RunningProcessEntry[]): ActiveApp...
    method discoverInstalledApps (line 182) | private discoverInstalledApps(): string[] {
    method discoverInstalledAppsLinux (line 194) | private discoverInstalledAppsLinux(): string[] {
    method discoverInstalledAppsMacOS (line 247) | private discoverInstalledAppsMacOS(): string[] {
    method discoverInstalledAppsWindows (line 273) | private discoverInstalledAppsWindows(): string[] {
    method probePeripherals (line 305) | private probePeripherals(): PeripheralsSnapshot {
    method probePeripheralsLinux (line 317) | private probePeripheralsLinux(): PeripheralsSnapshot {
    method probePeripheralsMacOS (line 393) | private probePeripheralsMacOS(): PeripheralsSnapshot {
    method probePeripheralsWindows (line 444) | private probePeripheralsWindows(): PeripheralsSnapshot {
    method normalizePeripherals (line 528) | private normalizePeripherals(snapshot: PeripheralsSnapshot): Periphera...
    method normalizeState (line 551) | private normalizeState(state: LocalInventoryState, nowIso: string): Lo...
    method updateState (line 564) | private updateState(
    method getAppsRankedByUsage (line 613) | private getAppsRankedByUsage(
    method buildCategoryCounts (line 638) | private buildCategoryCounts(appNames: string[]): Array<{ category: str...
    method detectCategory (line 651) | private detectCategory(appName: string): string {
    method computeDeltaSeconds (line 672) | private computeDeltaSeconds(lastSampleAt: string, now: Date): number {
    method isIsoDate (line 686) | private isIsoDate(value: string): boolean {
    method normalizeProcessName (line 694) | private normalizeProcessName(rawName: string): string {
    method formatList (line 703) | private formatList(values: string[], maxItems: number): string {

FILE: server/src/core/context-manager/context-files/media-profile-context-file.ts
  type MediaProfileState (line 10) | interface MediaProfileState {
  type BrowserHistoryRecord (line 17) | interface BrowserHistoryRecord {
  constant FALLBACK_STATE (line 23) | const FALLBACK_STATE: MediaProfileState = {
  constant MAX_DOMAINS (line 30) | const MAX_DOMAINS = 24
  constant MAX_SEEN_ENTRIES (line 31) | const MAX_SEEN_ENTRIES = 4000
  class MediaProfileContextFile (line 33) | class MediaProfileContextFile extends ContextFile {
    method constructor (line 42) | public constructor(
    method generate (line 50) | public generate(): string {
    method loadBrowserHistoryRecords (line 96) | private loadBrowserHistoryRecords(browserHistoryPath: string): Browser...
    method normalizeState (line 130) | private normalizeState(state: MediaProfileState, nowIso: string): Medi...
    method updateState (line 147) | private updateState(
    method rankCounts (line 185) | private rankCounts(counts: Record<string, number>): Array<{ key: strin...
    method buildMediaSignals (line 192) | private buildMediaSignals(

FILE: server/src/core/context-manager/context-files/network-ecosystem-context-file.ts
  type DiscoveredNeighbor (line 10) | interface DiscoveredNeighbor {
  type EcosystemDeviceState (line 18) | interface EcosystemDeviceState {
  type LocalEcosystemState (line 29) | interface LocalEcosystemState {
  constant FALLBACK_STATE (line 35) | const FALLBACK_STATE: LocalEcosystemState = {
  constant MAX_NEIGHBORS (line 41) | const MAX_NEIGHBORS = 40
  constant MAX_DEVICE_STATE (line 42) | const MAX_DEVICE_STATE = 1000
  constant MAX_SERVICE_LINES (line 43) | const MAX_SERVICE_LINES = 18
  constant MAX_ACTIVE_SCAN_TARGETS (line 44) | const MAX_ACTIVE_SCAN_TARGETS = 320
  constant PREFERRED_SUBNET_PREFIX (line 45) | const PREFERRED_SUBNET_PREFIX = '192.168.0'
  constant PREFERRED_SUBNET_MAX_HOST (line 46) | const PREFERRED_SUBNET_MAX_HOST = 254
  class NetworkEcosystemContextFile (line 48) | class NetworkEcosystemContextFile extends ContextFile {
    method constructor (line 57) | public constructor(
    method generate (line 65) | public generate(): string {
    method buildNetworkInterfaceLines (line 158) | private buildNetworkInterfaceLines(
    method buildActiveProbeTargets (line 181) | private buildActiveProbeTargets(
    method hasPreferredSubnetInterface (line 253) | private hasPreferredSubnetInterface(
    method shouldKeepNeighbor (line 275) | private shouldKeepNeighbor(ip: string, hasPreferredSubnet: boolean): b...
    method probeNeighbors (line 287) | private probeNeighbors(): DiscoveredNeighbor[] {
    method probeNeighborsLinux (line 299) | private probeNeighborsLinux(): DiscoveredNeighbor[] {
    method probeNeighborsMacOS (line 327) | private probeNeighborsMacOS(): DiscoveredNeighbor[] {
    method probeNeighborsWindows (line 355) | private probeNeighborsWindows(): DiscoveredNeighbor[] {
    method deduplicateNeighbors (line 391) | private deduplicateNeighbors(neighbors: DiscoveredNeighbor[]): Discove...
    method normalizeState (line 407) | private normalizeState(
    method updateState (line 423) | private updateState(
    method getRankedDevices (line 492) | private getRankedDevices(devices: Record<string, EcosystemDeviceState>...
    method normalizeDeviceStateEntries (line 509) | private normalizeDeviceStateEntries(
    method inferDeviceHint (line 538) | private inferDeviceHint(neighbor: DiscoveredNeighbor): string {
    method buildDeviceIdentifier (line 573) | private buildDeviceIdentifier(neighbor: DiscoveredNeighbor, hint: stri...
    method detectVendorFromMac (line 590) | private detectVendorFromMac(
    method isPrivateIpv4 (line 641) | private isPrivateIpv4(ip: string): boolean {
    method buildServiceSignals (line 669) | private buildServiceSignals(neighbors: DiscoveredNeighbor[]): string[] {
    method isValidDate (line 707) | private isValidDate(value: string): boolean {

FILE: server/src/core/context-manager/context-files/owner-context-file.ts
  constant OWNER_CONTEXT_TTL_MS (line 10) | const OWNER_CONTEXT_TTL_MS: number | null = null
  class OwnerContextFile (line 12) | class OwnerContextFile extends ContextFile {
    method constructor (line 16) | public constructor(ttlMs: number | null) {
    method generate (line 21) | public generate(): string {

FILE: server/src/core/context-manager/context-files/storage-context-file.ts
  class StorageContextFile (line 5) | class StorageContextFile extends ContextFile {
    method constructor (line 9) | public constructor(
    method generate (line 17) | public generate(): string {

FILE: server/src/core/context-manager/context-files/system-resources-context-file.ts
  class SystemResourcesContextFile (line 8) | class SystemResourcesContextFile extends ContextFile {
    method constructor (line 12) | public constructor(
    method generate (line 20) | public generate(): string {

FILE: server/src/core/context-manager/context-files/workspace-intelligence-context-file.ts
  type RepositoryStateEntry (line 10) | interface RepositoryStateEntry {
  type WorkspaceState (line 16) | interface WorkspaceState {
  type RepositorySnapshot (line 22) | interface RepositorySnapshot {
  type ToolchainEntry (line 31) | interface ToolchainEntry {
  constant FALLBACK_STATE (line 36) | const FALLBACK_STATE: WorkspaceState = {
  constant MAX_REPOS (line 42) | const MAX_REPOS = 24
  constant MAX_STATE_REPOS (line 43) | const MAX_STATE_REPOS = 600
  constant MAX_LANG_LINES (line 44) | const MAX_LANG_LINES = 12
  constant MAX_TOOLCHAINS (line 45) | const MAX_TOOLCHAINS = 12
  class WorkspaceIntelligenceContextFile (line 47) | class WorkspaceIntelligenceContextFile extends ContextFile {
    method constructor (line 56) | public constructor(
    method generate (line 64) | public generate(): string {
    method getWorkspaceRoots (line 119) | private getWorkspaceRoots(): string[] {
    method discoverRepositories (line 133) | private discoverRepositories(roots: string[]): string[] {
    method buildRepositorySnapshot (line 192) | private buildRepositorySnapshot(repoPath: string): RepositorySnapshot ...
    method probeRepositoryLanguage (line 224) | private probeRepositoryLanguage(repoPath: string): {
    method extensionToLanguage (line 296) | private extensionToLanguage(extension: string): string {
    method normalizeState (line 321) | private normalizeState(state: WorkspaceState, nowIso: string): Workspa...
    method updateState (line 334) | private updateState(
    method buildLanguageDistribution (line 383) | private buildLanguageDistribution(
    method probeToolchainAvailability (line 397) | private probeToolchainAvailability(): ToolchainEntry[] {
    method isValidDate (line 421) | private isValidDate(value: string): boolean {

FILE: server/src/core/context-manager/context-manager.ts
  type ContextFileMetadata (line 22) | interface ContextFileMetadata {
  constant CONTEXT_FILES_SOURCE_DIR (line 26) | const CONTEXT_FILES_SOURCE_DIR = path.join(
  constant CONTEXT_MANAGER_DIR (line 30) | const CONTEXT_MANAGER_DIR = path.dirname(fileURLToPath(import.meta.url))
  constant SOURCE_AWARE_STATIC_CONTEXT_FILES (line 31) | const SOURCE_AWARE_STATIC_CONTEXT_FILES = new Set([
  constant BOOT_REFRESH_MIN_DELAY_MS (line 35) | const BOOT_REFRESH_MIN_DELAY_MS = 6_000
  constant BOOT_REFRESH_MAX_DELAY_MS (line 36) | const BOOT_REFRESH_MAX_DELAY_MS = 20_000
  constant BOOT_REFRESH_RETRY_DELAY_MS (line 37) | const BOOT_REFRESH_RETRY_DELAY_MS = 4_000
  constant BOOT_REFRESH_MAX_DEFERRAL_MS (line 38) | const BOOT_REFRESH_MAX_DEFERRAL_MS = 60_000
  constant BOOT_REFRESH_DEFER_LOAD_RATIO (line 39) | const BOOT_REFRESH_DEFER_LOAD_RATIO = 0.85
  constant BOOT_REFRESH_PRIORITY_FILENAMES (line 40) | const BOOT_REFRESH_PRIORITY_FILENAMES = [
  constant BOOT_REFRESH_TIMER_LABEL (line 46) | const BOOT_REFRESH_TIMER_LABEL = 'Context files boot refresh total'
  constant PERIODIC_REFRESH_TIMER_LABEL (line 47) | const PERIODIC_REFRESH_TIMER_LABEL = 'Context files periodic refresh total'
  constant READ_REFRESH_TIMER_LABEL (line 48) | const READ_REFRESH_TIMER_LABEL = 'Context files read refresh total'
  constant CONTEXT_REFRESH_WORKER_SRC_PATH (line 49) | const CONTEXT_REFRESH_WORKER_SRC_PATH = path.join(
  constant CONTEXT_REFRESH_WORKER_DIST_PATH (line 53) | const CONTEXT_REFRESH_WORKER_DIST_PATH = path.join(
  constant CONTEXT_REFRESH_WORKER_MAX_BUFFER (line 57) | const CONTEXT_REFRESH_WORKER_MAX_BUFFER = 1024 * 1024 * 8
  constant RETIRED_CONTEXT_FILES (line 58) | const RETIRED_CONTEXT_FILES = [
  constant RETIRED_STATE_FILES (line 64) | const RETIRED_STATE_FILES = ['.media-tastes-state.json']
  function clamp (line 66) | function clamp(value: number, min: number, max: number): number {
  class ContextManager (line 72) | class ContextManager {
    method constructor (line 100) | public constructor() {
    method isLoaded (line 109) | public get isLoaded(): boolean {
    method load (line 113) | public async load(): Promise<void> {
    method refreshContextFilesAtBootInBackground (line 138) | private refreshContextFilesAtBootInBackground(): void {
    method getManifest (line 195) | public getManifest(): string {
    method getContextFileContent (line 207) | public getContextFileContent(filename: string): string | null {
    method getContextForToolkit (line 237) | public getContextForToolkit(toolkitId: string): string {
    method getContextFilesForToolkit (line 257) | public getContextFilesForToolkit(toolkitId: string): string[] {
    method getContextFilePath (line 274) | private getContextFilePath(filename: string): string {
    method normalizeFilename (line 278) | private normalizeFilename(filename: string): string {
    method resolveDefinition (line 289) | private resolveDefinition(filename: string): ContextFile | null {
    method isContextFileStale (line 302) | private isContextFileStale(definition: ContextFile): boolean {
    method getContextSourceUpdatedAt (line 345) | private getContextSourceUpdatedAt(definition: ContextFile): number | n...
    method resolveContextSourcePath (line 358) | private resolveContextSourcePath(definition: ContextFile): string | nu...
    method getContextSourceBasename (line 373) | private getContextSourceBasename(filename: string): string {
    method getBootRefreshPriority (line 377) | private getBootRefreshPriority(filename: string): number {
    method getNormalizedLoadRatio (line 386) | private getNormalizedLoadRatio(): number {
    method getAdaptiveBootInitialDelayMs (line 392) | private getAdaptiveBootInitialDelayMs(): number {
    method getAdaptiveBootRetryDelayMs (line 405) | private getAdaptiveBootRetryDelayMs(): number {
    method shouldDeferBootRefresh (line 411) | private shouldDeferBootRefresh(elapsedMs: number): boolean {
    method getContextRefreshWorkerArgs (line 419) | private getContextRefreshWorkerArgs(): string[] {
    method refreshContextFileInChildProcess (line 432) | private async refreshContextFileInChildProcess(
    method queueRefresh (line 483) | private queueRefresh(
    method runBackgroundRefresh (line 514) | private async runBackgroundRefresh(
    method getStaleContextFiles (line 556) | private getStaleContextFiles(): ContextFile[] {
    method sortContextDefinitions (line 562) | private sortContextDefinitions(definitions: ContextFile[]): ContextFil...
    method yieldToEventLoop (line 574) | private async yieldToEventLoop(): Promise<void> {
    method logContextFilesUpdated (line 583) | private logContextFilesUpdated(reason: string, filenames: string[]): v...
    method syncContextReadFilenameEnum (line 595) | private async syncContextReadFilenameEnum(): Promise<void> {
    method refreshContextFile (line 627) | private refreshContextFile(definition: ContextFile, force = false): bo...
    method ensureTrailingNewline (line 651) | private ensureTrailingNewline(content: string): string {
    method extractSummary (line 659) | private extractSummary(content: string): string | null {
    method buildManifest (line 672) | private buildManifest(): string {
    method schedulePeriodicRefresh (line 693) | private schedulePeriodicRefresh(): void {
    method parseContextFileList (line 710) | private parseContextFileList(rawFileList: string): Set<string> {
    method cleanupDisabledContextFiles (line 719) | private cleanupDisabledContextFiles(): void {
    method cleanupRetiredContextFiles (line 736) | private cleanupRetiredContextFiles(): void {

FILE: server/src/core/context-manager/context-probe-helper.ts
  type CommandProbe (line 7) | interface CommandProbe {
  type DefaultRouteProbe (line 12) | interface DefaultRouteProbe {
  type NvidiaSmiProbe (line 17) | interface NvidiaSmiProbe {
  type StorageSnapshotEntry (line 26) | interface StorageSnapshotEntry {
  type StorageSnapshot (line 35) | interface StorageSnapshot {
  type OwnerLocationProbeSource (line 41) | type OwnerLocationProbeSource =
  type OwnerLocationProbeConfidence (line 49) | type OwnerLocationProbeConfidence = 'high' | 'medium' | 'low'
  type OwnerLocationProbe (line 51) | interface OwnerLocationProbe {
  type VpnProxyProbe (line 57) | interface VpnProxyProbe {
  type NeighborWarmupProbe (line 66) | interface NeighborWarmupProbe {
  type ReverseDnsProbe (line 72) | interface ReverseDnsProbe {
  type IpGeolocationRecord (line 78) | interface IpGeolocationRecord {
  type ProcessCpuMetric (line 89) | type ProcessCpuMetric = 'percent' | 'seconds'
  type RunningProcessEntry (line 91) | interface RunningProcessEntry {
  type RunningProcessSnapshot (line 101) | interface RunningProcessSnapshot {
  class ContextProbeHelper (line 107) | class ContextProbeHelper {
    method getSafeUsername (line 108) | public getSafeUsername(): string {
    method runCommand (line 116) | public runCommand(
    method probeCommandVersion (line 140) | public probeCommandVersion(command: string, args: string[]): CommandPr...
    method formatCommandProbe (line 161) | public formatCommandProbe(commandProbe: CommandProbe): string {
    method getOperatingSystemNameVersion (line 169) | public getOperatingSystemNameVersion(): string {
    method parseKeyValueFile (line 236) | public parseKeyValueFile(content: string): Record<string, string> {
    method formatGiB (line 265) | public formatGiB(bytes: number): string {
    method formatUptime (line 273) | public formatUptime(totalSeconds: number): string {
    method redactProxyValue (line 295) | public redactProxyValue(proxyValue: string): string {
    method isLikelyTunnelInterface (line 317) | public isLikelyTunnelInterface(interfaceName: string): boolean {
    method probeDefaultRoute (line 332) | public probeDefaultRoute(): DefaultRouteProbe {
    method probeNvidiaSmi (line 344) | public probeNvidiaSmi(): NvidiaSmiProbe {
    method probeStorage (line 386) | public probeStorage(): StorageSnapshot {
    method probeOwnerLocation (line 394) | public probeOwnerLocation(options: {
    method probeVpnOrProxyStatus (line 454) | public probeVpnOrProxyStatus(): VpnProxyProbe {
    method warmNeighborCache (line 521) | public warmNeighborCache(ipAddresses: string[]): NeighborWarmupProbe {
    method probeReverseDnsHostnames (line 622) | public probeReverseDnsHostnames(ipAddresses: string[]): ReverseDnsProbe {
    method probeRunningProcesses (line 742) | public probeRunningProcesses(limit = 80): RunningProcessSnapshot {
    method getCommandCandidates (line 750) | private getCommandCandidates(command: string): string[] {
    method parseLinuxOsRelease (line 758) | private parseLinuxOsRelease(): {
    method extractCityFromTimeZone (line 790) | private extractCityFromTimeZone(timeZone: string): string {
    method extractRegionFromLocale (line 804) | private extractRegionFromLocale(locale: string): string {
    method probeOwnerLocationFromIpGeolocation (line 817) | private probeOwnerLocationFromIpGeolocation(
    method fetchIpGeolocationRecords (line 933) | private fetchIpGeolocationRecords(): IpGeolocationRecord[] {
    method probeDefaultRouteLinux (line 1092) | private probeDefaultRouteLinux(): DefaultRouteProbe {
    method probeDefaultRouteMacOS (line 1140) | private probeDefaultRouteMacOS(): DefaultRouteProbe {
    method probeDefaultRouteWindows (line 1163) | private probeDefaultRouteWindows(): DefaultRouteProbe {
    method extractPrefixedLineValue (line 1199) | private extractPrefixedLineValue(
    method probeStorageUnix (line 1224) | private probeStorageUnix(): StorageSnapshot {
    method probeStorageWindows (line 1268) | private probeStorageWindows(): StorageSnapshot {
    method probeRunningProcessesUnix (line 1342) | private probeRunningProcessesUnix(limit: number): RunningProcessSnapsh...
    method probeRunningProcessesWindows (line 1401) | private probeRunningProcessesWindows(limit: number): RunningProcessSna...
    method parseUnixProcessLine (line 1516) | private parseUnixProcessLine(
    method parseElapsedDuration (line 1559) | private parseElapsedDuration(duration: string): number {
    method formatStartedAt (line 1597) | private formatStartedAt(runtimeSeconds: number): string {
    method isRunningProcessEntry (line 1605) | private isRunningProcessEntry(

FILE: server/src/core/context-manager/context-refresh-worker.ts
  type WorkerInput (line 4) | interface WorkerInput {
  function parseArgs (line 11) | function parseArgs(argv: string[]): WorkerInput {
  function main (line 53) | async function main(): Promise<void> {

FILE: server/src/core/context-manager/context-state-store.ts
  class ContextStateStore (line 6) | class ContextStateStore<T> {
    method constructor (line 9) | public constructor(stateFilename: string, private readonly fallback: T) {
    method load (line 13) | public load(): T {
    method save (line 26) | public save(state: T): void {
    method clone (line 35) | private clone(value: T): T {

FILE: server/src/core/context-manager/owner-profile-sync.ts
  constant OWNER_DOCUMENT_TOKEN_BUDGET (line 19) | const OWNER_DOCUMENT_TOKEN_BUDGET = 2_000
  constant OWNER_DOCUMENT_UPDATE_TIMEOUT_MS (line 20) | const OWNER_DOCUMENT_UPDATE_TIMEOUT_MS = 30_000
  constant OWNER_DOCUMENT_COMPACT_TIMEOUT_MS (line 21) | const OWNER_DOCUMENT_COMPACT_TIMEOUT_MS = 30_000
  constant OWNER_DOCUMENT_VERIFY_TIMEOUT_MS (line 22) | const OWNER_DOCUMENT_VERIFY_TIMEOUT_MS = 15_000
  constant OWNER_DOCUMENT_MAX_RETRIES (line 23) | const OWNER_DOCUMENT_MAX_RETRIES = 1
  constant OWNER_DOCUMENT_UPDATE_MAX_TOKENS (line 24) | const OWNER_DOCUMENT_UPDATE_MAX_TOKENS = 2_000
  constant OWNER_DOCUMENT_COMPACT_MAX_TOKENS (line 25) | const OWNER_DOCUMENT_COMPACT_MAX_TOKENS = 2_000
  constant OWNER_DOCUMENT_VERIFY_MAX_TOKENS (line 26) | const OWNER_DOCUMENT_VERIFY_MAX_TOKENS = 500
  constant OWNER_TURN_MAX_USER_CHARS (line 27) | const OWNER_TURN_MAX_USER_CHARS = 1_200
  constant OWNER_TURN_MAX_ASSISTANT_CHARS (line 28) | const OWNER_TURN_MAX_ASSISTANT_CHARS = 600
  constant OWNER_MEMORY_ITEM_MAX_TITLE_CHARS (line 29) | const OWNER_MEMORY_ITEM_MAX_TITLE_CHARS = 120
  constant OWNER_MEMORY_ITEM_MAX_CONTENT_CHARS (line 30) | const OWNER_MEMORY_ITEM_MAX_CONTENT_CHARS = 240
  type OwnerTurnToolExecution (line 32) | interface OwnerTurnToolExecution {
  type OwnerMemoryItem (line 38) | interface OwnerMemoryItem {
  type OwnerDocumentVerification (line 43) | interface OwnerDocumentVerification {
  type OwnerStaticFields (line 48) | type OwnerStaticFields = Pick<
  constant OWNER_DOCUMENT_VERIFICATION_SCHEMA (line 61) | const OWNER_DOCUMENT_VERIFICATION_SCHEMA = {
  constant OWNER_STATIC_FIELDS_SCHEMA (line 74) | const OWNER_STATIC_FIELDS_SCHEMA = {
  function normalizeText (line 101) | function normalizeText(value: string): string {
  function truncateText (line 105) | function truncateText(value: string, maxChars: number): string {
  function stripMarkdownFences (line 114) | function stripMarkdownFences(value: string): string {
  function estimateTokenCount (line 122) | function estimateTokenCount(value: string): number {
  function areOwnerProfilesEquivalent (line 126) | function areOwnerProfilesEquivalent(
  function areOwnerDocumentProfilesEquivalent (line 139) | function areOwnerDocumentProfilesEquivalent(
  function extractOwnerStaticFieldsFromOutput (line 170) | function extractOwnerStaticFieldsFromOutput(output: unknown): OwnerStati...
  function extractOwnerMemoryItemsFromToolExecutions (line 201) | function extractOwnerMemoryItemsFromToolExecutions(
  function parsedInputLike (line 288) | function parsedInputLike(value: unknown): value is Record<string, unknow...
  function parseOwnerDocumentCandidate (line 292) | function parseOwnerDocumentCandidate(
  function promptForOwnerDocument (line 316) | async function promptForOwnerDocument(
  function repairOwnerDocumentCandidate (line 344) | async function repairOwnerDocumentCandidate(
  function rewriteOwnerDocumentFromTurn (line 388) | async function rewriteOwnerDocumentFromTurn(
  function compactOwnerDocument (line 454) | async function compactOwnerDocument(
  function verifyOwnerDocumentPreservesFacts (line 501) | async function verifyOwnerDocumentPreservesFacts(
  function extractOwnerStaticFields (line 546) | async function extractOwnerStaticFields(
  function writeOwnerArtifacts (line 587) | async function writeOwnerArtifacts(
  function syncOwnerProfileFromTurn (line 647) | async function syncOwnerProfileFromTurn(

FILE: server/src/core/context-manager/owner-profile.ts
  constant OWNER_CONTEXT_PATH (line 7) | const OWNER_CONTEXT_PATH = path.join(CONTEXT_PATH, 'OWNER.md')
  constant OWNER_PROFILE_PATH (line 8) | const OWNER_PROFILE_PATH = path.join(
  constant LEGACY_OWNER_PROFILE_PATH (line 12) | const LEGACY_OWNER_PROFILE_PATH = path.join(
  constant LEGACY_OWNER_MEMORY_PATH (line 17) | const LEGACY_OWNER_MEMORY_PATH = path.join(
  type LegacyOwnerSeed (line 25) | interface LegacyOwnerSeed {
  type OwnerProfileSectionKey (line 30) | type OwnerProfileSectionKey =
  type OwnerProfile (line 40) | interface OwnerProfile {
  constant OWNER_PROFILE_SECTIONS (line 61) | const OWNER_PROFILE_SECTIONS: Array<{
  constant OWNER_PROFILE_SCHEMA (line 108) | const OWNER_PROFILE_SCHEMA = {
  function createEmptyOwnerProfile (line 193) | function createEmptyOwnerProfile(): OwnerProfile {
  function normalizeLine (line 216) | function normalizeLine(value: unknown): string {
  function normalizeLines (line 224) | function normalizeLines(value: unknown): string[] {
  function normalizeNullableLine (line 242) | function normalizeNullableLine(value: unknown): string | null {
  function normalizeOwnerProfile (line 247) | function normalizeOwnerProfile(value: unknown): OwnerProfile {
  function readOwnerProfileCacheSync (line 278) | function readOwnerProfileCacheSync(): OwnerProfile {
  function getSectionByTitle (line 297) | function getSectionByTitle(title: string): {
  function clipText (line 305) | function clipText(value: string, maxChars: number): string {
  function parseOwnerDocument (line 313) | function parseOwnerDocument(content: string): OwnerProfile {
  function readOwnerDocumentSync (line 351) | function readOwnerDocumentSync(): string {
  function readOwnerProfileSync (line 363) | function readOwnerProfileSync(): OwnerProfile {
  function writeOwnerProfile (line 384) | async function writeOwnerProfile(profile: OwnerProfile): Promise<void> {
  function readLegacyOwnerSeedSync (line 400) | function readLegacyOwnerSeedSync(): LegacyOwnerSeed | null {
  function applyLegacyOwnerSeed (line 424) | function applyLegacyOwnerSeed(profile: OwnerProfile): OwnerProfile {
  function getOwnerProfileLineCount (line 455) | function getOwnerProfileLineCount(profile: OwnerProfile): number {
  function getOwnerProfileFilledSectionCount (line 462) | function getOwnerProfileFilledSectionCount(profile: OwnerProfile): number {
  function getOwnerProfileMissingSectionTitles (line 468) | function getOwnerProfileMissingSectionTitles(
  function buildOwnerManifest (line 476) | function buildOwnerManifest(profile: OwnerProfile): string {
  function buildOwnerDocument (line 504) | function buildOwnerDocument(profile: OwnerProfile): string {

FILE: server/src/core/http-server/api/llm-inference/post.ts
  type PostLLMInferenceSchema (line 16) | interface PostLLMInferenceSchema {
  constant LLM_DUTIES_MAP (line 24) | const LLM_DUTIES_MAP = {
  function resolveLLMDuty (line 35) | async function resolveLLMDuty(

FILE: server/src/core/http-server/api/open-path/post.ts
  function expandHomeAlias (line 11) | function expandHomeAlias(inputPath: string): string {
  function openResolvedPath (line 23) | function openResolvedPath(

FILE: server/src/core/http-server/api/utterance/post.ts
  type PostUtteranceSchema (line 14) | interface PostUtteranceSchema {

FILE: server/src/core/http-server/http-server.ts
  type APIOptions (line 29) | interface APIOptions {
  class HTTPServer (line 33) | class HTTPServer {
    method constructor (line 40) | constructor(
    method init (line 58) | public async init(): Promise<void> {
    method bootstrap (line 95) | private async bootstrap(): Promise<void> {
    method listen (line 134) | private async listen(): Promise<void> {

FILE: server/src/core/http-server/old-server.js
  method handler (line 119) | async handler(request, reply) {

FILE: server/src/core/index.ts
  constant PYTHON_TCP_CLIENT (line 35) | const PYTHON_TCP_CLIENT = new TCPClient(
  constant EVENT_EMITTER (line 41) | const EVENT_EMITTER = new EventEmitter()
  constant LLM_PROVIDER (line 47) | const LLM_PROVIDER = new LLMProvider()
  constant LLM_MANAGER (line 49) | const LLM_MANAGER = new LLMManager()
  constant CONVERSATION_LOGGER (line 51) | const CONVERSATION_LOGGER = new ConversationLogger({
  constant LOOP_CONVERSATION_LOGGER (line 57) | const LOOP_CONVERSATION_LOGGER = new ConversationLogger({
  constant TOOL_CALL_LOGGER (line 63) | const TOOL_CALL_LOGGER = new ToolCallLogger({
  constant HTTP_SERVER (line 69) | const HTTP_SERVER = new HTTPServer(String(HOST), PORT)
  constant SOCKET_SERVER (line 71) | const SOCKET_SERVER = new SocketServer()
  constant TOOLKIT_REGISTRY (line 73) | const TOOLKIT_REGISTRY = new ToolkitRegistry()
  constant TOOL_EXECUTOR (line 75) | const TOOL_EXECUTOR = new ToolExecutor()
  constant PERSONA (line 77) | const PERSONA = new Persona()
  constant CONTEXT_MANAGER (line 79) | const CONTEXT_MANAGER = new ContextManager()
  constant MEMORY_MANAGER (line 80) | const MEMORY_MANAGER = new MemoryManager()
  constant SELF_MODEL_MANAGER (line 81) | const SELF_MODEL_MANAGER = new SelfModelManager()
  constant PULSE_MANAGER (line 82) | const PULSE_MANAGER = new PulseManager()
  constant STT (line 84) | const STT = new SpeechToText()
  constant TTS (line 86) | const TTS = new TextToSpeech()
  constant ASR (line 88) | const ASR = new AutomaticSpeechRecognition()
  constant NER (line 90) | const NER = new NamedEntityRecognition()
  constant MODEL_LOADER (line 92) | const MODEL_LOADER = new ModelLoader()
  constant NLU (line 94) | const NLU = new NaturalLanguageUnderstanding()
  constant BRAIN (line 96) | const BRAIN = new Brain()

FILE: server/src/core/llm-manager/llm-duties/action-calling-llm-duty.ts
  type ActionCallingLLMDutyParams (line 28) | interface ActionCallingLLMDutyParams {
  constant CHAT_HISTORY_SIZE (line 33) | const CHAT_HISTORY_SIZE = 8
  class ActionCallingLLMDuty (line 35) | class ActionCallingLLMDuty extends LLMDuty {
    method constructor (line 85) | constructor(params: ActionCallingLLMDutyParams) {
    method parseOptionalParameters (line 103) | private parseOptionalParameters(
    method filterActionsWithFlow (line 143) | private filterActionsWithFlow(
    method actionsToFunctionsSchema (line 182) | private async actionsToFunctionsSchema(
    method actionsToOpenAITools (line 243) | private actionsToOpenAITools(
    method handlePreLLMInference (line 294) | private handlePreLLMInference(
    method init (line 352) | public async init(
    method execute (line 404) | public async execute(): Promise<LLMDutyResult | null> {

FILE: server/src/core/llm-manager/llm-duties/action-recognition-llm-duty.ts
  type ActionRecognitionLLMDutyParams (line 15) | interface ActionRecognitionLLMDutyParams extends LLMDutyParams {
  constant JSON_KEY_RESPONSE (line 21) | const JSON_KEY_RESPONSE = 'intent_name'
  class ActionRecognitionLLMDuty (line 23) | class ActionRecognitionLLMDuty extends LLMDuty {
    method constructor (line 33) | constructor(params: ActionRecognitionLLMDutyParams) {
    method init (line 65) | public async init(
    method execute (line 102) | public async execute(): Promise<LLMDutyResult | null> {

FILE: server/src/core/llm-manager/llm-duties/conversation-llm-duty.ts
  class ConversationLLMDuty (line 28) | class ConversationLLMDuty extends LLMDuty {
    method constructor (line 38) | constructor() {
    method init (line 56) | public async init(
    method execute (line 145) | public async execute(

FILE: server/src/core/llm-manager/llm-duties/custom-llm-duty.ts
  type CustomLLMDutyParams (line 13) | interface CustomLLMDutyParams extends LLMDutyParams {
  constant DEFAULT_DISPOSE_TIMEOUT (line 25) | const DEFAULT_DISPOSE_TIMEOUT = 60_000
  constant DEFAULT_THOUGHT_TOKENS_BUDGET (line 30) | const DEFAULT_THOUGHT_TOKENS_BUDGET = 128
  constant DEFAULT_TEMPERATURE (line 31) | const DEFAULT_TEMPERATURE = 0
  class CustomLLMDuty (line 33) | class CustomLLMDuty extends LLMDuty {
    method constructor (line 50) | constructor(params: CustomLLMDutyParams) {
    method resetDisposeTimer (line 77) | private resetDisposeTimer(): void {
    method dispose (line 109) | public static async dispose(): Promise<void> {
    method init (line 132) | public async init(): Promise<void> {
    method execute (line 183) | public async execute(): Promise<LLMDutyResult | null> {

FILE: server/src/core/llm-manager/llm-duties/custom-ner-llm-duty.ts
  type CustomNERLLMDutyParams (line 15) | interface CustomNERLLMDutyParams<T> extends LLMDutyParams {
  class CustomNERLLMDuty (line 21) | class CustomNERLLMDuty<T> extends LLMDuty {
    method constructor (line 32) | constructor(params: CustomNERLLMDutyParams<T>) {
    method init (line 46) | public async init(
    method execute (line 83) | public async execute(): Promise<LLMDutyResult | null> {

FILE: server/src/core/llm-manager/llm-duties/paraphrase-llm-duty.ts
  type ParaphraseLLMDutyParams (line 24) | type ParaphraseLLMDutyParams = LLMDutyParams
  class ParaphraseLLMDuty (line 26) | class ParaphraseLLMDuty extends LLMDuty {
    method constructor (line 47) | constructor(params: ParaphraseLLMDutyParams) {
    method init (line 67) | public async init(
    method execute (line 108) | public async execute(

FILE: server/src/core/llm-manager/llm-duties/react-llm-duty.ts
  constant REACT_CONTINUATION_STATE_FILENAME (line 99) | const REACT_CONTINUATION_STATE_FILENAME = '.react-execution-continuation...
  constant REACT_HISTORY_COMPACTION_STATE_FILENAME (line 100) | const REACT_HISTORY_COMPACTION_STATE_FILENAME =
  constant REACT_CONTINUATION_MAX_AGE_MS (line 102) | const REACT_CONTINUATION_MAX_AGE_MS = 30 * 60 * 1_000
  constant REACT_PROMPTS_LOG_DIR (line 103) | const REACT_PROMPTS_LOG_DIR = path.join(LOGS_PATH, 'prompts')
  type ReactHistoryCompactionScope (line 105) | type ReactHistoryCompactionScope = 'local' | 'remote'
  type ReactExecutionContinuationState (line 107) | interface ReactExecutionContinuationState {
  type ReactExecutionContinuationPayload (line 122) | interface ReactExecutionContinuationPayload {
  type PreparedReactHistory (line 127) | interface PreparedReactHistory {
  type ReactHistoryCompactionProviderState (line 132) | interface ReactHistoryCompactionProviderState {
  type ReactHistoryCompactionState (line 138) | interface ReactHistoryCompactionState {
  function buildProgressMessageFromSteps (line 144) | function buildProgressMessageFromSteps(steps: PlanStep[]): string | null {
  type ReactHistoryCompactionConfig (line 160) | interface ReactHistoryCompactionConfig {
  function createEmptyHistoryCompactionProviderState (line 165) | function createEmptyHistoryCompactionProviderState(): ReactHistoryCompac...
  constant REACT_HISTORY_COMPACTION_STATE_FALLBACK (line 173) | const REACT_HISTORY_COMPACTION_STATE_FALLBACK: ReactHistoryCompactionSta...
  class ReActLLMDuty (line 179) | class ReActLLMDuty extends LLMDuty {
    method constructor (line 218) | constructor(params: ReactLLMDutyParams) {
    method init (line 235) | public async init(
    method execute (line 283) | public async execute(): Promise<LLMDutyResult | null> {
    method loadPreparedHistory (line 963) | private async loadPreparedHistory(): Promise<PreparedReactHistory> {
    method getHistoryCompactionScope (line 986) | private getHistoryCompactionScope(): ReactHistoryCompactionScope {
    method getHistoryCompactionConfig (line 990) | private getHistoryCompactionConfig(): ReactHistoryCompactionConfig {
    method loadHistoryCompactionProviderState (line 1004) | private loadHistoryCompactionProviderState(
    method normalizeHistoryCompactionProviderState (line 1011) | private normalizeHistoryCompactionProviderState(
    method saveHistoryCompactionProviderState (line 1029) | private saveHistoryCompactionProviderState(
    method normalizeMessageLogs (line 1049) | private normalizeMessageLogs(value: unknown): MessageLog[] {
    method hasStoredHistoryCompactionState (line 1079) | private hasStoredHistoryCompactionState(
    method areMessageLogsEqual (line 1089) | private areMessageLogsEqual(left: MessageLog[], right: MessageLog[]): ...
    method areHistoryCompactionStatesEqual (line 1106) | private areHistoryCompactionStatesEqual(
    method synchronizeHistoryCompactionState (line 1117) | private synchronizeHistoryCompactionState(
    method buildHistoryForCurrentTurn (line 1168) | private buildHistoryForCurrentTurn(
    method getStateForPostAnswerCompaction (line 1184) | private getStateForPostAnswerCompaction(
    method rollHistoryCompactionState (line 1199) | private async rollHistoryCompactionState(
    method maybeCompactHistoryAfterAnswer (line 1245) | private async maybeCompactHistoryAfterAnswer(
    method buildHistoryFromCompactionState (line 1296) | private buildHistoryFromCompactionState(
    method buildPreparedHistory (line 1312) | private buildPreparedHistory(history: MessageLog[]): PreparedReactHist...
    method compactHistoryLogs (line 1331) | private async compactHistoryLogs(
    method getInputAsText (line 1415) | private getInputAsText(input: string | object | null): string {
    method loadValidExecutionContinuationState (line 1427) | private static loadValidExecutionContinuationState(): ReactExecutionCo...
    method loadExecutionContinuation (line 1448) | private loadExecutionContinuation(): ReactExecutionContinuationState |...
    method saveExecutionContinuation (line 1452) | private saveExecutionContinuation(state: ReactExecutionContinuationSta...
    method clearExecutionContinuation (line 1456) | private clearExecutionContinuation(): void {
    method consumeExecutionContinuation (line 1460) | private consumeExecutionContinuation(
    method pauseExecutionForClarification (line 1475) | private pauseExecutionForClarification(params: {
    method buildPausedTrackedSteps (line 1509) | private buildPausedTrackedSteps(
    method supportsNativeTools (line 1544) | private get supportsNativeTools(): boolean {
    method createLLMCaller (line 1552) | private createLLMCaller(
    method withLocalPromptSession (line 1574) | private async withLocalPromptSession<T>(
    method callLLM (line 1600) | private async callLLM(
    method callLLMText (line 1704) | private async callLLMText(
    method callLLMWithTools (line 1869) | private async callLLMWithTools(
    method safeJSONStringify (line 2193) | private safeJSONStringify(value: unknown): string {
    method resolveAllowedToolCallName (line 2201) | private resolveAllowedToolCallName(
    method estimateTokensFromText (line 2244) | private estimateTokensFromText(text: string): number {
    method estimateHistoryTokens (line 2252) | private estimateHistoryTokens(history?: MessageLog[]): number {
    method formatHistoryForPromptLog (line 2264) | private formatHistoryForPromptLog(history?: MessageLog[]): string {
    method buildLogTitle (line 2279) | private buildLogTitle(context?: string): string {
    method logTitle (line 2283) | private logTitle(context?: string): void {
    method writePhasePromptLog (line 2287) | private writePhasePromptLog(params: {
    method logPromptDispatch (line 2371) | private logPromptDispatch(params: {
    method compactSectionSourcePath (line 2453) | private compactSectionSourcePath(source: string): string {
    method buildDefaultPromptSections (line 2463) | private buildDefaultPromptSections(params: {
    method logPromptUsage (line 2510) | private logPromptUsage(
    method observeCompletionMetrics (line 2522) | private observeCompletionMetrics(params: {
    method logPromptReasoning (line 2585) | private logPromptReasoning(
    method buildLongToolCallReason (line 2599) | private buildLongToolCallReason(
    method runLongToolCallDiagnosis (line 2626) | private async runLongToolCallDiagnosis(
    method emitProgress (line 2665) | private async emitProgress(message: string): Promise<void> {
    method toProgressiveMessage (line 2680) | private toProgressiveMessage(message: string): string {
    method makeDutyResult (line 2695) | private makeDutyResult(output: string): LLMDutyResult {
    method getReasoningGenerationId (line 2755) | private getReasoningGenerationId(
    method emitReasoningToken (line 2769) | private emitReasoningToken(
    method emitSyntheticTokenStream (line 2788) | private emitSyntheticTokenStream(output: string): void {

FILE: server/src/core/llm-manager/llm-duties/react-llm-duty/catalog.ts
  function buildCatalog (line 9) | function buildCatalog(): Catalog {

FILE: server/src/core/llm-manager/llm-duties/react-llm-duty/constants.ts
  constant CATALOG_TOKEN_BUDGET (line 9) | const CATALOG_TOKEN_BUDGET = 2_000
  constant CHARS_PER_TOKEN (line 10) | const CHARS_PER_TOKEN = 4
  constant DUTY_NAME (line 11) | const DUTY_NAME = 'ReAct LLM Duty'
  constant FORMATTING_RULES (line 13) | const FORMATTING_RULES = `FORMATTING RULES for all user-facing text:
  constant PLAN_SYSTEM_PROMPT (line 21) | const PLAN_SYSTEM_PROMPT = `You are an autonomous planning and acting ag...
  constant EXECUTE_SYSTEM_PROMPT (line 83) | const EXECUTE_SYSTEM_PROMPT = `You are an autonomous acting agent execut...
  constant RESOLVE_FUNCTION_SYSTEM_PROMPT (line 117) | const RESOLVE_FUNCTION_SYSTEM_PROMPT = `You are selecting a function fro...
  constant RECOVERY_PLAN_SYSTEM_PROMPT (line 146) | const RECOVERY_PLAN_SYSTEM_PROMPT = `You are revising a failed execution...
  constant REACT_HISTORY_COMPACTION_SYSTEM_PROMPT (line 178) | const REACT_HISTORY_COMPACTION_SYSTEM_PROMPT = `You rewrite a bounded ro...
  constant MAX_EXECUTIONS (line 195) | const MAX_EXECUTIONS = 20
  constant MAX_REPLANS (line 196) | const MAX_REPLANS = 3
  constant MAX_RETRIES_PER_FUNCTION (line 197) | const MAX_RETRIES_PER_FUNCTION = 2
  constant MAX_TOOL_FAILURE_RETRIES (line 198) | const MAX_TOOL_FAILURE_RETRIES = 2
  constant REACT_TEMPERATURE (line 199) | const REACT_TEMPERATURE = 0.2
  constant REACT_INFERENCE_TIMEOUT_MS (line 200) | const REACT_INFERENCE_TIMEOUT_MS = 120_000
  constant REACT_TIMEOUT_MAX_RETRIES (line 201) | const REACT_TIMEOUT_MAX_RETRIES = 1
  constant FINAL_ANSWER_RETRY_DURATION_MS (line 202) | const FINAL_ANSWER_RETRY_DURATION_MS = 75_000
  constant FINAL_ANSWER_MAX_RETRIES (line 203) | const FINAL_ANSWER_MAX_RETRIES = 2
  constant TOOL_CALL_WAIT_NOTICE_DELAY_MS (line 204) | const TOOL_CALL_WAIT_NOTICE_DELAY_MS = 45_000
  constant TOOL_CALL_DIAGNOSIS_DELAY_MS (line 205) | const TOOL_CALL_DIAGNOSIS_DELAY_MS = 90_000
  constant TOOL_CALL_DIAGNOSIS_RETRY_DELAY_MS (line 206) | const TOOL_CALL_DIAGNOSIS_RETRY_DELAY_MS = 10_000
  constant PLANNING_WAIT_NOTICE_DELAY_MS (line 207) | const PLANNING_WAIT_NOTICE_DELAY_MS = 1_500
  constant REACT_HISTORY_COMPACTION_MAX_TOKENS (line 209) | const REACT_HISTORY_COMPACTION_MAX_TOKENS = 512
  constant REACT_HISTORY_COMPACTION_RETRY_MAX_TOKENS (line 210) | const REACT_HISTORY_COMPACTION_RETRY_MAX_TOKENS = 1_024
  constant REACT_LOCAL_PROVIDER_HISTORY_LOGS (line 211) | const REACT_LOCAL_PROVIDER_HISTORY_LOGS = 16
  constant REACT_LOCAL_PROVIDER_HISTORY_COMPACTION_POINT (line 212) | const REACT_LOCAL_PROVIDER_HISTORY_COMPACTION_POINT = 12
  constant REACT_REMOTE_PROVIDER_HISTORY_LOGS (line 213) | const REACT_REMOTE_PROVIDER_HISTORY_LOGS = 32
  constant REACT_REMOTE_PROVIDER_HISTORY_COMPACTION_POINT (line 214) | const REACT_REMOTE_PROVIDER_HISTORY_COMPACTION_POINT = 24

FILE: server/src/core/llm-manager/llm-duties/react-llm-duty/execution.ts
  function buildExecutionMemorySection (line 53) | async function buildExecutionMemorySection(
  function buildExecutionPromptSections (line 64) | function buildExecutionPromptSections(params: {
  function parseExecutionHandoffIntent (line 113) | function parseExecutionHandoffIntent(
  function createExecutionHandoff (line 131) | function createExecutionHandoff(
  function shouldInjectContextManifestForExecution (line 146) | function shouldInjectContextManifestForExecution(
  function buildExecutionContextManifestSection (line 153) | function buildExecutionContextManifestSection(
  function runExecutionSelfObservationPhase (line 165) | async function runExecutionSelfObservationPhase(
  function runExecutionStep (line 298) | async function runExecutionStep(
  function runToolLevelExecution (line 405) | async function runToolLevelExecution(
  function resolveToolFunctionWithNativeTools (line 491) | async function resolveToolFunctionWithNativeTools(
  function resolveToolFunctionWithJSONMode (line 681) | async function resolveToolFunctionWithJSONMode(
  function executeFunction (line 875) | async function executeFunction(
  function executeFunctionWithNativeTools (line 912) | async function executeFunctionWithNativeTools(
  function executeFunctionWithJSONMode (line 1192) | async function executeFunctionWithJSONMode(
  function runToolExecution (line 1462) | async function runToolExecution(

FILE: server/src/core/llm-manager/llm-duties/react-llm-duty/final-answer.ts
  function runFinalAnswerPhase (line 22) | async function runFinalAnswerPhase(

FILE: server/src/core/llm-manager/llm-duties/react-llm-duty/history-compaction.ts
  constant SUMMARY_MAX_CHARS (line 5) | const SUMMARY_MAX_CHARS = 900
  function cleanText (line 7) | function cleanText(value: unknown): string {
  function clampSummary (line 19) | function clampSummary(value: string): string {
  function toTopicBullets (line 37) | function toTopicBullets(value: string): string {
  function normalizeLegacySummaryObject (line 47) | function normalizeLegacySummaryObject(value: Record<string, unknown>): s...
  function normalizeHistoryCompactionSummary (line 79) | function normalizeHistoryCompactionSummary(output: unknown): string | nu...
  function hasHistoryCompactionContent (line 95) | function hasHistoryCompactionContent(summary: string | null): boolean {
  function formatHistoryForCompaction (line 99) | function formatHistoryForCompaction(
  function buildCompactedHistoryMessage (line 126) | function buildCompactedHistoryMessage(summary: string): string {
  function toChatHistoryItems (line 130) | function toChatHistoryItems(logs: MessageLog[]): ChatHistoryItem[] {
  function isSameMessageLog (line 149) | function isSameMessageLog(left: MessageLog, right: MessageLog): boolean {
  function findMessageSequenceStart (line 157) | function findMessageSequenceStart(

FILE: server/src/core/llm-manager/llm-duties/react-llm-duty/metrics.ts
  type RawPhaseMetric (line 5) | interface RawPhaseMetric {
  type RawPhaseMetrics (line 10) | type RawPhaseMetrics = Record<ReactPhase, RawPhaseMetric>
  type VisibleOutputParams (line 12) | interface VisibleOutputParams {
  type VisibleOutputMetrics (line 17) | interface VisibleOutputMetrics {
  type FinalAnswerCaptureParams (line 23) | interface FinalAnswerCaptureParams {
  type FinalAnswerMetricsSnapshot (line 35) | interface FinalAnswerMetricsSnapshot {
  type PhaseMetricSnapshot (line 45) | interface PhaseMetricSnapshot extends RawPhaseMetric {
  type PhaseMetricSnapshots (line 49) | type PhaseMetricSnapshots = Record<ReactPhase, PhaseMetricSnapshot>
  type DerivedLLMMetrics (line 51) | interface DerivedLLMMetrics {
  type AccumulatedLLMMetricsState (line 71) | interface AccumulatedLLMMetricsState {
  type MeasureVisibleOutputOptions (line 81) | interface MeasureVisibleOutputOptions {
  type DeriveLLMMetricsOptions (line 86) | interface DeriveLLMMetricsOptions extends MeasureVisibleOutputOptions {
  type RecordCompletionMetricsParams (line 99) | interface RecordCompletionMetricsParams {
  type ObserveCompletionMetricsOptions (line 109) | interface ObserveCompletionMetricsOptions
  type CompletionObservationResult (line 126) | interface CompletionObservationResult {
  function perSecond (line 132) | function perSecond(units: number, durationMs: number): number {
  function safeJSONStringify (line 136) | function safeJSONStringify(value: unknown): string {
  function buildVisibleOutputText (line 144) | function buildVisibleOutputText(params: VisibleOutputParams): string {
  function measureVisibleOutput (line 162) | function measureVisibleOutput(
  function measureOutputMetrics (line 185) | function measureOutputMetrics(
  function recordCompletionMetrics (line 197) | function recordCompletionMetrics(
  function observeCompletionMetrics (line 225) | function observeCompletionMetrics(
  function captureFinalAnswerMetrics (line 277) | function captureFinalAnswerMetrics(
  function createPhaseMetricSnapshots (line 318) | function createPhaseMetricSnapshots(
  function averagePhaseTokensPerSecond (line 357) | function averagePhaseTokensPerSecond(
  function resolveFinalAnswerOutputTokens (line 383) | function resolveFinalAnswerOutputTokens(
  function selectTokensPerSecond (line 407) | function selectTokensPerSecond(params: {
  function deriveLLMMetrics (line 445) | function deriveLLMMetrics(

FILE: server/src/core/llm-manager/llm-duties/react-llm-duty/phase-helpers.ts
  type DuplicateInputMatch (line 12) | interface DuplicateInputMatch {
  function asRecord (line 17) | function asRecord(value: unknown): Record<string, unknown> | null {
  function normalizeStepLabel (line 25) | function normalizeStepLabel(label: string | null | undefined): string {
  function stableSerialize (line 33) | function stableSerialize(value: unknown): string {
  function normalizeToolInputForComparison (line 48) | function normalizeToolInputForComparison(toolInput: string): string {
  function extractRequestedToolInputFromObservation (line 62) | function extractRequestedToolInputFromObservation(
  function extractFailureMessageFromObservation (line 87) | function extractFailureMessageFromObservation(observation: string): stri...
  function getExecutionRequestedToolInput (line 111) | function getExecutionRequestedToolInput(execution: ExecutionRecord): str...
  function findDuplicateToolInputMatch (line 119) | function findDuplicateToolInputMatch(
  function buildPreviouslyUsedInputsSection (line 168) | function buildPreviouslyUsedInputsSection(
  function buildToolkitContextSection (line 198) | function buildToolkitContextSection(
  function buildContextManifestSection (line 260) | function buildContextManifestSection(manifest: string): string {
  function buildSelfModelSection (line 269) | function buildSelfModelSection(snapshot: string): string {
  function stripInlineToolMarkup (line 278) | function stripInlineToolMarkup(text: string): string {
  function shouldTreatPlanningTextAsFinalAnswer (line 291) | function shouldTreatPlanningTextAsFinalAnswer(text: string): boolean {
  function extractPlanningMarkedFinalAnswer (line 295) | function extractPlanningMarkedFinalAnswer(text: string): string | null {
  function extractPlanningTextHandoffDraft (line 310) | function extractPlanningTextHandoffDraft(text: string): string | null {
  function humanizeIdentifier (line 324) | function humanizeIdentifier(value: string): string {
  function normalizeStepLabelFromFunction (line 333) | function normalizeStepLabelFromFunction(functionName: string): string {
  function getFunctionDescription (line 343) | function getFunctionDescription(functionName: string): string {
  function descriptionToStepLabel (line 359) | function descriptionToStepLabel(description: string): string {
  function buildStepLabelFromFunction (line 374) | function buildStepLabelFromFunction(functionName: string): string {
  function commandTokenFromArgs (line 386) | function commandTokenFromArgs(rawArguments: string): string {
  function buildRecoveredStepLabel (line 411) | function buildRecoveredStepLabel(
  function resolveFunctionNameForPlan (line 423) | function resolveFunctionNameForPlan(functionName: string): string | null {
  function createPlanFromUnexpectedToolCall (line 475) | function createPlanFromUnexpectedToolCall(

FILE: server/src/core/llm-manager/llm-duties/react-llm-duty/phase-policy.ts
  type ReactPhasePolicy (line 6) | interface ReactPhasePolicy {
  constant REACT_PHASE_POLICIES (line 22) | const REACT_PHASE_POLICIES: Record<ReactPhase, ReactPhasePolicy> = {
  function getPhasePolicy (line 61) | function getPhasePolicy(phase?: ReactPhase): ReactPhasePolicy {
  function buildPhaseSystemPrompt (line 69) | function buildPhaseSystemPrompt(
  function formatPhasePolicyForLog (line 82) | function formatPhasePolicyForLog(

FILE: server/src/core/llm-manager/llm-duties/react-llm-duty/plan-contract.ts
  constant PLAN_STEP_PROPERTIES_SCHEMA (line 1) | const PLAN_STEP_PROPERTIES_SCHEMA = {
  constant PLAN_STEP_SCHEMA (line 6) | const PLAN_STEP_SCHEMA = {
  constant NULLABLE_PLAN_STEPS_SCHEMA (line 13) | const NULLABLE_PLAN_STEPS_SCHEMA = {
  constant NULLABLE_STRING_SCHEMA (line 23) | const NULLABLE_STRING_SCHEMA = {
  constant NULLABLE_PLAN_INTENT_SCHEMA (line 27) | const NULLABLE_PLAN_INTENT_SCHEMA = {
  constant PLAN_RESPONSE_SCHEMA (line 37) | const PLAN_RESPONSE_SCHEMA = {

FILE: server/src/core/llm-manager/llm-duties/react-llm-duty/plan-widget.ts
  function buildPlanComponentTree (line 17) | function buildPlanComponentTree(
  function emitPlanWidget (line 233) | function emitPlanWidget(

FILE: server/src/core/llm-manager/llm-duties/react-llm-duty/planning.ts
  function buildPlanningPromptSections (line 37) | function buildPlanningPromptSections(params: {
  function isOperatingSystemControlOnlyPlan (line 84) | function isOperatingSystemControlOnlyPlan(steps: { function: string }[])...
  function createPlanningHandoff (line 94) | function createPlanningHandoff(
  function shouldAttemptForcedPlanFallback (line 108) | function shouldAttemptForcedPlanFallback(planResult: PlanResult): boolean {
  function runPlanningPhase (line 115) | async function runPlanningPhase(

FILE: server/src/core/llm-manager/llm-duties/react-llm-duty/recovery-planning.ts
  function buildRecoveryPromptSections (line 34) | function buildRecoveryPromptSections(params: {
  function createRecoveryHandoff (line 80) | function createRecoveryHandoff(
  function runRecoveryPlanningPhase (line 94) | async function runRecoveryPlanningPhase(

FILE: server/src/core/llm-manager/llm-duties/react-llm-duty/types.ts
  type ReactLLMDutyParams (line 9) | type ReactLLMDutyParams = LLMDutyParams
  type FunctionConfig (line 11) | interface FunctionConfig {
  type ToolFunctionsMap (line 22) | type ToolFunctionsMap = Record<string, FunctionConfig>
  type PlanStep (line 24) | interface PlanStep {
  type ExecutionRecord (line 29) | interface ExecutionRecord {
  type PlanStepStatus (line 37) | type PlanStepStatus = 'pending' | 'in_progress' | 'completed'
  type TrackedPlanStep (line 39) | interface TrackedPlanStep {
  type Catalog (line 44) | interface Catalog {
  type FinalPhaseIntent (line 49) | type FinalPhaseIntent =
  type FinalResponseSignal (line 56) | interface FinalResponseSignal {
  type PlanResult (line 68) | type PlanResult =
  type ExecutionStepResult (line 72) | type ExecutionStepResult =
  type ToolExecutionResult (line 81) | interface ToolExecutionResult {
  type PromptLogSection (line 87) | interface PromptLogSection {
  type ReactPhase (line 93) | type ReactPhase = 'planning' | 'execution' | 'recovery' | 'final_answer'
  type LLMCallOptions (line 95) | interface LLMCallOptions {
  type LLMCaller (line 108) | interface LLMCaller {

FILE: server/src/core/llm-manager/llm-duties/react-llm-duty/utils.ts
  type ExecutionHistoryFormatMode (line 10) | type ExecutionHistoryFormatMode = 'compact' | 'complete'
  constant COMPACT_EXECUTION_HISTORY_MAX_DETAILED_STEPS (line 12) | const COMPACT_EXECUTION_HISTORY_MAX_DETAILED_STEPS = 6
  function clipText (line 18) | function clipText(value: string, maxLength = 180): string {
  function clipMultilineText (line 27) | function clipMultilineText(
  function summarizeScalar (line 54) | function summarizeScalar(
  function pickRepresentativeText (line 82) | function pickRepresentativeText(record: Record<string, unknown>): string...
  function summarizeArrayField (line 111) | function summarizeArrayField(
  function summarizeObjectField (line 148) | function summarizeObjectField(
  function summarizeStructuredPayload (line 173) | function summarizeStructuredPayload(
  function extractObservationPayload (line 220) | function extractObservationPayload(
  function formatObservationSummary (line 253) | function formatObservationSummary(
  function parseFinalIntent (line 322) | function parseFinalIntent(
  function indentBlock (line 340) | function indentBlock(value: string, prefix: string): string {
  function formatExecutionEntry (line 347) | function formatExecutionEntry(
  function formatOlderExecutionSummary (line 369) | function formatOlderExecutionSummary(history: ExecutionRecord[]): string {
  function formatExecutionHistory (line 396) | function formatExecutionHistory(
  function parseStepsFromArgs (line 440) | function parseStepsFromArgs(
  function extractPlanFromParsed (line 463) | function extractPlanFromParsed(
  function parseOutput (line 565) | function parseOutput(
  function parseToolCallArguments (line 623) | function parseToolCallArguments(
  function extractPlanResultFromCreatePlanArgs (line 664) | function extractPlanResultFromCreatePlanArgs(
  function extractTaggedJson (line 787) | function extractTaggedJson(input: string): string | null {
  function extractJsonSubstring (line 798) | function extractJsonSubstring(input: string): string | null {
  function extractFinalAnswerFromToolResult (line 827) | function extractFinalAnswerFromToolResult(toolExecutionResult: {
  function validateToolInput (line 853) | function validateToolInput(
  functio
Condensed preview — 1078 files, each showing path, character count, and a content snippet. Download the .json file or copy for the full structured content (7,701K chars).
[
  {
    "path": ".changelogrc",
    "chars": 395,
    "preview": "{\n  \"app_name\": \"Leon\",\n  \"sections\": [\n    {\n      \"title\": \"BREAKING CHANGES\",\n      \"grep\": \"BREAKING\"\n    },\n    {\n "
  },
  {
    "path": ".editorconfig",
    "chars": 276,
    "preview": "# EditorConfig is awesome: https://EditorConfig.org\n\n# top-most EditorConfig file\nroot = true\n\n# Unix-style newlines wit"
  },
  {
    "path": ".env.sample",
    "chars": 3975,
    "preview": "# Main settings of Leon\n# https://docs.getleon.ai/configuration\n\n# Language currently used\nLEON_LANG=en-US\n\n# Server\nLEO"
  },
  {
    "path": ".github/CODE_OF_CONDUCT.md",
    "chars": 3353,
    "preview": "# Contributor Covenant Code of Conduct\n\n## Our Pledge\n\nIn the interest of fostering an open and welcoming environment, w"
  },
  {
    "path": ".github/CONTRIBUTING.md",
    "chars": 7892,
    "preview": "# Contributing\n\nThanks a lot for your interest in contributing to Leon! :heart:\n\n**Leon needs open source to live**, the"
  },
  {
    "path": ".github/FUNDING.yml",
    "chars": 351,
    "preview": "# These are supported funding model platforms\n\ngithub: [louistiti]\npatreon: # Replace with a single Patreon username\nope"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/BUG.md",
    "chars": 623,
    "preview": "---\nname: 🐞 Bug Report\nabout: Report an unexpected problem or unintended behavior.\nlabels: bug\n---\n\n<!--\nThanks for your"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/DOCS.md",
    "chars": 512,
    "preview": "---\nname: 📝 Documentation\nabout: Are the docs missing, confusing, etc.? Tell us more about it.\n---\n\n<!--\nThanks for your"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/FEATURE_REQUEST.md",
    "chars": 250,
    "preview": "---\nname: ✨ Feature Request\nabout: Suggest a new feature idea.\nlabels: feature request\n---\n\n<!--\nThanks for your interes"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/IMPROVEMENT.md",
    "chars": 268,
    "preview": "---\nname: 🔧 Improvement\nabout: Suggest an idea which is not a feature.\nlabels: improvement\n---\n\n<!--\nThanks for your int"
  },
  {
    "path": ".github/ISSUE_TEMPLATE/QUESTION.md",
    "chars": 241,
    "preview": "---\nname: ❓ Question\nabout: Ask a question about Leon.\nlabels: question\n---\n\n<!--\nThanks for your interest in Leon! ❤️\nP"
  },
  {
    "path": ".github/PULL_REQUEST_TEMPLATE.md",
    "chars": 722,
    "preview": "<!--\n\nThanks a lot for your interest in contributing to Leon! :heart:\n\nPlease first discuss the change you wish to make "
  },
  {
    "path": ".github/workflows/build.yml",
    "chars": 720,
    "preview": "name: Build\n\non:\n  push:\n    # branches: [master, develop]\n    branches: [master]\n  pull_request:\n    # branches: [maste"
  },
  {
    "path": ".github/workflows/lint.yml",
    "chars": 668,
    "preview": "name: Lint\n\non:\n  push:\n    # branches: [master, develop]\n    branches: [master]\n  pull_request:\n    # branches: [master"
  },
  {
    "path": ".github/workflows/pre-release-nodejs-bridge.yml",
    "chars": 3545,
    "preview": "name: Pre-release Node.js bridge\n\non: workflow_dispatch\n\njobs:\n  build:\n    name: Build\n\n    strategy:\n      fail-fast: "
  },
  {
    "path": ".github/workflows/pre-release-python-bridge.yml",
    "chars": 4443,
    "preview": "name: Pre-release Python bridge\n\non: workflow_dispatch\n\nenv:\n  PIPENV_PIPFILE: bridges/python/src\n  PIPENV_VENV_IN_PROJE"
  },
  {
    "path": ".github/workflows/pre-release-tcp-server.yml",
    "chars": 4580,
    "preview": "name: Pre-release TCP server\n\non: workflow_dispatch\n\nenv:\n  PIPENV_PIPFILE: tcp_server/src\n  PIPENV_VENV_IN_PROJECT: tru"
  },
  {
    "path": ".github/workflows/tests.yml",
    "chars": 1018,
    "preview": "name: Tests\n\non:\n  push:\n    # branches: [master, develop]\n    branches: [master]\n  pull_request:\n    # branches: [maste"
  },
  {
    "path": ".gitignore",
    "chars": 1236,
    "preview": "__pycache__/\n.idea/\n.fleet/\n.vscode/\n**/dist/*\n**/build/\n**/node_modules/\ntest/coverage/\n**/tmp/*\n**/src/.venv/*\nlogs/*\n"
  },
  {
    "path": ".gitpod.yml",
    "chars": 311,
    "preview": "image: gitpod/workspace-full\n\ntasks:\n  - before: npm install -g @leon-ai/cli\n    init: leon create birth\n    command: le"
  },
  {
    "path": ".husky/commit-msg",
    "chars": 301,
    "preview": "if ! [ -x \"$(command -v npm)\" ]; then\n  echo \"npm: command not found\"\n  echo \"If you use a version manager tool such as "
  },
  {
    "path": ".husky/pre-commit",
    "chars": 289,
    "preview": "if ! [ -x \"$(command -v npm)\" ]; then\n  echo \"npm: command not found\"\n  echo \"If you use a version manager tool such as "
  },
  {
    "path": ".lintstagedrc",
    "chars": 28,
    "preview": "{\n  \"*\": [\"npm run lint\"]\n}\n"
  },
  {
    "path": ".npmrc",
    "chars": 54,
    "preview": "engine-strict=true\npackage-lock=false\nsave-exact=true\n"
  },
  {
    "path": ".nvmrc",
    "chars": 6,
    "preview": "lts/*\n"
  },
  {
    "path": "CHANGELOG.md",
    "chars": 33138,
    "preview": "# [1.0.0-beta.8](https://github.com/leon-ai/leon/compare/v1.0.0-beta.7...v1.0.0-beta.8) (2023-05-01) / Binaries and Type"
  },
  {
    "path": "LICENSE.md",
    "chars": 1098,
    "preview": "MIT License\n\nCopyright (c) 2019-present, Louis Grenard <louis@getleon.ai>\n\nPermission is hereby granted, free of charge,"
  },
  {
    "path": "README.md",
    "chars": 12041,
    "preview": "<p align=\"center\">\n  <a href=\"https://getleon.ai\"><img width=\"800\" src=\"https://getleon.ai/img/hero-animation.gif\" /></a"
  },
  {
    "path": "app/src/css/style.scss",
    "chars": 11798,
    "preview": "@import '@fontsource/source-sans-pro/200.css';\n@import '@fontsource/source-sans-pro/300.css';\n@import '@fontsource/sourc"
  },
  {
    "path": "app/src/css/voice-energy/base.scss",
    "chars": 2654,
    "preview": "/**\n * Overlay and containers\n */\n\nbody.voice-mode-enabled {\n  #voice-overlay-transitor,\n  #voice-overlay-bg {\n    visib"
  },
  {
    "path": "app/src/css/voice-energy/idle.scss",
    "chars": 1125,
    "preview": "/**\n * IDLE status\n */\n\n#voice-energy-container.idle {\n  .voice-particle {\n    visibility: hidden;\n    animation-play-st"
  },
  {
    "path": "app/src/css/voice-energy/listening.scss",
    "chars": 1180,
    "preview": "/**\n * Listening status\n */\n\n#voice-energy-container.listening {\n  .voice-particle {\n    visibility: hidden;\n    animati"
  },
  {
    "path": "app/src/css/voice-energy/main.scss",
    "chars": 119,
    "preview": "@import 'base.scss';\n@import 'listening.scss';\n@import 'idle.scss';\n@import 'processing.scss';\n@import 'talking.scss';\n"
  },
  {
    "path": "app/src/css/voice-energy/processing.scss",
    "chars": 1769,
    "preview": "@use 'sass:math';\n\n/**\n * Processing status\n */\n\n#voice-energy-container.processing {\n  #purple-neon-blur {\n    animatio"
  },
  {
    "path": "app/src/css/voice-energy/talking.scss",
    "chars": 1591,
    "preview": "@use 'sass:math';\n\n/**\n * Talking status\n */\n\n#voice-energy-container.talking {\n  .voice-neon {\n    margin: 0;\n  }\n  #pu"
  },
  {
    "path": "app/src/custom-aurora-components/index.ts",
    "chars": 24,
    "preview": "export * from './timer'\n"
  },
  {
    "path": "app/src/custom-aurora-components/timer/index.ts",
    "chars": 24,
    "preview": "export * from './timer'\n"
  },
  {
    "path": "app/src/custom-aurora-components/timer/timer.tsx",
    "chars": 1763,
    "preview": "import React, { useState, useEffect } from 'react'\nimport { CircularProgress, Flexbox, Text } from '@leon-ai/aurora'\n\nin"
  },
  {
    "path": "app/src/index.html",
    "chars": 11286,
    "preview": "<!doctype html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"utf-8\" />\n    <link rel=\"icon\" type=\"image/png\" href=\"/img/"
  },
  {
    "path": "app/src/js/chatbot.js",
    "chars": 19202,
    "preview": "import { createElement } from 'react'\nimport { createRoot } from 'react-dom/client'\nimport axios from 'axios'\n// eslint-"
  },
  {
    "path": "app/src/js/client.js",
    "chars": 15414,
    "preview": "import { io } from 'socket.io-client'\n\nimport Chatbot from './chatbot'\nimport VoiceEnergy from './voice-energy'\nimport {"
  },
  {
    "path": "app/src/js/constants.js",
    "chars": 1319,
    "preview": "export const INIT_MESSAGES = [\n  [\n    'Hello there! Glad to e-meet meet you, I\\'m Leon, your open-source personal assis"
  },
  {
    "path": "app/src/js/init.jsx",
    "chars": 5602,
    "preview": "import { useEffect, useState, useRef } from 'react'\nimport { createRoot } from 'react-dom/client'\nimport {\n  WidgetWrapp"
  },
  {
    "path": "app/src/js/listener.js",
    "chars": 826,
    "preview": "const listener = {}\n\nlistener.listening = (\n  stream,\n  minDecibels,\n  maxBlankTime,\n  cbOnStart,\n  cbOnEnd\n) => {\n  con"
  },
  {
    "path": "app/src/js/main.js",
    "chars": 4734,
    "preview": "import axios from 'axios'\nimport '@leon-ai/aurora/style.css'\n\nwindow.leonInitStatusEvent = new EventTarget()\n\nimport './"
  },
  {
    "path": "app/src/js/onkeydown.js",
    "chars": 1036,
    "preview": "let index = -1\nlet parsedHistory = null\n\nconst onkeydowninput = (e, client) => {\n  const key = e.which || e.keyCode\n\n  i"
  },
  {
    "path": "app/src/js/recorder.js",
    "chars": 1351,
    "preview": "import on from '../sounds/on.mp3'\nimport off from '../sounds/off.mp3'\n\nexport default class Recorder {\n  constructor(str"
  },
  {
    "path": "app/src/js/render-aurora-component.js",
    "chars": 1588,
    "preview": "import { createElement } from 'react'\nimport * as auroraComponents from '@leon-ai/aurora'\n\nimport * as customAuroraCompo"
  },
  {
    "path": "app/src/js/suggestion-handler.js",
    "chars": 1185,
    "preview": "import { createElement } from 'react'\nimport { createRoot } from 'react-dom/client'\nimport { WidgetWrapper, List, ListHe"
  },
  {
    "path": "app/src/js/tool-ui-handler.js",
    "chars": 6021,
    "preview": "/**\n * Tool UI Handler\n * Manages the display and interaction of tool output in shell-like containers\n */\nexport default"
  },
  {
    "path": "app/src/js/voice-energy.js",
    "chars": 2104,
    "preview": "const STATUS = {\n  listening: 'Listening...',\n  processing: 'Processing...',\n  talking: 'Talking...',\n  idle: 'Idle'\n}\n\n"
  },
  {
    "path": "app/vite.config.js",
    "chars": 578,
    "preview": "import dns from 'node:dns'\n\nimport dotenv from 'dotenv'\nimport { defineConfig } from 'vite'\nimport react from '@vitejs/p"
  },
  {
    "path": "bin/cmake/versions.json",
    "chars": 23,
    "preview": "{\n  \"cmake\": \"4.3.0\"\n}\n"
  },
  {
    "path": "bin/llama.cpp/versions.json",
    "chars": 27,
    "preview": "{\n  \"llama.cpp\": \"b8417\"\n}\n"
  },
  {
    "path": "bin/ninja/versions.json",
    "chars": 24,
    "preview": "{\n  \"ninja\": \"1.13.2\"\n}\n"
  },
  {
    "path": "bin/pytorch/versions.json",
    "chars": 23,
    "preview": "{\n  \"torch\": \"2.9.0\"\n}\n"
  },
  {
    "path": "bridges/nodejs/.npmrc",
    "chars": 35,
    "preview": "package-lock=false\nsave-exact=true\n"
  },
  {
    "path": "bridges/nodejs/package.json",
    "chars": 607,
    "preview": "{\n  \"name\": \"leon-nodejs-bridge\",\n  \"description\": \"Leon's Node.js bridge to communicate between the core and skills mad"
  },
  {
    "path": "bridges/nodejs/src/constants.ts",
    "chars": 3228,
    "preview": "import fs from 'node:fs'\nimport path from 'node:path'\n\nimport type { SkillLocaleConfigSchema } from '@/schemas/skill-sch"
  },
  {
    "path": "bridges/nodejs/src/main.ts",
    "chars": 1628,
    "preview": "import path from 'node:path'\n\nimport { FileHelper } from '@/helpers/file-helper'\n\nimport type { ActionFunction, ActionPa"
  },
  {
    "path": "bridges/nodejs/src/sdk/aurora/button.ts",
    "chars": 225,
    "preview": "import { type ButtonProps } from '@leon-ai/aurora'\n\nimport { WidgetComponent } from '../widget-component'\n\nexport class "
  },
  {
    "path": "bridges/nodejs/src/sdk/aurora/card.ts",
    "chars": 217,
    "preview": "import { type CardProps } from '@leon-ai/aurora'\n\nimport { WidgetComponent } from '../widget-component'\n\nexport class Ca"
  },
  {
    "path": "bridges/nodejs/src/sdk/aurora/checkbox.ts",
    "chars": 233,
    "preview": "import { type CheckboxProps } from '@leon-ai/aurora'\n\nimport { WidgetComponent } from '../widget-component'\n\nexport clas"
  },
  {
    "path": "bridges/nodejs/src/sdk/aurora/circular-progress.ts",
    "chars": 265,
    "preview": "import { type CircularProgressProps } from '@leon-ai/aurora'\n\nimport { WidgetComponent } from '../widget-component'\n\nexp"
  },
  {
    "path": "bridges/nodejs/src/sdk/aurora/flexbox.ts",
    "chars": 229,
    "preview": "import { type FlexboxProps } from '@leon-ai/aurora'\n\nimport { WidgetComponent } from '../widget-component'\n\nexport class"
  },
  {
    "path": "bridges/nodejs/src/sdk/aurora/form.ts",
    "chars": 217,
    "preview": "import { type FormProps } from '@leon-ai/aurora'\n\nimport { WidgetComponent } from '../widget-component'\n\nexport class Fo"
  },
  {
    "path": "bridges/nodejs/src/sdk/aurora/icon-button.ts",
    "chars": 241,
    "preview": "import { type IconButtonProps } from '@leon-ai/aurora'\n\nimport { WidgetComponent } from '../widget-component'\n\nexport cl"
  },
  {
    "path": "bridges/nodejs/src/sdk/aurora/icon.ts",
    "chars": 217,
    "preview": "import { type IconProps } from '@leon-ai/aurora'\n\nimport { WidgetComponent } from '../widget-component'\n\nexport class Ic"
  },
  {
    "path": "bridges/nodejs/src/sdk/aurora/image.ts",
    "chars": 221,
    "preview": "import { type ImageProps } from '@leon-ai/aurora'\n\nimport { WidgetComponent } from '../widget-component'\n\nexport class I"
  },
  {
    "path": "bridges/nodejs/src/sdk/aurora/index.ts",
    "chars": 807,
    "preview": "export * from './button'\nexport * from './card'\nexport * from './checkbox'\nexport * from './circular-progress'\nexport * "
  },
  {
    "path": "bridges/nodejs/src/sdk/aurora/input.ts",
    "chars": 221,
    "preview": "import { type InputProps } from '@leon-ai/aurora'\n\nimport { WidgetComponent } from '../widget-component'\n\nexport class I"
  },
  {
    "path": "bridges/nodejs/src/sdk/aurora/link.ts",
    "chars": 217,
    "preview": "import { type LinkProps } from '@leon-ai/aurora'\n\nimport { WidgetComponent } from '../widget-component'\n\nexport class Li"
  },
  {
    "path": "bridges/nodejs/src/sdk/aurora/list-header.ts",
    "chars": 241,
    "preview": "import { type ListHeaderProps } from '@leon-ai/aurora'\n\nimport { WidgetComponent } from '../widget-component'\n\nexport cl"
  },
  {
    "path": "bridges/nodejs/src/sdk/aurora/list-item.ts",
    "chars": 233,
    "preview": "import { type ListItemProps } from '@leon-ai/aurora'\n\nimport { WidgetComponent } from '../widget-component'\n\nexport clas"
  },
  {
    "path": "bridges/nodejs/src/sdk/aurora/list.ts",
    "chars": 217,
    "preview": "import { type ListProps } from '@leon-ai/aurora'\n\nimport { WidgetComponent } from '../widget-component'\n\nexport class Li"
  },
  {
    "path": "bridges/nodejs/src/sdk/aurora/loader.ts",
    "chars": 225,
    "preview": "import { type LoaderProps } from '@leon-ai/aurora'\n\nimport { WidgetComponent } from '../widget-component'\n\nexport class "
  },
  {
    "path": "bridges/nodejs/src/sdk/aurora/progress.ts",
    "chars": 233,
    "preview": "import { type ProgressProps } from '@leon-ai/aurora'\n\nimport { WidgetComponent } from '../widget-component'\n\nexport clas"
  },
  {
    "path": "bridges/nodejs/src/sdk/aurora/radio-group.ts",
    "chars": 241,
    "preview": "import { type RadioGroupProps } from '@leon-ai/aurora'\n\nimport { WidgetComponent } from '../widget-component'\n\nexport cl"
  },
  {
    "path": "bridges/nodejs/src/sdk/aurora/radio.ts",
    "chars": 221,
    "preview": "import { type RadioProps } from '@leon-ai/aurora'\n\nimport { WidgetComponent } from '../widget-component'\n\nexport class R"
  },
  {
    "path": "bridges/nodejs/src/sdk/aurora/range-slider.ts",
    "chars": 245,
    "preview": "import { type RangeSliderProps } from '@leon-ai/aurora'\n\nimport { WidgetComponent } from '../widget-component'\n\nexport c"
  },
  {
    "path": "bridges/nodejs/src/sdk/aurora/scroll-container.ts",
    "chars": 261,
    "preview": "import { type ScrollContainerProps } from '@leon-ai/aurora'\n\nimport { WidgetComponent } from '../widget-component'\n\nexpo"
  },
  {
    "path": "bridges/nodejs/src/sdk/aurora/select-option.ts",
    "chars": 249,
    "preview": "import { type SelectOptionProps } from '@leon-ai/aurora'\n\nimport { WidgetComponent } from '../widget-component'\n\nexport "
  },
  {
    "path": "bridges/nodejs/src/sdk/aurora/select.ts",
    "chars": 225,
    "preview": "import { type SelectProps } from '@leon-ai/aurora'\n\nimport { WidgetComponent } from '../widget-component'\n\nexport class "
  },
  {
    "path": "bridges/nodejs/src/sdk/aurora/status.ts",
    "chars": 225,
    "preview": "import { type StatusProps } from '@leon-ai/aurora'\n\nimport { WidgetComponent } from '../widget-component'\n\nexport class "
  },
  {
    "path": "bridges/nodejs/src/sdk/aurora/switch.ts",
    "chars": 225,
    "preview": "import { type SwitchProps } from '@leon-ai/aurora'\n\nimport { WidgetComponent } from '../widget-component'\n\nexport class "
  },
  {
    "path": "bridges/nodejs/src/sdk/aurora/tab-content.ts",
    "chars": 241,
    "preview": "import { type TabContentProps } from '@leon-ai/aurora'\n\nimport { WidgetComponent } from '../widget-component'\n\nexport cl"
  },
  {
    "path": "bridges/nodejs/src/sdk/aurora/tab-group.ts",
    "chars": 233,
    "preview": "import { type TabGroupProps } from '@leon-ai/aurora'\n\nimport { WidgetComponent } from '../widget-component'\n\nexport clas"
  },
  {
    "path": "bridges/nodejs/src/sdk/aurora/tab-list.ts",
    "chars": 229,
    "preview": "import { type TabListProps } from '@leon-ai/aurora'\n\nimport { WidgetComponent } from '../widget-component'\n\nexport class"
  },
  {
    "path": "bridges/nodejs/src/sdk/aurora/tab.ts",
    "chars": 213,
    "preview": "import { type TabProps } from '@leon-ai/aurora'\n\nimport { WidgetComponent } from '../widget-component'\n\nexport class Tab"
  },
  {
    "path": "bridges/nodejs/src/sdk/aurora/text.ts",
    "chars": 217,
    "preview": "import { type TextProps } from '@leon-ai/aurora'\n\nimport { WidgetComponent } from '../widget-component'\n\nexport class Te"
  },
  {
    "path": "bridges/nodejs/src/sdk/aurora/widget-wrapper.ts",
    "chars": 253,
    "preview": "import { type WidgetWrapperProps } from '@leon-ai/aurora'\n\nimport { WidgetComponent } from '../widget-component'\n\nexport"
  },
  {
    "path": "bridges/nodejs/src/sdk/base-tool.ts",
    "chars": 39058,
    "preview": "import fs from 'node:fs'\nimport path from 'node:path'\nimport os from 'node:os'\nimport { spawn, execSync, spawnSync } fro"
  },
  {
    "path": "bridges/nodejs/src/sdk/leon.ts",
    "chars": 5029,
    "preview": "import fs from 'node:fs'\nimport path from 'node:path'\n\nimport type {\n  AnswerData,\n  AnswerInput,\n  AnswerOutput,\n  Answ"
  },
  {
    "path": "bridges/nodejs/src/sdk/memory.ts",
    "chars": 2586,
    "preview": "import path from 'node:path'\nimport fs from 'node:fs'\n\nimport { SKILL_PATH, SKILLS_PATH } from '@bridge/constants'\n\ninte"
  },
  {
    "path": "bridges/nodejs/src/sdk/network.ts",
    "chars": 5156,
    "preview": "import dns from 'node:dns'\n\nimport type { AxiosInstance } from 'axios'\nimport axios from 'axios'\n\nimport { LEON_VERSION,"
  },
  {
    "path": "bridges/nodejs/src/sdk/packages/lodash.ts",
    "chars": 33,
    "preview": "export { default } from 'lodash'\n"
  },
  {
    "path": "bridges/nodejs/src/sdk/params-helper.ts",
    "chars": 4003,
    "preview": "import type { ActionParams, NEREntity } from '@sdk/types'\nimport { INTENT_OBJECT } from '@bridge/constants'\n\nexport clas"
  },
  {
    "path": "bridges/nodejs/src/sdk/settings.ts",
    "chars": 3141,
    "preview": "import path from 'node:path'\nimport fs from 'node:fs'\n\nimport { SKILL_PATH } from '@bridge/constants'\n\nexport class Sett"
  },
  {
    "path": "bridges/nodejs/src/sdk/tool-manager.ts",
    "chars": 1504,
    "preview": "import { formatFilePath } from '@sdk/utils'\nimport { Tool } from '@sdk/base-tool'\nimport { reportToolOutput } from '@sdk"
  },
  {
    "path": "bridges/nodejs/src/sdk/tool-reporter.ts",
    "chars": 384,
    "preview": "export type ToolReporter = (input: Record<string, unknown>) => Promise<void>\n\nlet toolReporter: ToolReporter | null = nu"
  },
  {
    "path": "bridges/nodejs/src/sdk/toolkit-config.ts",
    "chars": 3672,
    "preview": "import { readFileSync, existsSync, mkdirSync, writeFileSync } from 'node:fs'\nimport { join } from 'node:path'\n\nimport { "
  },
  {
    "path": "bridges/nodejs/src/sdk/tools/assemblyai_audio/assemblyai_audio-tool.ts",
    "chars": 7546,
    "preview": "import fs from 'node:fs'\n\nimport type { TranscriptionOutput } from '@sdk/tools/transcription-schema'\nimport { Tool } fro"
  },
  {
    "path": "bridges/nodejs/src/sdk/tools/assemblyai_audio/index.ts",
    "chars": 50,
    "preview": "export { default } from './assemblyai_audio-tool'\n"
  },
  {
    "path": "bridges/nodejs/src/sdk/tools/assemblyai_audio/lib/.gitkeep",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "bridges/nodejs/src/sdk/tools/bash/bash-tool.ts",
    "chars": 13651,
    "preview": "import fs from 'node:fs'\nimport path from 'node:path'\n\nimport { Tool } from '@sdk/base-tool'\nimport { ToolkitConfig } fr"
  },
  {
    "path": "bridges/nodejs/src/sdk/tools/bash/index.ts",
    "chars": 38,
    "preview": "export { default } from './bash-tool'\n"
  },
  {
    "path": "bridges/nodejs/src/sdk/tools/bash/lib/.gitkeep",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "bridges/nodejs/src/sdk/tools/cerebras/cerebras-tool.ts",
    "chars": 8735,
    "preview": "import { Tool } from '@sdk/base-tool'\nimport { ToolkitConfig } from '@sdk/toolkit-config'\nimport { Network, NetworkError"
  },
  {
    "path": "bridges/nodejs/src/sdk/tools/cerebras/index.ts",
    "chars": 42,
    "preview": "export { default } from './cerebras-tool'\n"
  },
  {
    "path": "bridges/nodejs/src/sdk/tools/cerebras/lib/.gitkeep",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "bridges/nodejs/src/sdk/tools/chatterbox_onnx/chatterbox_onnx-tool.ts",
    "chars": 7834,
    "preview": "import fs from 'node:fs'\nimport os from 'node:os'\nimport path from 'node:path'\n\nimport { NVIDIA_LIBS_PATH } from '@bridg"
  },
  {
    "path": "bridges/nodejs/src/sdk/tools/chatterbox_onnx/index.ts",
    "chars": 49,
    "preview": "export { default } from './chatterbox_onnx-tool'\n"
  },
  {
    "path": "bridges/nodejs/src/sdk/tools/chatterbox_onnx/lib/.gitkeep",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "bridges/nodejs/src/sdk/tools/context/context-tool.ts",
    "chars": 10025,
    "preview": "import fs from 'node:fs'\nimport path from 'node:path'\n\nimport { Tool } from '@sdk/base-tool'\nimport { ToolkitConfig } fr"
  },
  {
    "path": "bridges/nodejs/src/sdk/tools/context/index.ts",
    "chars": 41,
    "preview": "export { default } from './context-tool'\n"
  },
  {
    "path": "bridges/nodejs/src/sdk/tools/ecapa/ecapa-tool.ts",
    "chars": 3117,
    "preview": "import fs from 'node:fs'\n\nimport { Tool } from '@sdk/base-tool'\nimport { ToolkitConfig } from '@sdk/toolkit-config'\n\ncon"
  },
  {
    "path": "bridges/nodejs/src/sdk/tools/ecapa/index.ts",
    "chars": 39,
    "preview": "export { default } from './ecapa-tool'\n"
  },
  {
    "path": "bridges/nodejs/src/sdk/tools/ecapa/lib/.gitkeep",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "bridges/nodejs/src/sdk/tools/elevenlabs_audio/elevenlabs_audio-tool.ts",
    "chars": 7942,
    "preview": "import fs from 'node:fs'\n\nimport FormData from 'form-data'\n\nimport type { TranscriptionOutput } from '@sdk/tools/transcr"
  },
  {
    "path": "bridges/nodejs/src/sdk/tools/elevenlabs_audio/index.ts",
    "chars": 50,
    "preview": "export { default } from './elevenlabs_audio-tool'\n"
  },
  {
    "path": "bridges/nodejs/src/sdk/tools/elevenlabs_audio/lib/.gitkeep",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "bridges/nodejs/src/sdk/tools/faster_whisper/faster_whisper-tool.ts",
    "chars": 4829,
    "preview": "import fs from 'node:fs'\n\nimport type { TranscriptionOutput } from '@sdk/tools/transcription-schema'\nimport { Tool } fro"
  },
  {
    "path": "bridges/nodejs/src/sdk/tools/faster_whisper/index.ts",
    "chars": 48,
    "preview": "export { default } from './faster_whisper-tool'\n"
  },
  {
    "path": "bridges/nodejs/src/sdk/tools/faster_whisper/lib/.gitkeep",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "bridges/nodejs/src/sdk/tools/ffmpeg/ffmpeg-tool.ts",
    "chars": 15714,
    "preview": "import { Tool } from '@sdk/base-tool'\nimport { ToolkitConfig } from '@sdk/toolkit-config'\n\nconst DEFAULT_SETTINGS: Recor"
  },
  {
    "path": "bridges/nodejs/src/sdk/tools/ffmpeg/index.ts",
    "chars": 40,
    "preview": "export { default } from './ffmpeg-tool'\n"
  },
  {
    "path": "bridges/nodejs/src/sdk/tools/ffmpeg/lib/.gitkeep",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "bridges/nodejs/src/sdk/tools/ffprobe/ffprobe-tool.ts",
    "chars": 10416,
    "preview": "import { Tool } from '@sdk/base-tool'\nimport { ToolkitConfig } from '@sdk/toolkit-config'\n\nconst DEFAULT_SETTINGS: Recor"
  },
  {
    "path": "bridges/nodejs/src/sdk/tools/ffprobe/index.ts",
    "chars": 41,
    "preview": "export { default } from './ffprobe-tool'\n"
  },
  {
    "path": "bridges/nodejs/src/sdk/tools/ffprobe/lib/.gitkeep",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "bridges/nodejs/src/sdk/tools/grok/grok-tool.ts",
    "chars": 11860,
    "preview": "import { Tool } from '@sdk/base-tool'\nimport { ToolkitConfig } from '@sdk/toolkit-config'\n\n/**\n * xAI Grok Tool with Ser"
  },
  {
    "path": "bridges/nodejs/src/sdk/tools/grok/index.ts",
    "chars": 38,
    "preview": "export { default } from './grok-tool'\n"
  },
  {
    "path": "bridges/nodejs/src/sdk/tools/grok/lib/.gitkeep",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "bridges/nodejs/src/sdk/tools/memory/index.ts",
    "chars": 40,
    "preview": "export { default } from './memory-tool'\n"
  },
  {
    "path": "bridges/nodejs/src/sdk/tools/memory/memory-tool.ts",
    "chars": 34697,
    "preview": "import fs from 'node:fs'\nimport path from 'node:path'\nimport { createHash, randomUUID } from 'node:crypto'\n\nimport SQLit"
  },
  {
    "path": "bridges/nodejs/src/sdk/tools/memory/qmd-embed-worker.mjs",
    "chars": 2300,
    "preview": "import fs from 'node:fs/promises'\nimport process from 'node:process'\n\nimport { createStore } from '@tobilu/qmd'\n\nconst ["
  },
  {
    "path": "bridges/nodejs/src/sdk/tools/memory/qmd-retrieval.ts",
    "chars": 39554,
    "preview": "import fs from 'node:fs'\nimport path from 'node:path'\nimport { gunzipSync } from 'node:zlib'\n\nexport interface QMDCollec"
  },
  {
    "path": "bridges/nodejs/src/sdk/tools/memory/qmd-store.ts",
    "chars": 14792,
    "preview": "import { execFile } from 'node:child_process'\nimport fs from 'node:fs'\nimport { fileURLToPath } from 'node:url'\nimport o"
  },
  {
    "path": "bridges/nodejs/src/sdk/tools/open-meteo/index.ts",
    "chars": 44,
    "preview": "export { default } from './open-meteo-tool'\n"
  },
  {
    "path": "bridges/nodejs/src/sdk/tools/open-meteo/lib/.gitkeep",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "bridges/nodejs/src/sdk/tools/open-meteo/open-meteo-tool.ts",
    "chars": 9047,
    "preview": "import { Tool } from '@sdk/base-tool'\nimport { ToolkitConfig } from '@sdk/toolkit-config'\nimport { Network, NetworkError"
  },
  {
    "path": "bridges/nodejs/src/sdk/tools/openai_audio/index.ts",
    "chars": 46,
    "preview": "export { default } from './openai_audio-tool'\n"
  },
  {
    "path": "bridges/nodejs/src/sdk/tools/openai_audio/lib/.gitkeep",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "bridges/nodejs/src/sdk/tools/openai_audio/openai_audio-tool.ts",
    "chars": 4463,
    "preview": "import fs from 'node:fs'\n\nimport FormData from 'form-data'\n\nimport type { TranscriptionOutput } from '@sdk/tools/transcr"
  },
  {
    "path": "bridges/nodejs/src/sdk/tools/opencode/index.ts",
    "chars": 42,
    "preview": "export { default } from './opencode-tool'\n"
  },
  {
    "path": "bridges/nodejs/src/sdk/tools/opencode/lib/.gitkeep",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "bridges/nodejs/src/sdk/tools/opencode/lib/prompt.md",
    "chars": 1712,
    "preview": "{{SYSTEM_PROMPT_SECTION}}\n{{REPO_SNAPSHOT}}\n{{TOOLKIT_INFO}}\n\n# Leon Skill Creation (Concise)\n\nYou are generating a Leon"
  },
  {
    "path": "bridges/nodejs/src/sdk/tools/opencode/opencode-tool.ts",
    "chars": 87414,
    "preview": "import fs from 'node:fs'\nimport path from 'node:path'\nimport os from 'node:os'\n\nimport { Tool } from '@sdk/base-tool'\nim"
  },
  {
    "path": "bridges/nodejs/src/sdk/tools/openrouter/index.ts",
    "chars": 44,
    "preview": "export { default } from './openrouter-tool'\n"
  },
  {
    "path": "bridges/nodejs/src/sdk/tools/openrouter/lib/.gitkeep",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "bridges/nodejs/src/sdk/tools/openrouter/openrouter-tool.ts",
    "chars": 8644,
    "preview": "import { Tool } from '@sdk/base-tool'\nimport { ToolkitConfig } from '@sdk/toolkit-config'\nimport { Network, NetworkError"
  },
  {
    "path": "bridges/nodejs/src/sdk/tools/qwen3_asr/index.ts",
    "chars": 43,
    "preview": "export { default } from './qwen3_asr-tool'\n"
  },
  {
    "path": "bridges/nodejs/src/sdk/tools/qwen3_asr/lib/.gitkeep",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "bridges/nodejs/src/sdk/tools/qwen3_asr/qwen3_asr-tool.ts",
    "chars": 6040,
    "preview": "import fs from 'node:fs'\nimport os from 'node:os'\nimport path from 'node:path'\n\nimport type { TranscriptionOutput } from"
  },
  {
    "path": "bridges/nodejs/src/sdk/tools/qwen3_tts/index.ts",
    "chars": 43,
    "preview": "export { default } from './qwen3_tts-tool'\n"
  },
  {
    "path": "bridges/nodejs/src/sdk/tools/qwen3_tts/lib/.gitkeep",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "bridges/nodejs/src/sdk/tools/qwen3_tts/qwen3_tts-tool.ts",
    "chars": 7884,
    "preview": "import fs from 'node:fs'\nimport os from 'node:os'\nimport path from 'node:path'\n\nimport { Tool } from '@sdk/base-tool'\nim"
  },
  {
    "path": "bridges/nodejs/src/sdk/tools/transcription-schema.ts",
    "chars": 647,
    "preview": "export interface TranscriptionSegment {\n  // Start time in seconds\n  from: number\n\n  // End time in seconds\n  to: number"
  },
  {
    "path": "bridges/nodejs/src/sdk/tools/ultimate_vocal_remover_onnx/index.ts",
    "chars": 61,
    "preview": "export { default } from './ultimate_vocal_remover_onnx-tool'\n"
  },
  {
    "path": "bridges/nodejs/src/sdk/tools/ultimate_vocal_remover_onnx/lib/.gitkeep",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "bridges/nodejs/src/sdk/tools/ultimate_vocal_remover_onnx/ultimate_vocal_remover_onnx-tool.ts",
    "chars": 3465,
    "preview": "import fs from 'node:fs'\nimport os from 'node:os'\nimport path from 'node:path'\n\nimport { NVIDIA_LIBS_PATH } from '@bridg"
  },
  {
    "path": "bridges/nodejs/src/sdk/tools/ytdlp/index.ts",
    "chars": 39,
    "preview": "export { default } from './ytdlp-tool'\n"
  },
  {
    "path": "bridges/nodejs/src/sdk/tools/ytdlp/lib/.gitkeep",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "bridges/nodejs/src/sdk/tools/ytdlp/yt-dlp.conf",
    "chars": 134,
    "preview": "--retries 3\n--sleep-interval 0.5\n--max-sleep-interval 2\n--extractor-args youtube:player_client=default,-web_safari\n--js-"
  },
  {
    "path": "bridges/nodejs/src/sdk/tools/ytdlp/ytdlp-tool.ts",
    "chars": 12138,
    "preview": "import { mkdirSync } from 'node:fs'\nimport { join } from 'node:path'\n\nimport { Tool, type ProgressCallback } from '@sdk/"
  },
  {
    "path": "bridges/nodejs/src/sdk/types.ts",
    "chars": 1020,
    "preview": "/**\n * Action types\n */\nimport type {\n  ActionParams,\n  IntentObject,\n  SkillAnswerCoreData,\n  SkillAnswerOutput\n} from "
  },
  {
    "path": "bridges/nodejs/src/sdk/utils.ts",
    "chars": 7641,
    "preview": "import { platform, arch, cpus } from 'node:os'\nimport fs from 'node:fs'\nimport path from 'node:path'\nimport { execSync }"
  },
  {
    "path": "bridges/nodejs/src/sdk/widget-component.ts",
    "chars": 1289,
    "preview": "export type SupportedWidgetEvent = (typeof SUPPORTED_WIDGET_EVENTS)[number]\ninterface WidgetEvent {\n  type: SupportedWid"
  },
  {
    "path": "bridges/nodejs/src/sdk/widget.ts",
    "chars": 3857,
    "preview": "import { type WidgetWrapperProps } from '@leon-ai/aurora'\n\nimport { INTENT_OBJECT, SKILL_LOCALE_CONFIG } from '@bridge/c"
  },
  {
    "path": "bridges/nodejs/src/tool-runtime.ts",
    "chars": 4618,
    "preview": "/**\n * Tool runtime for executing Node.js tools.\n * This runtime exists only for Node.js because the core server is buil"
  },
  {
    "path": "bridges/nodejs/src/version.ts",
    "chars": 31,
    "preview": "export const VERSION = '1.3.0'\n"
  },
  {
    "path": "bridges/nodejs/tsconfig.json",
    "chars": 464,
    "preview": "{\n  \"extends\": \"../../tsconfig.json\",\n  \"compilerOptions\": {\n    \"outDir\": \"./dist/bin\",\n    \"rootDir\": \"../../\",\n    \"b"
  },
  {
    "path": "bridges/python/dist/.gitkeep",
    "chars": 0,
    "preview": ""
  },
  {
    "path": "bridges/python/src/Pipfile",
    "chars": 243,
    "preview": "[[source]]\nurl = \"https://pypi.org/simple\"\nverify_ssl = true\nname = \"pypi\"\n\n[requires]\npython_version = \"3.11.9\"\n\n[packa"
  },
  {
    "path": "bridges/python/src/constants.py",
    "chars": 1985,
    "preview": "import sys\nimport json\nimport os\n\nimport version\n\nargv = sys.argv[1:]\nif \"--runtime\" in argv:\n    runtime_index = argv.i"
  },
  {
    "path": "bridges/python/src/main.py",
    "chars": 1943,
    "preview": "import sys\nimport inspect\nfrom traceback import print_exc\nfrom importlib import import_module\n\nfrom constants import INT"
  },
  {
    "path": "bridges/python/src/sdk/aurora/button.py",
    "chars": 155,
    "preview": "from ..widget_component import WidgetComponent\n\n\nclass Button(WidgetComponent[dict]):\n    def __init__(self, props: dict"
  },
  {
    "path": "bridges/python/src/sdk/aurora/card.py",
    "chars": 153,
    "preview": "from ..widget_component import WidgetComponent\n\n\nclass Card(WidgetComponent[dict]):\n    def __init__(self, props: dict):"
  },
  {
    "path": "bridges/python/src/sdk/aurora/checkbox.py",
    "chars": 157,
    "preview": "from ..widget_component import WidgetComponent\n\n\nclass Checkbox(WidgetComponent[dict]):\n    def __init__(self, props: di"
  },
  {
    "path": "bridges/python/src/sdk/aurora/circular_progress.py",
    "chars": 165,
    "preview": "from ..widget_component import WidgetComponent\n\n\nclass CircularProgress(WidgetComponent[dict]):\n    def __init__(self, p"
  },
  {
    "path": "bridges/python/src/sdk/aurora/flexbox.py",
    "chars": 156,
    "preview": "from ..widget_component import WidgetComponent\n\n\nclass Flexbox(WidgetComponent[dict]):\n    def __init__(self, props: dic"
  },
  {
    "path": "bridges/python/src/sdk/aurora/form.py",
    "chars": 153,
    "preview": "from ..widget_component import WidgetComponent\n\n\nclass Form(WidgetComponent[dict]):\n    def __init__(self, props: dict):"
  },
  {
    "path": "bridges/python/src/sdk/aurora/icon.py",
    "chars": 153,
    "preview": "from ..widget_component import WidgetComponent\n\n\nclass Icon(WidgetComponent[dict]):\n    def __init__(self, props: dict):"
  },
  {
    "path": "bridges/python/src/sdk/aurora/icon_button.py",
    "chars": 159,
    "preview": "from ..widget_component import WidgetComponent\n\n\nclass IconButton(WidgetComponent[dict]):\n    def __init__(self, props: "
  },
  {
    "path": "bridges/python/src/sdk/aurora/image.py",
    "chars": 154,
    "preview": "from ..widget_component import WidgetComponent\n\n\nclass Image(WidgetComponent[dict]):\n    def __init__(self, props: dict)"
  },
  {
    "path": "bridges/python/src/sdk/aurora/input.py",
    "chars": 154,
    "preview": "from ..widget_component import WidgetComponent\n\n\nclass Input(WidgetComponent[dict]):\n    def __init__(self, props: dict)"
  },
  {
    "path": "bridges/python/src/sdk/aurora/link.py",
    "chars": 153,
    "preview": "from ..widget_component import WidgetComponent\n\n\nclass Link(WidgetComponent[dict]):\n    def __init__(self, props: dict):"
  },
  {
    "path": "bridges/python/src/sdk/aurora/list.py",
    "chars": 153,
    "preview": "from ..widget_component import WidgetComponent\n\n\nclass List(WidgetComponent[dict]):\n    def __init__(self, props: dict):"
  },
  {
    "path": "bridges/python/src/sdk/aurora/list_header.py",
    "chars": 159,
    "preview": "from ..widget_component import WidgetComponent\n\n\nclass ListHeader(WidgetComponent[dict]):\n    def __init__(self, props: "
  },
  {
    "path": "bridges/python/src/sdk/aurora/list_item.py",
    "chars": 157,
    "preview": "from ..widget_component import WidgetComponent\n\n\nclass ListItem(WidgetComponent[dict]):\n    def __init__(self, props: di"
  },
  {
    "path": "bridges/python/src/sdk/aurora/loader.py",
    "chars": 155,
    "preview": "from ..widget_component import WidgetComponent\n\n\nclass Loader(WidgetComponent[dict]):\n    def __init__(self, props: dict"
  },
  {
    "path": "bridges/python/src/sdk/aurora/progress.py",
    "chars": 157,
    "preview": "from ..widget_component import WidgetComponent\n\n\nclass Progress(WidgetComponent[dict]):\n    def __init__(self, props: di"
  },
  {
    "path": "bridges/python/src/sdk/aurora/radio.py",
    "chars": 154,
    "preview": "from ..widget_component import WidgetComponent\n\n\nclass Radio(WidgetComponent[dict]):\n    def __init__(self, props: dict)"
  },
  {
    "path": "bridges/python/src/sdk/aurora/radio_group.py",
    "chars": 159,
    "preview": "from ..widget_component import WidgetComponent\n\n\nclass RadioGroup(WidgetComponent[dict]):\n    def __init__(self, props: "
  },
  {
    "path": "bridges/python/src/sdk/aurora/range_slider.py",
    "chars": 160,
    "preview": "from ..widget_component import WidgetComponent\n\n\nclass RangeSlider(WidgetComponent[dict]):\n    def __init__(self, props:"
  },
  {
    "path": "bridges/python/src/sdk/aurora/scroll_container.py",
    "chars": 164,
    "preview": "from ..widget_component import WidgetComponent\n\n\nclass ScrollContainer(WidgetComponent[dict]):\n    def __init__(self, pr"
  },
  {
    "path": "bridges/python/src/sdk/aurora/select.py",
    "chars": 155,
    "preview": "from ..widget_component import WidgetComponent\n\n\nclass Select(WidgetComponent[dict]):\n    def __init__(self, props: dict"
  },
  {
    "path": "bridges/python/src/sdk/aurora/select_option.py",
    "chars": 161,
    "preview": "from ..widget_component import WidgetComponent\n\n\nclass SelectOption(WidgetComponent[dict]):\n    def __init__(self, props"
  },
  {
    "path": "bridges/python/src/sdk/aurora/status.py",
    "chars": 155,
    "preview": "from ..widget_component import WidgetComponent\n\n\nclass Status(WidgetComponent[dict]):\n    def __init__(self, props: dict"
  },
  {
    "path": "bridges/python/src/sdk/aurora/switch.py",
    "chars": 155,
    "preview": "from ..widget_component import WidgetComponent\n\n\nclass Switch(WidgetComponent[dict]):\n    def __init__(self, props: dict"
  }
]

// ... and 878 more files (download for full content)

About this extraction

This page contains the full source code of the leon-ai/leon GitHub repository, extracted and formatted as plain text for AI agents and large language models (LLMs). The extraction includes 1078 files (18.2 MB), approximately 1.9M tokens, and a symbol index with 3816 extracted functions, classes, methods, constants, and types. Use this with OpenClaw, Claude, ChatGPT, Cursor, Windsurf, or any other AI tool that accepts text input. You can copy the full output to your clipboard or download it as a .txt file.

Extracted by GitExtract — free GitHub repo to text converter for AI. Built by Nikandr Surkov.

Copied to clipboard!