### Navigate to WebSocket Example Directory
Source: https://github.com/uezo/aiavatarkit/blob/main/examples/websocket/README.md
Change the working directory to the location of the WebSocket example files.
```sh
cd aiavatarkit/examples/websocket
```
--------------------------------
### Setup Admin Panel
Source: https://github.com/uezo/aiavatarkit/blob/main/FEATURES.md
Initializes the admin panel for runtime configuration and control. The adapter can be dynamically registered after setup.
```python
# Setup admin panel
from aiavatar.admin import setup_admin_panel
panel = setup_admin_panel(app, adapter=aiavatar_app)
# Dynamic adapter registration after setup
panel.add_adapter(another_adapter, name="secondary")
```
--------------------------------
### Install Dependencies
Source: https://github.com/uezo/aiavatarkit/blob/main/examples/websocket/README.md
Install the necessary Python packages for the WebSocket server.
```sh
pip install aiavatar silero-vad fastapi uvicorn websockets
```
--------------------------------
### Start AIAvatarKit WebSocket Server
Source: https://github.com/uezo/aiavatarkit/blob/main/README.md
Script to set up and run the AIAvatarKit WebSocket server using FastAPI. It includes downloading an example UI and optionally setting up an admin panel. Requires a running VOICEVOX instance.
```python
from fastapi import FastAPI
from fastapi.staticfiles import StaticFiles
from aiavatar.adapter.websocket.server import AIAvatarWebSocketServer
from aiavatar.util import download_example
# Download example UI if not exists
download_example("websocket/html")
# Build Speech-to-Speech pipeline with WebSocket adapter
aiavatar_app = AIAvatarWebSocketServer(
openai_api_key=OPENAI_API_KEY
)
# Build websocket server
app = FastAPI()
router = aiavatar_app.get_websocket_router()
app.include_router(router)
app.mount("/static", StaticFiles(directory="html"), name="static")
# Setup admin panel (Optional)
from aiavatar.admin import setup_admin_panel
setup_admin_panel(app, adapter=aiavatar_app)
```
--------------------------------
### Quick Start - Local Console
Source: https://context7.com/uezo/aiavatarkit/llms.txt
Set up a basic AI avatar for local console use. This snippet initializes the AIAvatar with OpenAI and VOICEVOX, then starts listening for voice input.
```python
import asyncio
from aiavatar import AIAvatar
OPENAI_API_KEY = "your-openai-api-key"
aiavatar_app = AIAvatar(
openai_api_key=OPENAI_API_KEY,
openai_model="gpt-4o",
system_prompt="You are a helpful assistant.",
voicevox_speaker=46, # Speaker ID for VOICEVOX TTS
debug=True
)
# Start listening - conversation begins with wake word "Hello"
asyncio.run(aiavatar_app.start_listening())
```
--------------------------------
### Register Example Tools
Source: https://github.com/uezo/aiavatarkit/blob/main/README.md
Pre-built tools like Google Search and Web Scraper can be added directly to the application.
```python
# Google Search
from examples.tools.gemini_websearch import GeminiWebSearchTool
aiavatar_app.sts.llm.add_tool(GeminiWebSearchTool(gemini_api_key=GEMINI_API_KEY))
# Web Scraper
from examples.tools.webscraper import WebScraperTool
aiavatar_app.sts.llm.add_tool(WebScraperTool())
```
--------------------------------
### Start WebSocket Server
Source: https://github.com/uezo/aiavatarkit/blob/main/examples/websocket/README.md
Launch the FastAPI application using Uvicorn.
```sh
uvicorn server:app
```
--------------------------------
### Install asyncpg for PostgreSQL Support
Source: https://github.com/uezo/aiavatarkit/blob/main/README.md
Install the `asyncpg` library, which is required for enabling PostgreSQL support in AIAvatarKit. This is recommended for production environments.
```sh
pip install asyncpg
```
--------------------------------
### Install Azure Speech SDK
Source: https://github.com/uezo/aiavatarkit/blob/main/README.md
Install the required package for Azure speech recognition.
```sh
pip install azure-cognitiveservices-speech
```
--------------------------------
### Admin Panel Setup
Source: https://github.com/uezo/aiavatarkit/blob/main/FEATURES.md
Provides instructions on setting up and extending the Admin Panel for runtime configuration and monitoring of the AI avatar.
```APIDOC
## Admin Panel Setup
### Description
Set up and configure the web-based Admin Panel for monitoring, controlling, and evaluating the AI avatar.
### Features
- **Metrics**: Real-time STS pipeline performance visualization.
- **Logs**: Conversation history with audio playback.
- **Control**: Send messages and control the avatar directly.
- **Config**: Dynamic adjustment of pipeline, VAD, STT, LLM, TTS, and adapter settings.
- **Evaluation**: Run dialogue evaluation scenarios.
- **Characters**: Manage character information (requires CharacterService).
- **Authentication**: Supports basic authentication and API key (Bearer token).
### Setup Example
```python
from aiavatar.admin import setup_admin_panel
panel = setup_admin_panel(app, adapter=aiavatar_app)
# Dynamic adapter registration after setup
panel.add_adapter(another_adapter, name="secondary")
```
```
--------------------------------
### Configure Recording Started Callback
Source: https://github.com/uezo/aiavatarkit/blob/main/README.md
Set up a callback to trigger when meaningful speech is detected.
```python
# Option 1: Pass callback in constructor
async def my_recording_started_handler(session_id: str):
print(f"Recording started for session: {session_id}")
await stop_ai_speech()
vad = SileroSpeechDetector(
on_recording_started=my_recording_started_handler,
on_recording_started_min_duration=1.5, # Trigger after 1.5 sec of speech (default)
# other parameters...
)
```
--------------------------------
### Install AIAvatarKit for WebSocket Server
Source: https://github.com/uezo/aiavatarkit/blob/main/README.md
Install AIAvatarKit along with necessary dependencies for building a WebSocket server.
```sh
pip install aiavatar fastapi uvicorn websockets
```
--------------------------------
### Install AIAvatarKit (Console)
Source: https://github.com/uezo/aiavatarkit/blob/main/README.md
Install the AIAvatarKit package for local console applications. Consider downgrading if using older technical blogs.
```sh
pip install aiavatar
```
--------------------------------
### WebSocket Server Setup
Source: https://context7.com/uezo/aiavatarkit/llms.txt
Deploy AIAvatarKit as a WebSocket server for browser-based interactions. This example configures the server with VAD on the server side and sets up a FastAPI application.
```python
from fastapi import FastAPI
from fastapi.staticfiles import StaticFiles
from aiavatar.adapter.websocket.server import AIAvatarWebSocketServer
from aiavatar.admin import setup_admin_panel
OPENAI_API_KEY = "your-openai-api-key"
# Create WebSocket server with VAD on server side
aiavatar_app = AIAvatarWebSocketServer(
openai_api_key=OPENAI_API_KEY,
volume_db_threshold=-30,
debug=True
)
# Setup FastAPI app
app = FastAPI()
router = aiavatar_app.get_websocket_router()
app.include_router(router)
app.mount("/static", StaticFiles(directory="html"), name="static")
# Optional: Setup admin panel at /admin
setup_admin_panel(app, adapter=aiavatar_app)
# Run with: uvicorn server:app
```
--------------------------------
### Install Cryptography Package
Source: https://github.com/uezo/aiavatarkit/blob/main/examples/websocket/openclaw.md
Install the cryptography package required for certificate generation.
```sh
pip install cryptography
```
--------------------------------
### Install Langfuse
Source: https://github.com/uezo/aiavatarkit/blob/main/README.md
Install the Langfuse library to enable integration with AIAvatarKit for enhanced observability.
```sh
pip install langfuse
```
--------------------------------
### Install Amazon Transcribe SDK
Source: https://github.com/uezo/aiavatarkit/blob/main/README.md
Install the required package for Amazon Transcribe.
```sh
pip install amazon-transcribe
```
--------------------------------
### Install FastMCP Dependency
Source: https://github.com/uezo/aiavatarkit/blob/main/README.md
Install the required package to enable MCP support.
```sh
pip install fastmcp
```
--------------------------------
### Run AIAvatarKit Locally (Console)
Source: https://github.com/uezo/aiavatarkit/blob/main/README.md
Basic script to start AIAvatarKit for local console interaction. Requires an OpenAI API key and a running VOICEVOX instance for TTS. Conversation starts with a wake word.
```python
import asyncio
from aiavatar import AIAvatar
aiavatar_app = AIAvatar(
openai_api_key=OPENAI_API_KEY,
debug=True
)
asyncio.run(aiavatar_app.start_listening())
```
--------------------------------
### Setup Admin Panel with Basic Authentication
Source: https://github.com/uezo/aiavatarkit/blob/main/README.md
Secure the admin panel using Basic Authentication by providing a username and password. This adds a layer of protection for accessing the panel.
```python
setup_admin_panel(
app,
adapter=aiavatar_app,
api_key="your-api-key",
basic_auth_username="admin",
basic_auth_password="your-password",
)
```
--------------------------------
### Setup Admin Panel with Custom HTML
Source: https://github.com/uezo/aiavatarkit/blob/main/README.md
Customize the admin panel's appearance by providing your own HTML content. This allows for full control over the user interface.
```python
custom_html = open("my_admin.html").read()
setup_admin_panel(
app,
adapter=aiavatar_app,
html=custom_html, # Use your own HTML instead of the built-in template
)
```
--------------------------------
### Run AIAvatar Application
Source: https://github.com/uezo/aiavatarkit/blob/main/README.md
Execute the application script to start the AIAvatar service.
```bash
$ run.py
```
--------------------------------
### PostgreSQL Pool Provider Setup
Source: https://github.com/uezo/aiavatarkit/blob/main/FEATURES.md
Configure and initialize a shared PostgreSQL connection pool for efficient resource management across multiple components. Set min_size and max_size for pool configuration.
```python
from aiavatar.database.postgres import PostgreSQLPoolProvider
# Create shared pool provider
pool_provider = PostgreSQLPoolProvider(
connection_str="postgresql://user:pass@host:5432/db",
min_size=5,
max_size=30
)
# Pass to components - all share the same pool
from aiavatar.sts.context.postgres import PostgreSQLContextManager
from aiavatar.sts.session.postgres import PostgreSQLSessionStateManager
from aiavatar.sts.performance.postgres import PostgreSQLPerformanceRecorder
from aiavatar.character import CharacterService
context_manager = PostgreSQLContextManager(get_pool=pool_provider.get_pool)
session_manager = PostgreSQLSessionStateManager(get_pool=pool_provider.get_pool)
performance_recorder = PostgreSQLPerformanceRecorder(get_pool=pool_provider.get_pool)
character_service = CharacterService(db_pool_provider=pool_provider)
```
--------------------------------
### Define Recording Started Callback
Source: https://github.com/uezo/aiavatarkit/blob/main/README.md
Use the on_recording_started decorator to execute logic when speech detection begins.
```python
@vad.on_recording_started
async def on_recording_started(session_id):
await stop_ai_speech()
```
--------------------------------
### Initialize Render Loop
Source: https://github.com/uezo/aiavatarkit/blob/main/examples/websocket/html/vrm.html
Starts the animation frame loop for the 3D scene.
```javascript
function animate() {
requestAnimationFrame(animate);
controls.update();
idle.update(clock.getDelta());
renderer.render(scene, camera);
}
animate();
```
--------------------------------
### Initialize TTS with Pronunciation Preprocessor
Source: https://github.com/uezo/aiavatarkit/blob/main/FEATURES.md
Set up a `PatternMatchPreprocessor` to handle custom string replacements and pronunciation rules for TTS. This example adds a pattern for 'OpenAI' and enables number-dash replacement.
```python
# Usage example
preprocessor = PatternMatchPreprocessor()
preprocessor.add_pattern("OpenAI", "Open A I")
preprocessor.add_number_dash_pattern() # Number-dash pattern replacement
tts = VoicevoxSpeechSynthesizer(preprocessors=[preprocessor])
```
--------------------------------
### Launch AIAvatarKit Server
Source: https://github.com/uezo/aiavatarkit/blob/main/examples/websocket/openclaw.md
Command to start the AIAvatarKit server after OpenClaw is running.
```sh
python openclaw.py
```
--------------------------------
### Setup Admin Panel
Source: https://github.com/uezo/aiavatarkit/blob/main/README.md
Configure the built-in admin panel for monitoring and controlling your AI avatar. Access it at the '/admin' route. Optional parameters include an evaluator, character service, character ID, and API key for authentication.
```python
from aiavatar.admin import setup_admin_panel
setup_admin_panel(
app,
adapter=aiavatar_app,
evaluator=evaluator, # Optional: If omitted, the pipeline LLM settings are used
character_service=character_service, # Optional: If using CharacterService
character_id=YOUR_CHARACTER_ID, # Optional: Required if character_service is set
api_key="your-api-key" # Optional: If omitted, no authentication is required
)
```
--------------------------------
### Setup VRMA Section and File Input
Source: https://github.com/uezo/aiavatarkit/blob/main/examples/websocket/html/vrm.html
Initializes a section for VRMA animations, including a file input for adding animations and a button to trigger it. Handles the file selection and caching of VRMA files.
```javascript
const vrmaSection = document.createElement('div'); vrmaSection.style.cssText = 'margin-top:16px'; const vrmaHeading = document.createElement('div'); vrmaHeading.style.cssText = 'font-size:11px;color:#999;margin-bottom:6px'; vrmaHeading.textContent = 'VRMA'; vrmaSection.appendChild(vrmaHeading); const vrmaFileInput = document.createElement('input'); vrmaFileInput.type = 'file'; vrmaFileInput.accept = '.vrma'; vrmaFileInput.multiple = true; vrmaFileInput.style.display = 'none'; const vrmaAddBtn = document.createElement('button'); vrmaAddBtn.className = 'vrmi-sampler-btn'; vrmaAddBtn.textContent = 'Add animation'; vrmaAddBtn.addEventListener('click', () => vrmaFileInput.click()); vrmaFileInput.addEventListener('change', async (e) => { for (const file of e.target.files) { const animName = file.name.replace(/\.vrma$/i, ''); try { await loadAndCacheVRMA(animName, file); } catch (err) { console.error('Failed to load VRMA:', err); alert(`Failed to load VRMA: ${file.name}`); } } vrmaFileInput.value = ''; refreshVrmaList(); }); vrmaSection.appendChild(vrmaAddBtn); vrmaSection.appendChild(vrmaFileInput);
```
--------------------------------
### Microphone Section UI Setup
Source: https://github.com/uezo/aiavatarkit/blob/main/examples/websocket/html/vrm.html
Initializes the microphone section UI, including a toggle for the microphone glow indicator. Assumes 'makeToggle' and 'saveDisplay' functions are defined elsewhere.
```javascript
const micSection = document.createElement('div'); micSection.style.cssText = 'margin-top:12px;'; micSection.appendChild(sectionHeading('Microphone')); const micToggles = document.createElement('div'); micToggles.style.cssText = 'display:flex;flex-direction:column;gap:10px'; const micGlowToggle = makeToggle('Show indicator', showMicGlow, (v) => { showMicGlow = v; if (!v) document.getElementById('micGlow').classList.remove('active'); saveDisplay(); }); const micMuteToggl
```
--------------------------------
### Setup Ambient and Directional Lighting
Source: https://github.com/uezo/aiavatarkit/blob/main/examples/websocket/html/vrm.html
Initializes ambient and directional lights for the scene. The `applyLighting` function dynamically updates these lights based on configuration values, including intensity, position, and color temperature.
```javascript
const ambientLight = new THREE.AmbientLight(0xffffff, 1.0);
scene.add(ambientLight);
const dirLight = new THREE.DirectionalLight(0xffffff, 1.0);
dirLight.position.set(1, 2, 3);
scene.add(dirLight);
applyLighting = () => {
ambientLight.intensity = L.ambient / 100;
dirLight.intensity = L.direct / 100;
const h = L.hAngle * Math.PI / 180;
const v = L.vAngle * Math.PI / 180;
dirLight.position.set(
Math.cos(v) * Math.sin(h),
Math.sin(v),
Math.cos(v) * Math.cos(h)
);
const [r, g, b] = kelvinToRGB(L.temp);
dirLight.color.setRGB(r, g, b);
};
applyLighting();
```
--------------------------------
### Setup FastAPI App with AIAvatar Components
Source: https://github.com/uezo/aiavatarkit/blob/main/README.md
Integrate AIAvatar's API router into a FastAPI application. Ensure you have FastAPI and uvicorn installed to run the server.
```python
from fastapi import FastAPI
import aiavatar_app
app = FastAPI()
router = aiavatar_app.get_api_router()
app.include_router(router)
```
--------------------------------
### Initialize QuickResponderPro
Source: https://github.com/uezo/aiavatarkit/blob/main/README.md
Configure the QuickResponderPro instance with a context manager and system prompt.
```python
from aiavatar.sts.quick_responder.pro import QuickResponderPro, DEFAULT_QRP_SYSTEM_PROMPT_JA
from aiavatar.sts.llm.context_manager.postgres import PostgreSQLContextManager
from aiavatar.sts.models import STSRequest
quick_responder_pro = QuickResponderPro(
api_key="YOUR_OPENAI_API_KEY",
model="gpt-4.1-nano",
tts=tts,
context_manager=PostgreSQLContextManager(get_pool=pool_provider.get_pool),
language="ja",
system_prompt=DEFAULT_QRP_SYSTEM_PROMPT_JA + "\n\n# Character\nYour character description here.",
timeout=1.5,
)
@aiavatar_app.sts.on_before_llm
async def on_before_llm(request: STSRequest):
await quick_responder_pro.respond(request)
```
--------------------------------
### Configure PostgreSQL for AIAvatar Database
Source: https://context7.com/uezo/aiavatarkit/llms.txt
Set up PostgreSQL as a persistent database for AIAvatar Kit, enabling connection pooling for character services, LLM context management, and session management. Ensure asyncpg is installed.
```python
from aiavatar.database.postgres import PostgreSQLPoolProvider
from aiavatar.character import CharacterService
from aiavatar.sts.llm.chatgpt import ChatGPTService
from aiavatar.sts.llm.context_manager.postgres import PostgreSQLContextManager
from aiavatar.adapter.websocket.server import AIAvatarWebSocketServer
# pip install asyncpg
DB_CONNECTION_STR = "postgresql://user:password@localhost:5432/aiavatar"
# Create shared connection pool
pool_provider = PostgreSQLPoolProvider(
connection_str=DB_CONNECTION_STR,
max_size=20,
min_size=5
)
# Character service with PostgreSQL
character_service = CharacterService(
openai_api_key=OPENAI_API_KEY,
db_pool_provider=pool_provider
)
# LLM with PostgreSQL context manager
llm = ChatGPTService(
openai_api_key=OPENAI_API_KEY,
context_manager=PostgreSQLContextManager(get_pool=pool_provider.get_pool)
)
# Adapter with PostgreSQL session management
aiavatar_app = AIAvatarWebSocketServer(
llm=llm,
db_pool_provider=pool_provider
)
```
--------------------------------
### Python Client for AIAvatar HTTP Streaming API
Source: https://github.com/uezo/aiavatarkit/blob/main/README.md
A simple Python client to interact with the AIAvatar HTTP streaming API. This example uses `asyncio` and `AIAvatarHttpClient` to start listening for sessions.
```python
import asyncio
from aiavatar.adapter.http.client import AIAvatarHttpClient
aiavatar_app = AIAvatarHttpClient(
debug=True
)
asyncio.run(aiavatar_app.start_listening(session_id="http_session", user_id="http_user"))
```
--------------------------------
### Setup Dummy Components for Load Testing
Source: https://github.com/uezo/aiavatarkit/blob/main/FEATURES.md
Initialize dummy components for SpeechRecognizer, LLMService, and SpeechSynthesizer. Configure recognized text, response text, synthesized audio data, and delays for performance testing without external dependencies.
```python
from aiavatar.sts.stt.dummy import SpeechRecognizerDummy
from aiavatar.sts.llm.dummy import LLMServiceDummy
from aiavatar.sts.tts.dummy import SpeechSynthesizerDummy
stt = SpeechRecognizerDummy(recognized_text="Hello", wait_sec=0.1)
llm = LLMServiceDummy(response_text="Hi there!", wait_sec=0.5)
tts = SpeechSynthesizerDummy(synthesized_bytes=b"audio_data", wait_sec=0.2)
```
--------------------------------
### Initialize Built-in Tools
Source: https://github.com/uezo/aiavatarkit/blob/main/README.md
Register pre-built tools for web searching, scraping, and image generation.
```python
# Web Search
from aiavatar.sts.llm.tools.gemini_websearch import GeminiWebSearchTool
google_search_tool = GeminiWebSearchTool(gemini_api_key=GEMINI_API_KEY)
llm.add_tool(google_search_tool)
from aiavatar.sts.llm.tools.openai_websearch import OpenAIWebSearchTool
web_search_tool = OpenAIWebSearchTool(openai_api_key=OPENAI_API_KEY)
llm.add_tool(web_search_tool)
from aiavatar.sts.llm.tools.grok_search import GrokSearchTool
grok_web_search_tool = GrokSearchTool(xai_api_key=XAI_API_KEY)
llm.add_tool(grok_web_search_tool)
# Web Scraper
from aiavatar.sts.llm.tools.webscraper import WebScraperTool
webscraper_tool = WebScraperTool()
# webscraper_tool = WebScraperTool(openai_api_key=OPENAI_API_KEY, return_summary=True) # Provides summary instead of full innerText (recommended)
llm.add_tool(webscraper_tool)
# Image Generation
from aiavatar.sts.llm.tools.nanobanana import NanoBananaTool
nanobanana_tool = NanoBananaTool(gemini_api_key=GEMINI_API_KEY)
llm.add_tool(nanobanana_tool)
from aiavatar.sts.llm.tools.nanobanana import NanoBananaSelfieTool
selfie_tool = NanoBananaSelfieTool(gemini_api_key=GEMINI_API_KEY, reference_image=image_bytes_or_image_url_of_file_api)
llm.add_tool(selfie_tool)
```
--------------------------------
### Install AIAvatarKit Dependencies
Source: https://github.com/uezo/aiavatarkit/blob/main/examples/websocket/openclaw.md
Command to install required Python packages for the AIAvatarKit environment.
```sh
pip install aiavatar uvicorn fastapi websockets
```
--------------------------------
### Vue App Setup with Tabs and Configuration
Source: https://github.com/uezo/aiavatarkit/blob/main/aiavatar/admin/static/index.html
Sets up the main Vue application, defining components, reactive state for API keys, active tabs, tab availability, and configuration sections. Includes methods for API fetching and toast notifications.
```javascript
const apiKey = ref('');
const activeTab = ref('metrics');
const tabs = [
{ id: 'metrics', label: 'Metrics' },
{ id: 'logs', label: 'Logs' },
{ id: 'control', label: 'Control' },
{ id: 'character', label: 'Character' },
{ id: 'config', label: 'Config' },
{ id: 'evaluation', label: 'Evaluation' },
];
const tabAvailability = reactive({
character: 'unknown',
evaluation: 'unknown',
});
const tabSetupMessages = {
character: 'Character features are not configured. To use this tab, set up CharacterService and call setup_character_api().',
evaluation: 'Evaluation features are not configured. To use this tab, set up an Evaluator and call setup_evaluation_api().',
};
const activeConfigSection = ref('pipeline');
const configSections = [
{ id: 'pipeline', label: 'Pipeline' },
{ id: 'vad', label: 'VAD' },
{ id: 'stt', label: 'STT' },
{ id: 'llm', label: 'LLM' },
{ id: 'tts', label: 'TTS' },
{ id: 'adapters', label: 'Adapters' },
];
const configLoading = ref(false);
const saving = ref(false);
const toast = reactive({ show: false, message: '', type: 'success' });
let toastTimer = null;
const showToast = (message, type = 'success') => {
toast.show = true;
toast.message = message;
toast.type = type;
clearTimeout(toastTimer);
toastTimer = setTimeout(() => {
toast.show = false;
}, 2500);
};
```
--------------------------------
### Set up AIAvatarKit router
Source: https://github.com/uezo/aiavatarkit/blob/main/README.md
Initialize the API router and include it in the application.
```python
router = aiavatar_app.get_api_router()
app.include_router(router)
```
--------------------------------
### Voice Notification HTTP Example
Source: https://github.com/uezo/aiavatarkit/blob/main/examples/websocket/voice_push_notification_skill.md
A complete HTTP request example for notifying a specific session with a greeting.
```http
POST {base_url}/avatar/perform
Authorization: Bearer {api_key}
Content-Type: application/json
{"text": "[face:joy]Hello! You have a new message.", "user_id": "agent:main:main"}
```
--------------------------------
### Configure Custom Clients
Source: https://github.com/uezo/aiavatarkit/blob/main/README.md
Use Azure OpenAI or other custom clients by passing them directly to the constructor.
```python
from openai import AsyncAzureOpenAI
quick_responder_pro = QuickResponderPro(
client=AsyncAzureOpenAI(
api_key="YOUR_AZURE_API_KEY",
api_version="2025-01-01-preview",
azure_endpoint="https://your-resource.openai.azure.com/openai/deployments/your-deployment/chat/completions?api-version=2025-01-01-preview"
),
model="your-deployment-name",
tts=tts,
context_manager=context_manager,
)
```
```python
quick_responder_pro = QuickResponderPro(
api_key="YOUR_ANTHROPIC_API_KEY",
base_url="https://api.anthropic.com/v1/",
model="claude-haiku-4-5",
extra_body={"thinking": {"type": "disabled"}},
tts=tts,
context_manager=context_manager,
)
```
--------------------------------
### Initialize VRChatFaceController
Source: https://github.com/uezo/aiavatarkit/blob/main/README.md
Set up the VRChatFaceController with a mapping of expression names to FaceOSC values. Ensure 'neutral: 0' is always included.
```python
vrc_face_controller = VRChatFaceController(
faces={
"neutral": 0, # always set `neutral: 0`
# key = the name that LLM can understand the expression
# value = FaceOSC value that is set to the transition on the FX animator controller
"joy": 1,
"angry": 2,
"sorrow": 3,
"fun": 4
}
)
```
--------------------------------
### Initialize Character Service with PostgreSQL
Source: https://github.com/uezo/aiavatarkit/blob/main/README.md
Instantiate the `CharacterService` and provide the configured `PostgreSQLPoolProvider`. This ensures that character data is managed using PostgreSQL.
```python
# Character
from aiavatar.character import CharacterService
character_service = CharacterService(
openai_api_key=OPENAI_API_KEY,
db_pool_provider=pool_provider, # Creates PostgreSQLCharacterRepository and PostgreSQLActivityRepository internally
)
```
--------------------------------
### VRChat Animation Control Example
Source: https://github.com/uezo/aiavatarkit/blob/main/FEATURES.md
Example of how an LLM response containing an animation tag is translated into an OSC message to trigger VRChat avatar animations.
```python
# LLM response example: "See you! [animation:waving_arm]"
# → Send "/avatar/parameters/VRCEmote" = 3 to VRChat
# → Avatar waves
```
--------------------------------
### VRChat Expression Control Example
Source: https://github.com/uezo/aiavatarkit/blob/main/FEATURES.md
Example of how an LLM response containing a face tag is translated into an OSC message to control VRChat avatar expressions.
```python
# LLM response example: "I'm happy! [face:joy]"
# → Send "/avatar/parameters/FaceOSC" = 1 to VRChat
# → Avatar smiles
```
--------------------------------
### Create LINE Bot Adapter
Source: https://github.com/uezo/aiavatarkit/blob/main/README.md
Initialize the AIAvatarLineBotServer with necessary credentials and configuration for a LINE Bot. Ensure the webhook URL is registered in the LINE Developers Console.
```python
# NOTE: Register https://{your.domain}/webhook as the "Webhook URL" in LINE Developers Console
# Create LINE Bot adapter
from aiavatar.adapter.linebot.server import AIAvatarLineBotServer
aiavatar_app = AIAvatarLineBotServer(
openai_model="gpt-5.1",
system_prompt="You are a cat.",
openai_api_key=OPENAI_API_KEY,
channel_access_token=LINEBOT_CHANNEL_ACCESS_TOKEN,
channel_secret=LINEBOT_CHANNEL_SECRET,
image_download_url_base="https://{your.domain}",
debug=True
)
# Create FastAPI app
from fastapi import FastAPI
app = FastAPI()
```
--------------------------------
### Format Few-Shot Messages
Source: https://github.com/uezo/aiavatarkit/blob/main/README.md
Inject few-shot examples into the main LLM to prevent repetition of quick responses.
```python
@character_loader.format_messages
def format_messages(messages):
messages.append({"role": "user", "content": quick_responder_pro.prompt_prefix + "\n\nHello!"})
messages.append({"role": "assistant", "content": f"{quick_responder_pro.think_tag_content}Hello!"})
messages.append({"role": "user", "content": quick_responder_pro.request_prefix.format(quick_response_text="Hello!") + "\n\nHello!"})
messages.append({"role": "assistant", "content": "Respond warmly to the greeting.How can I help you today?"})
messages.append({"role": "user", "content": "You repeated 'Hello!' which was already sent. Always continue from where the previous output left off."})
messages.append({"role": "assistant", "content": "Noted the mistake. Will not repeat already-sent text next time.Got it."})
return messages
```
--------------------------------
### Run Python Client
Source: https://github.com/uezo/aiavatarkit/blob/main/README.md
Execute the Python client script to initiate voice interactions. Save the client code as `client.py`.
```sh
python client.py
```
--------------------------------
### Message Box UI Setup
Source: https://github.com/uezo/aiavatarkit/blob/main/examples/websocket/html/vrm.html
Sets up the message box section, including opacity and speed sliders, and toggles for speech display and menu visibility. Ensure 'applyMsgBoxOpacity', 'applyAutoHide', 'applyVnMenu', and 'saveDisplay' functions are defined elsewhere.
```javascript
const msgSection = document.createElement('div'); msgSection.appendChild(sectionHeading('Message box')); const grid = document.createElement('div'); grid.className = 'vrmi-sliders'; const label = document.createElement('span'); label.textContent = 'Opacity'; const slider = document.createElement('input'); slider.type = 'range'; slider.min = 0; slider.max = 100; slider.value = msgBoxOpacity; const display = document.createElement('span'); display.textContent = msgBoxOpacity + '%'; slider.addEventListener('input', () => { msgBoxOpacity = parseInt(slider.value); display.textContent = msgBoxOpacity + '%'; applyMsgBoxOpacity(); saveDisplay(); }); displaySlider = { slider, display }; grid.appendChild(label); grid.appendChild(slider); grid.appendChild(display); const speedLabel = document.createElement('span'); speedLabel.textContent = 'Speed'; const speedSlider = document.createElement('input'); speedSlider.type = 'range'; speedSlider.min = 1; speedSlider.max = 100; speedSlider.value = msgSpeed; const speedDisplay = document.createElement('span'); speedDisplay.textContent = msgSpeed; speedSlider.addEventListener('input', () => { msgSpeed = parseInt(speedSlider.value); twSpeed = Math.max(1, 101 - msgSpeed); speedDisplay.textContent = msgSpeed; saveDisplay(); }); speedSliderRef = { slider: speedSlider, display: speedDisplay }; grid.appendChild(speedLabel); grid.appendChild(speedSlider); grid.appendChild(speedDisplay); msgSection.appendChild(grid); const msgToggles = document.createElement('div'); msgToggles.style.cssText = 'margin-top:8px;display:flex;flex-direction:column;gap:10px'; const userTextToggle = makeToggle('Show user speech', showUserText, (v) => { showUserText = v; saveDisplay(); }); const aiTextToggle = makeToggle('Show AI speech', showAIText, (v) => { showAIText = v; saveDisplay(); }); const autoHideToggle = makeToggle('Auto-hide', autoHideMsgBox, (v) => { autoHideMsgBox = v; applyAutoHide(); saveDisplay(); }); const vnMenuToggle = makeToggle('Show menu buttons', showVnMenu, (v) => { showVnMenu = v; applyVnMenu(); saveDisplay(); }); msgToggles.appendChild(userTextToggle.row); msgToggles.appendChild(aiTextToggle.row); msgToggles.appendChild(autoHideToggle.row); msgToggles.appendChild(vnMenuToggle.row); msgSection.appendChild(msgToggles); panel.appendChild(msgSection);
```
--------------------------------
### Automated Cron Configuration
Source: https://github.com/uezo/aiavatarkit/blob/main/README.md
Example cron jobs for scheduling daily diary and schedule generation tasks.
```bash
# Generate daily schedule at 6:00 AM
0 6 * * * /usr/bin/python3 /path/to/generate_schedule.py
# Generate diary at 11:00 PM
0 23 * * * /usr/bin/python3 /path/to/generate_diary.py
```
--------------------------------
### Initialize Three.js Scene and Renderer
Source: https://github.com/uezo/aiavatarkit/blob/main/examples/websocket/html/vrm.html
Sets up the core Three.js scene, perspective camera, and WebGL renderer. Ensures the renderer matches the window size and pixel density, and sets the color space for output.
```javascript
const canvas = document.getElementById('vrmCanvas');
const scene = new THREE.Scene();
const camera = new THREE.PerspectiveCamera(
20,
window.innerWidth / window.innerHeight,
0.1,
100
);
camera.position.set(0, 1.35, 2.5);
camera.lookAt(0, 1.35, 0);
const renderer = new THREE.WebGLRenderer({ canvas, alpha: true, antialias: true });
renderer.setSize(window.innerWidth, window.innerHeight);
renderer.setPixelRatio(window.devicePixelRatio);
renderer.outputColorSpace = THREE.SRGBColorSpace;
```
--------------------------------
### Initialize AIAvatarKit HTTP Server
Source: https://github.com/uezo/aiavatarkit/blob/main/README.md
Set up a basic RESTful API server using FastAPI and AIAvatarHttpServer for hosting AIAvatarKit. This enables independent, context-aware conversations via SSE.
```python
from fastapi import FastAPI
from aiavatar.adapter.http.server import AIAvatarHttpServer
# AIAvatar
aiavatar_app = AIAvatarHttpServer(
openai_api_key=OPENAI_API_KEY,
debug=True
)
```
--------------------------------
### Run AIAvatarKit WebSocket Server Command
Source: https://github.com/uezo/aiavatarkit/blob/main/README.md
Command to start the Uvicorn server for the AIAvatarKit WebSocket application.
```bash
python -m uvicorn ws:app
```
--------------------------------
### AIAvatarKit and Lipsync Initialization
Source: https://github.com/uezo/aiavatarkit/blob/main/examples/websocket/html/mpt.html
Initializes the AIAvatar client and the LipsyncEngine with specific asset paths and audio processing options.
```javascript
// AIAvatar const aiavatar = new AIAvatarClient({ webSocketUrl: "../ws" }); // LipSync const lipsyncEngine = new LipsyncEngine({ elements: { video: document.getElementById("base-video"), mouthCanvas: document.getElementById("mouth-canvas"), stage: document.getElementById("stage") }, assets: { // Miuna video: "motionpngtuber/miuna/miuna_loop_mouthless.mp4", track: "motionpngtuber/miuna/mouth_track.json", mouth_closed: "motionpngtuber/miuna/mouth/closed.png", mouth_open: "motionpngtuber/miuna/mouth/open.png", mouth_half: "motionpngtuber/miuna/mouth/half.png", mouth_e: "motionpngtuber/miuna/mouth/e.png", mouth_u: "motionpngtuber/miuna/mouth/u.png" // Pinkchan // video: "motionpngtuber/assets/assets14/pinkchan_mouthless_h264.mp4", // track: "motionpngtuber/assets/assets14/mouth_track.json", // mouth_closed: "motionpngtuber/assets/assets14/mouth/closed.png", // mouth_open: "motionpngtuber/assets/assets14/mouth/open.png", // mouth_half: "motionpngtuber/assets/assets14/mouth/half.png", // mouth_e: "motionpngtuber/assets/assets14/mouth/e.png", // mouth_u: "motionpngtuber/assets/assets14/mouth/u.png" }, options: { hqAudioEnabled: true, // HQ Audio Mode sensitivity: 0, // Set threshold to max because RMS values are large debug: false } }); aiavatar.onPlaybackAnalyze = ({ rms, centroid01, tSec }) => { lipsyncEngine.processAudioData({ rms: rms * 0.2, // Scale down as values are still too large even at max threshold high: centroid01, low: 1 - centroid01 }); }; aiavatar.onResetFace = () => { lipsyncEngine.resetAudioStats(); }; // Close mouth on speech ends aiavatar.onPlaybackEnd = () => { if (lipsyncEngine) { lipsyncEngine.volume = 0; lipsyncEngine.smoothedHighRatio = 0; lipsyncEngine.setMouthState("closed", true); } }; // Camera const camera = new Camera({ videoElement: document.getElementById("cameraVideo"), canvasElement: document.getElementById("cameraCanvas"), onCapture: (imageDataUrl) => { const imageMessage = { type: "invoke", session_id: ui.sessionId, user_id: ui.userId, files: [{url: imageDataUrl}], allow_merge: false, wait_in_queue: true }; aiavatar.ws.send(JSON.stringify(imageMessage)); } }); // Shared UI const ui = new AvatarUI({ aiavatar: aiavatar, camera: camera, toolLabels: { "send_query_to_openclaw": "Asking OpenClaw🦞", }, onStop: () => { lipsyncEngine.volume = 0; lipsyncEngine.smoothedHighRatio = 0; lipsyncEngine.setMouthState("closed", true); } }); // Custom response handling aiavatar.onResponseReceived = (response) => { // Custom handling logic here // Common handling ui.handleResponse(response); } // Console helper: chat("Hello.") or chat("What's this?", imageDataUrl) window.chat = (text, imageDataUrl) => aiavatar.chat(ui.sessionId, ui.userId, text, imageDataUrl);
```
--------------------------------
### Register Tool via `add_tool`
Source: https://github.com/uezo/aiavatarkit/blob/main/README.md
Demonstrates an alternative method for registering a tool, using the `add_tool` method with `is_dynamic=True` for dynamic tool mode.
```python
# Difine tool without `is_dynamic` for other use cases
weather_tool = Tool("get_weather", get_weather_spec, get_weather, instruction="...")
# Register tool via `add_tool` with `is_dynamic`
llm.add_tool(weather_tool, is_dynamic=True)
```
--------------------------------
### Control API - Listener Management
Source: https://github.com/uezo/aiavatarkit/blob/main/FEATURES.md
Endpoints for controlling the voice input listener, allowing it to be started, stopped, or its status checked.
```APIDOC
## POST /listener/start
### Description
Start voice listener.
### Method
POST
### Endpoint
/listener/start
```
```APIDOC
## POST /listener/stop
### Description
Stop voice listener.
### Method
POST
### Endpoint
/listener/stop
```
```APIDOC
## GET /listener/status
### Description
Get listener status.
### Method
GET
### Endpoint
/listener/status
```
--------------------------------
### Merge Consecutive Utterances
Source: https://github.com/uezo/aiavatarkit/blob/main/FEATURES.md
Example configuration for merging multiple user utterances into a single request within a specified time threshold.
```python
# Example: Merge consecutive utterances within 3 seconds
```
--------------------------------
### Retrieve OpenClaw Session Data
Source: https://github.com/uezo/aiavatarkit/blob/main/examples/websocket/openclaw.md
Example JSON output from the OpenClaw session list command, showing active session keys and metadata.
```json
{
"path": "/home/{username}/.openclaw/agents/main/sessions/sessions.json",
"count": 2,
"activeMinutes": 60,
"sessions": [
{
"key": "agent:main:discord:channel:XXXXXXXXXXXXXXXXXXX",
"kind": "group",
"updatedAt": 1771740483138,
"ageMs": 4071,
"sessionId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"systemSent": true,
"abortedLastRun": false,
"inputTokens": 114780,
"outputTokens": 22,
"totalTokens": 114780,
"totalTokensFresh": true,
"model": "gpt-5.1-codex",
"modelProvider": "openai",
"contextTokens": 400000
},
{
"key": "agent:main:main",
"kind": "direct",
"updatedAt": 1771740336404,
"ageMs": 150805,
"sessionId": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
"systemSent": true,
"abortedLastRun": false,
"inputTokens": 56344,
"outputTokens": 521,
"totalTokens": 19070,
"totalTokensFresh": true,
"model": "gpt-5.1-codex",
"modelProvider": "openai",
"contextTokens": 400000
}
]
}
```
--------------------------------
### Configure PostgreSQL session manager
Source: https://github.com/uezo/aiavatarkit/blob/main/README.md
Initialize a PostgreSQLLineBotSessionManager and pass it to the AIAvatarLineBotServer.
```python
# Create PostgreSQLLineBotSessionManager
from aiavatar.adapter.linebot.session_manager.postgres import PostgreSQLLineBotSessionManager
linebot_session_manager = PostgreSQLLineBotSessionManager(
host=DB_HOST,
port=DB_PORT,
dbname=DB_NAME,
user=DB_USER,
password=DB_PASSWORD
)
aiavatar_app = AIAvatarLineBotServer(
openai_model="gpt-5.1",
system_prompt="You are a cat.",
openai_api_key=OPENAI_API_KEY,
channel_access_token=LINEBOT_CHANNEL_ACCESS_TOKEN,
channel_secret=LINEBOT_CHANNEL_SECRET,
image_download_url_base="https://{your.domain}",
session_manager=linebot_session_manager, # <- Set PostgresSQL session manager
debug=True
)
```
--------------------------------
### Initialize PGVector Speaker Registry
Source: https://github.com/uezo/aiavatarkit/blob/main/FEATURES.md
Sets up the speaker registry using the PostgreSQL vector store.
```python
from aiavatar.sts.stt.speaker_registry.pgvector import PGVectorStore
speaker_store = PGVectorStore(get_pool=pool_provider.get_pool)
speaker_registry = SpeakerRegistry(store=speaker_store)
```
--------------------------------
### Configure Stream-based Speech Detection
Source: https://github.com/uezo/aiavatarkit/blob/main/README.md
Set minimum duration or text length thresholds to trigger recording start events in stream-based detectors.
```python
vad = SileroStreamSpeechDetector(
speech_recognizer=speech_recognizer,
on_recording_started_min_duration=1.5, # Trigger after 1.5 sec of speech
on_recording_started_min_text_length=2, # OR trigger when text >= 2 chars
)
```
--------------------------------
### Configuration API (ConfigAPI)
Source: https://github.com/uezo/aiavatarkit/blob/main/FEATURES.md
API endpoints for dynamically getting and updating component settings, including STT, LLM, TTS, and component switching.
```APIDOC
## Configuration API (ConfigAPI)
### Description
Provides HTTP endpoints to get and update component settings dynamically.
### STT Configuration
Allows dynamic adjustment of speech recognition settings.
| Endpoint | Method | Description |
|-------------|--------|--------------------------|
| /stt/config | GET | Get STT configuration |
| /stt/config | POST | Update STT configuration |
**Configurable items**: language, alternative_languages, timeout, debug, model, base_url, sample_rate.
### LLM Configuration
Enables real-time changes to AI behavior and model configurations.
| Endpoint | Method | Description |
|-------------|--------|------------------------|
| /llm/config | GET | Get LLM configuration |
| /llm/config | POST | Update LLM configuration |
**Configurable items**: system_prompt, model, temperature, split_chars, voice_text_tag, use_dynamic_tools, etc.
### TTS Configuration
Allows dynamic adjustment of voice quality and speed.
| Endpoint | Method | Description |
|-------------|--------|------------------------|
| /tts/config | GET | Get TTS configuration |
| /tts/config | POST | Update TTS configuration |
**Configurable items**: style_mapper, timeout, debug, voice, speaker, speed, pitch, volume, etc.
### Component Switching
Dynamically switch between STT, LLM, and TTS providers.
| Endpoint | Method | Description |
|------------------|--------|-------------------------------|
| /sts/component | GET | Get available component list |
| /sts/component | POST | Switch active component |
### System Log
Access system logs for troubleshooting during operation.
| Endpoint | Method | Description |
|-----------------|--------|---------------------------------|
| /system/log | GET | Get latest logs (max 1000 lines) |
```
--------------------------------
### Inject Dynamic System Prompt Parameters
Source: https://github.com/uezo/aiavatarkit/blob/main/README.md
Uses placeholders in system prompts and provides values at runtime via system_prompt_params.
```python
aiavatar_app = AIAvatar(
openai_api_key="YOUR_OPENAI_API_KEY",
model="gpt-4o",
system_prompt="User's name is {name}."
)
```
```python
aiavatar_app.sts.invoke(STSRequest(
# (other fields omitted)
system_prompt_params={"name": "Nekochan"}
))
```
--------------------------------
### Restore VRM from Cache on Startup
Source: https://github.com/uezo/aiavatarkit/blob/main/examples/websocket/html/vrm.html
Loads and restores a VRM model from the cache when the application starts. It also restores the saved camera state if available.
```javascript
cacheDB.get('vrm_file').then(async blob => {
if (blob) {
const url = URL.createObjectURL(blob);
await loadVRM(url);
restoreCameraState();
}
}).catch(() => {});
```
--------------------------------
### Register MCP Tools
Source: https://github.com/uezo/aiavatarkit/blob/main/README.md
Connect to MCP servers using HTTP or Stdio and register tools to the LLM service.
```python
from aiavatar.sts.llm.chatgpt import ChatGPTService
llm = ChatGPTService(openai_api_key=OPENAI_API_KEY)
from aiavatar.sts.llm.tools.mcp import StreamableHttpMCP, StdioMCP
# MCP Server
mcp1 = StreamableHttpMCP(url=MCP1_URL)
mcp1.for_each_tool = llm.add_tool
# MCP Server with Auth
mcp2 = StreamableHttpMCP(url=MCP2_URL, headers={"Authorization": f"Bearer {MCP_JWT}"})
@mcp2.for_each_tool
def mcp2_tools(tool: Tool):
# Do something here (e.g. edit schema or func)
llm.add_tool(tool)
# MCP Server (Std I/O)
mcp3 = StdioMCP(server_script="weather.py") # supports .py and .js
mcp3.for_each_tool = llm.add_tool
```