# Complete File Paths in OpenAvatarChat Repository

## Root Configuration Files
- `.dockerignore`
- `.gitattributes`
- `.gitignore`
- `.gitmodules`
- `Dockerfile`
- `LICENSE`
- `README.md`
- `readme_en.md`
- `pyproject.toml`
- `setup.cfg`
- `docker-compose.yml`
- `install.py`
- `build_cuda128.sh`
- `run_docker_cuda128.sh`

## Directory Structure

### Configuration Directory (`config/`)
- `chat_with_lam.yaml`
- `chat_with_lam_bailian_asr_duplex.yaml`
- `chat_with_lam_duplex.yaml`
- `chat_with_openai_compatible.yaml`
- `chat_with_openai_compatible_bailian_cosyvoice.yaml`
- `chat_with_openai_compatible_bailian_cosyvoice_duplex.yaml`
- `chat_with_openai_compatible_bailian_cosyvoice_flashhead.yaml`
- `chat_with_openai_compatible_bailian_cosyvoice_flashhead_duplex.yaml`
- `chat_with_openai_compatible_bailian_cosyvoice_flashhead_duplex_agent.yaml`
- `chat_with_openai_compatible_bailian_cosyvoice_musetalk.yaml`
- `chat_with_openai_compatible_bailian_cosyvoice_musetalk_duplex.yaml`
- `chat_with_openai_compatible_edge_tts.yaml`
- `chat_with_qwen_omni.yaml`

### Documentation (`docs/`)
- `FAQ.md`
- `index.md`
- `package.json`
- `package-lock.json`

#### VitePress Configuration
- `.vitepress/config.mts`

#### Community Section
- `community/index.md`
- `community/faq.md`

#### Getting Started Section
- `getting-started/index.md`
- `getting-started/docker.md`
- `getting-started/flashhead.md`
- `getting-started/lam.md`
- `getting-started/liteavatar.md`
- `getting-started/musetalk.md`

#### Guide Section
- `guide/introduction.md`
- `guide/how-it-works.md`
- `guide/deployment.md`

#### Reference Section
- `reference/configuration.md`
- `reference/preset-modes.md`

#### Reference: Handlers
- `reference/handlers/index.md`

**Agent Handlers:**
- `reference/handlers/agent/chat-agent.md`

**ASR Handlers:**
- `reference/handlers/asr/sensevoice.md`

**Avatar Handlers:**
- `reference/handlers/avatar/flashhead.md`
- `reference/handlers/avatar/lam.md`
- `reference/handlers/avatar/liteavatar.md`
- `reference/handlers/avatar/musetalk.md`

**Client Handlers:**
- `reference/handlers/client/lam-client.md`
- `reference/handlers/client/rtc-client.md`

**LLM Handlers:**
- `reference/handlers/llm/dify.md`
- `reference/handlers/llm/openai-compatible.md`
- `reference/handlers/llm/qwen-omni.md`

**Manager Handlers:**
- `reference/handlers/manager/data-tool.md`

**TTS Handlers:**
- `reference/handlers/tts/bailian-cosyvoice.md`
- `reference/handlers/tts/cosyvoice-local.md`
- `reference/handlers/tts/edge-tts.md`

**VAD Handlers:**
- `reference/handlers/vad/silero-vad.md`
- `reference/handlers/vad/smart-turn.md`

#### Releases
- `releases/release-notes.md`

#### English Documentation (en/)
Same structure repeated with additional content in `en/` subdirectory

#### Beta Features
- `beta/index.md`
- `beta/chat-agent.md`

### Assets Directory
- `assets/images/bilibili_video.jpg`
- `assets/images/community_wechat.png`
- `assets/images/data_flow.svg`
- `assets/images/modelscope_logo.png`

### Build Directory
- `build/components_will_be_built_here.txt`

### COTURN Data
- `coturn-data/turnserver.conf`

### Extensions
- `extensions/openclaw/oac-bridge/index.ts`
- `extensions/openclaw/oac-bridge/package.json`
- `extensions/openclaw/oac-bridge/openclaw.plugin.json`
- `extensions/openclaw/oac-bridge/src/accounts.ts`
- `extensions/openclaw/oac-bridge/src/channel.ts`
- `extensions/openclaw/oac-bridge/src/gateway-runtime.ts`
- `extensions/openclaw/oac-bridge/src/inbound-context.ts`
- `extensions/openclaw/oac-bridge/src/inbound-turn.ts`
- `extensions/openclaw/oac-bridge/src/profile-tool.ts`
- `extensions/openclaw/oac-bridge/src/runtime.ts`
- `extensions/openclaw/oac-bridge/src/session-key.ts`
- `extensions/openclaw/oac-bridge/src/tasks-tool.ts`
- `extensions/openclaw/oac-bridge/src/types.ts`

### Models Directory
- `models/put_models_here.txt`

### Resources
- `resource/avatar/put_avatar_here.txt`
- `resource/avatar/flashhead/girl.png`

### Scripts
- `scripts/create_ssl_certs.sh`
- `scripts/download_avatar_model.py`
- `scripts/download_liteavatar_weights.sh`
- `scripts/download_models.py`
- `scripts/download_musetalk_weights.sh`
- `scripts/download_smart_turn_weights.sh`
- `scripts/setup_coturn.sh`

### Source Code (`src/`)

#### Main Demo
- `demo.py`

#### Chat Engine
- `chat_engine/__init__.py`
- `chat_engine/chat_engine.py`

**Common Modules:**
- `chat_engine/common/client_handler_base.py`
- `chat_engine/common/handler_base.py`
- `chat_engine/common/logic_base.py`

**Contexts:**
- `chat_engine/contexts/common_module_context.py`
- `chat_engine/contexts/handler_context.py`
- `chat_engine/contexts/logic_context.py`
- `chat_engine/contexts/session_clock.py`
- `chat_engine/contexts/session_context.py`
- `chat_engine/contexts/session_history.py`

**Core:**
- `chat_engine/core/chat_session.py`
- `chat_engine/core/handler_manager.py`
- `chat_engine/core/logic_manager.py`
- `chat_engine/core/signal_filter.py`
- `chat_engine/core/signal_manager.py`
- `chat_engine/core/stream_filter.py`
- `chat_engine/core/stream_manager.py`

**Data Models:**
- `chat_engine/data_models/chat_data_type.py`
- `chat_engine/data_models/chat_engine_config_data.py`
- `chat_engine/data_models/chat_signal.py`
- `chat_engine/data_models/chat_signal_type.py`
- `chat_engine/data_models/chat_stream.py`
- `chat_engine/data_models/chat_stream_config.py`
- `chat_engine/data_models/chat_stream_status.py`
- `chat_engine/data_models/engine_channel_type.py`
- `chat_engine/data_models/session_info_data.py`

**Chat Data Models:**
- `chat_engine/data_models/chat_data/chat_data_model.py`

**Internal Data Models:**
- `chat_engine/data_models/internal/chat_data_endpoints.py`
- `chat_engine/data_models/internal/handler_definition_data.py`
- `chat_engine/data_models/internal/handler_session_data.py`
- `chat_engine/data_models/internal/logic_definition_data.py`
- `chat_engine/data_models/internal/logic_session_data.py`

**Runtime Data Models:**
- `chat_engine/data_models/runtime_data/data_bundle.py`
- `chat_engine/data_models/runtime_data/data_store.py`
- `chat_engine/data_models/runtime_data/event_model.py`
- `chat_engine/data_models/runtime_data/motion_data.py`
- `chat_engine/data_models/runtime_data/motion_data_descriptors.py`
- `chat_engine/data_models/runtime_data/motion_entry_serializer_base.py`
- `chat_engine/data_models/runtime_data/motion_entry_serializers/int16_audio_serializer.py`
- `chat_engine/data_models/runtime_data/time_unit_type.py`

#### Engine Utilities
- `engine_utils/directory_info.py`
- `engine_utils/general_slicer.py`
- `engine_utils/import_utils.py`
- `engine_utils/inspect_utils.py`
- `engine_utils/interval_counter.py`
- `engine_utils/media_utils.py`
- `engine_utils/path_utils.py`
- `engine_utils/singleton.py`
- `engine_utils/text_filter.py`
- `engine_utils/time_utils.py`

**Audio Utilities:**
- `engine_utils/audio_utils/auto_gain_control.py`
- `engine_utils/audio_utils/common_audio_utils.py`

#### Handlers

**Agent Handler:**
- `handlers/agent/agent_data_models.py`
- `handlers/agent/chat_agent_handler.py`
- `handlers/agent/pyproject.toml`

**Agent Memory:**
- `handlers/agent/memory/perception_buffer.py`
- `handlers/agent/memory/session_memory_manager.py`
- `handlers/agent/memory/session_summary.py`
- `handlers/agent/memory/working_memory.py`
- `handlers/agent/memory/write_behind_queue.py`

**Agent OpenClaw Bridge:**
- `handlers/agent/oc_bridge/mcp_client.py`
- `handlers/agent/oc_bridge/memory_retriever.py`
- `handlers/agent/oc_bridge/oc_bridge_init.py`
- `handlers/agent/oc_bridge/oc_channel_client.py`
- `handlers/agent/oc_bridge/oc_prompt_injection.py`
- `handlers/agent/oc_bridge/oc_reply_bridge.py`
- `handlers/agent/oc_bridge/oc_tools.py`
- `handlers/agent/oc_bridge/pending_confirmations.py`
- `handlers/agent/oc_bridge/persona_snapshot_mgr.py`
- `handlers/agent/oc_bridge/task_mirror.py`
- `handlers/agent/oc_bridge/task_notification_queue.py`

**Agent Perception:**
- `handlers/agent/perception/perception_handler.py`
- `handlers/agent/perception/vision_model_interface.py`

**Agent Prompt:**
- `handlers/agent/prompt/prompt_compiler.py`

**Agent Scheduler:**
- `handlers/agent/scheduler/scheduler_layer.py`

**Agent Tools:**
- `handlers/agent/tools/base_tool.py`
- `handlers/agent/tools/demo_tools.py`
- `handlers/agent/tools/exec_approve.py`
- `handlers/agent/tools/pending_confirmations_tool.py`
- `handlers/agent/tools/spawn_agent.py`
- `handlers/agent/tools/tool_registry.py`

**Analyzer Handler:**
- `handlers/analyzer/analyzer_html_generator.py`
- `handlers/analyzer/analyzer_json_exporter.py`
- `handlers/analyzer/analyzer_models.py`
- `handlers/analyzer/vad_eou_analyzer.py`

**ASR Handlers:**
- `handlers/asr/bailian_asr/asr_handler_bailian.py`
- `handlers/asr/bailian_asr/pyproject.toml`
- `handlers/asr/sensevoice/asr_handler_sensevoice.py`
- `handlers/asr/sensevoice/pyproject.toml`

**Avatar: FlashHead:**
- `handlers/avatar/flashhead/avatar_handler_flashhead.py`
- `handlers/avatar/flashhead/flashhead_config.py`
- `handlers/avatar/flashhead/flashhead_face_crop.py`
- `handlers/avatar/flashhead/flashhead_processor.py`
- `handlers/avatar/flashhead/pyproject.toml`

**Avatar: LAM:**
- `handlers/avatar/lam/avatar_handler_lam_audio2expression.py`
- `handlers/avatar/lam/pyproject.toml`
- `handlers/avatar/lam/assets/arkit_face_channels.txt`

**Avatar: LiteAvatar:**
- `handlers/avatar/liteavatar/avatar_handler_liteavatar.py`
- `handlers/avatar/liteavatar/avatar_output_handler.py`
- `handlers/avatar/liteavatar/avatar_processor.py`
- `handlers/avatar/liteavatar/avatar_processor_factory.py`
- `handlers/avatar/liteavatar/liteavatar_handler_context.py`
- `handlers/avatar/liteavatar/liteavatar_worker.py`
- `handlers/avatar/liteavatar/liteavatar_worker_manager.py`
- `handlers/avatar/liteavatar/pyproject.toml`
- `handlers/avatar/liteavatar/shared_memory_buffer_pool.py`

**LiteAvatar Algorithm:**
- `handlers/avatar/liteavatar/algo/audio2signal_speed_limiter.py`
- `handlers/avatar/liteavatar/algo/base_algo_adapter.py`
- `handlers/avatar/liteavatar/algo/bg_frame_counter.py`
- `handlers/avatar/liteavatar/algo/tts2face_cpu_adapter.py`

**LiteAvatar Media:**
- `handlers/avatar/liteavatar/media/speech_audio_aligner.py`
- `handlers/avatar/liteavatar/media/speech_audio_processor.py`
- `handlers/avatar/liteavatar/media/video_audio_aligner.py`

**LiteAvatar Model:**
- `handlers/avatar/liteavatar/model/algo_model.py`
- `handlers/avatar/liteavatar/model/audio_input.py`

**Avatar: MuseTalk:**
- `handlers/avatar/musetalk/ARCHITECTURE.md`
- `handlers/avatar/musetalk/avatar_handler_musetalk.py`
- `handlers/avatar/musetalk/musetalk_algo.py`
- `handlers/avatar/musetalk/musetalk_config.py`
- `handlers/avatar/musetalk/musetalk_data_models.py`
- `handlers/avatar/musetalk/musetalk_processor.py`
- `handlers/avatar/musetalk/musetalk_review.md`
- `handlers/avatar/musetalk/musetalk_utils_preprocessing.py`
- `handlers/avatar/musetalk/pyproject.toml`

**Avatar: Without Avatar:**
- (placeholder directory structure)

**GitHub Workflows:**
- `.github/workflows/deploy-docs.yml`

This repository represents an extensive avatar chat system with modular handlers for speech recognition, text-to-speech, avatar animation, and AI agent functionalities.


Now I have the key file: `handlers/avatar/lam/avatar_handler_lam_audio2expression.py`. Let me fetch it.


WebFetch

Prompt: Show the COMPLETE Python source code - all imports, class definitions, method signatures and bodies. Do not summarize.


The server returned HTTP 404 Not Found.

The response body was not retrieved. If this URL requires authentication, use an authenticated tool (e.g. `gh` for GitHub, or an MCP-provided fetch tool) instead of WebFetch.


Prompt: Show the COMPLETE Python source code - all imports, class definitions, functions. How does streaming audio input work? What format does audio come in? What is the output?


# Audio Streaming Analysis

## Complete Source Code
The provided content shows a **main inference script** (not a complete library). Key components:

```python
from engines.defaults import default_argument_parser, default_config_parser, default_setup
from engines.infer import INFER
import librosa
from tqdm import tqdm
import time
from models.utils import export_blendshape_animation, ARKitBlendShape
```

The script includes one custom function:
- `export_json()` - exports blend shape animation data to JSON format at 30fps using ARKit format

## Streaming Audio Input Mechanism

**Audio Loading & Processing:**
- Audio is loaded via `librosa.load()` at 16kHz sample rate
- The stream is divided into **1-second chunks** (16,000 samples at 16kHz)
- Processing: `audio[i*gap:(i+1)*gap]` where `gap = 16000`

**Streaming Context:**
The function `infer_streaming_audio()` maintains a persistent `context` variable between calls, enabling the model to process audio sequentially while preserving state information.

## Input/Output Format

**Input:** Raw audio array (NumPy format) at 16kHz mono

**Output:** Dictionary containing `'expression'` key with facial expression/blend shape data (NumPy array)

**Final Output:** All expressions concatenated into a single array, then exported as JSON representing "ARKit blend shape animation" at 30fps—a format for facial animation data used in 3D character generation.


Prompt: Show the full raw source code line by line - do not summarize at all


Prompt: Show the complete source code of the network module - all class definitions, forward methods, input/output shapes


# Full Raw Source Code Line by Line

```
1  # Copyright 2024-2025 The Alibaba 3DAIGC Team Authors. All rights reserved.
2
3  Licensed under the Apache License, Version 2.0 (the "License");
4  you may not use this file except in compliance with the License.
5  You may obtain a copy of the License at
6
7      https://www.apache.org/licenses/LICENSE-2.0
8
9  Unless required by applicable law or agreed to in writing, software
10 distributed under the License is distributed on an "AS IS" BASIS,
11 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 See the License for the specific language governing permissions and
13 limitations under the License.
14
15 """
16
17 import numpy as np
18
19 from engines.defaults import (
20     default_argument_parser,
21     default_config_parser,
21     default_setup,
22 )
23 from engines.infer import INFER
24 import librosa
25 from tqdm import tqdm
26 import time
27
28
29 def export_json(bs_array, json_path):
30     from models.utils import export_blendshape_animation, ARKitBlendShape
31     export_blendshape_animation(bs_array, json_path, ARKitBlendShape, fps=30.0)
32
33 if __name__ == '__main__':
34     args = default_argument_parser().parse_args()
35     args.config_file = 'configs/lam_audio2exp_config_streaming.py'
36     cfg = default_config_parser(args.config_file, args.options)
37
38
39     cfg = default_setup(cfg)
40     infer = INFER.build(dict(type=cfg.infer.type, cfg=cfg))
41     infer.model.eval()
42
43     audio, sample_rate = librosa.load(cfg.audio_input, sr=16000)
44     context = None
45     input_num = audio.shape[0]//16000+1
46     gap = 16000
47     all_exp = []
48     for i in tqdm(range(input_num)):
49
50         start = time.time()
51         output, context = infer.infer_streaming_audio(audio[i*gap:(i+1)*gap], sample_rate, context)
52         end = time.time()
53         print('Inference time {}'.format(end - start))
54         all_exp.append(output['expression'])
55
56     all_exp = np.concatenate(all_exp,axis=0)
57
58     export_json(all_exp, cfg.save_json_path)
```


# Audio-to-Expression Neural Network Module

This codebase implements multiple neural architectures for audio-driven facial expression generation. Here's a comprehensive overview:

## Core Architecture Classes

### 1. **Audio2Expression** (Main Model)
- **Input**: Dictionary containing `input_audio_array` (B×T), `id_idx`, optional `time_steps`
- **Output**: Expression parameters via sigmoid, shape (B×T×52)
- **Key components**:
  - Audio encoder (Wav2Vec2 or WavLM, outputs 768-dim features)
  - Feature projection to hidden dimension (512-dim default)
  - Identity encoder for conditional processing
  - Decoder stack with ConvNormRelu blocks
  - Linear projection to expression_dim (52 default)

### 2. **AudioIdentityEncoder**
- **Input**: Audio features (B×hidden_dim×T), identity tensor
- **Output**: Refined features (B×hidden_dim×T)
- **Process**: "Concatenates identity embeddings with audio features, processes through sequential layers with optional transformer"

### 3. **MeshtalkEncoder**
- **Input**: Audio tensor (B×T×16000)
- **Output**: Latent embedding dictionary with "code" key (B×T×latent_dim)
- **Architecture**: MelSpectrogram → Conv1d layers with dilations → latent projection

### 4. **GeneratorTransformer**
- **Input**: Spectrogram, optional ground-truth poses, identity
- **Output**: Pose predictions (B×T×32)
- **Features**: Dual audio encoding pathways (MeshTalk/FaceFormer options), transformer decoder with periodic positional encoding

### 5. **UniTalkerDecoderTransformer**
- **Input**: Hidden states (B×T×out_dim), style index, frame count
- **Output**: Decorated features (B×T×out_dim)
- **Distinctive element**: "Learnable style embeddings with biased attention masking and periodic positional encoding"

## Utility Components

- **ConvNormRelu**: Flexible convolution block supporting 1D/2D, batch/group/layer normalization, residual connections
- **SeqTranslator1D**: Sequential 1D convolution translator
- **PeriodicPositionalEncoding**: "Sine/cosine positional encoding with periodic structure for temporal sequences"
- **audio_chunking()**: Slices 16kHz audio into frame-aligned chunks

All models operate on 16kHz audio sampled at ~30 fps video frame rate.


Prompt: Show the complete source code, especially ARKitBlendShape enum/class and export_blendshape_animation function. What are the 52 ARKit blendshape names?


Prompt: Show the complete Python source code


# ARKit Blendshape Names and Export Function

## The 52 ARKit Blendshape Names

The code defines these as a Python list constant:

```python
ARKitBlendShape =[
   "browDownLeft", "browDownRight", "browInnerUp", "browOuterUpLeft",
   "browOuterUpRight", "cheekPuff", "cheekSquintLeft", "cheekSquintRight",
   "eyeBlinkLeft", "eyeBlinkRight", "eyeLookDownLeft", "eyeLookDownRight",
   "eyeLookInLeft", "eyeLookInRight", "eyeLookOutLeft", "eyeLookOutRight",
   "eyeLookUpLeft", "eyeLookUpRight", "eyeSquintLeft", "eyeSquintRight",
   "eyeWideLeft", "eyeWideRight", "jawForward", "jawLeft", "jawOpen",
   "jawRight", "mouthClose", "mouthDimpleLeft", "mouthDimpleRight",
   "mouthFrownLeft", "mouthFrownRight", "mouthFunnel", "mouthLeft",
   "mouthLowerDownLeft", "mouthLowerDownRight", "mouthPressLeft",
   "mouthPressRight", "mouthPucker", "mouthRight", "mouthRollLower",
   "mouthRollUpper", "mouthShrugLower", "mouthShrugUpper", "mouthSmileLeft",
   "mouthSmileRight", "mouthStretchLeft", "mouthStretchRight",
   "mouthUpperUpLeft", "mouthUpperUpRight", "noseSneerLeft", "noseSneerRight",
   "tongueOut"
]
```

## Export Function Overview

The `export_blendshape_animation()` function serializes animation data to JSON. It accepts "52 blendshape weights (N frames), output path, corresponding name labels, frame rate," and optional rotation data. The function validates inputs, constructs a structured dictionary with metadata and per-frame weights with timing, and writes to a JSON file with error handling.


Prompt: Extract the COMPLETE Python source code - all class definitions, imports, methods. Show everything.


Prompt: Show the complete Python source code


Prompt: Return the download_url of this file


Prompt: Show complete source code


# OpenAvatarChat Web Server - Source Code Analysis

## Overview
This Python application sets up a web-based chat interface combining FastAPI, Gradio, and a custom ChatEngine for real-time avatar conversations.

## Key Components

**Main Dependencies:**
- FastAPI for the backend server
- Gradio for the web UI
- Uvicorn as the ASGI server
- PyTorch for model operations

**Core Architecture:**

The `OpenAvatarChatWebServer` class extends `uvicorn.Server` to integrate a custom chat engine. The initialization accepts a ChatEngine instance and manages graceful shutdown, ensuring the engine properly closes connections before the server stops.

**Configuration System:**

Arguments parse host, port, config file path, and environment selection. The system prioritizes environment variables (`OPEN_AVATAR_CHAT_CONFIG`) over command-line arguments. Configuration loading handles multiple aspects: logging setup, service parameters, and engine settings.

**PyTorch Patching:**

The code modifies torch.load behavior to enforce `weights_only=False` by default, ensuring compatibility with model loading operations that might otherwise fail with stricter security settings.

**UI Setup:**

The `setup_demo()` function creates a FastAPI application with embedded Gradio interface, applies responsive CSS for mobile compatibility, and hides default footer elements.

**Startup Flow:**

1. Parse arguments
2. Load configurations
3. Configure logging and environment
4. Initialize UI components
5. Create and configure ChatEngine
6. Setup SSL context
7. Launch Uvicorn server with custom shutdown handler

The error handling uses KeyboardInterrupt catching and signal management for clean termination.


Prompt: Show the complete Python source code, do not summarize


Prompt: Show complete source code - what data model does motion data use?


Prompt: Show the complete Python source code, all lines


Prompt: Show the complete Python source code


Prompt: List all files visible and extract any code content shown in the page


Prompt: Show the complete content of the arkit_face_channels.txt file


Prompt: List files in this directory and return their download_urls


Prompt: Show the complete documentation content about LAM setup, configuration, audio pipeline, and how it integrates


# LAM Quick Start Documentation Summary

Based on the GitHub documentation provided, here's what the LAM setup entails:

## Overview
The LAM integration enables "端侧渲染" (edge-side rendering) using Gaussian Splatting assets. The system leverages CosyVoice from Bailian for speech, with only VAD (Voice Activity Detection) and ASR (Automatic Speech Recognition) running locally on GPU, keeping hardware demands minimal.

## Handler Components

The pipeline uses six specialized handlers:

1. **Client**: WebSocket LAM client for communication
2. **VAD**: Silero-based voice detection
3. **ASR**: SenseVoice for speech recognition
4. **LLM**: OpenAI-compatible language model interface
5. **TTS**: Bailian CosyVoice for speech synthesis
6. **Avatar**: LAM audio-to-expression conversion

## Setup Process

The implementation requires three sequential steps:

- Installing dependencies via configuration file
- Downloading necessary models for the LAM handler
- Launching the demo application

Each handler links to detailed reference documentation for configuration specifics. The architecture supports "一机多路" (multiple streams per machine), suggesting scalability for concurrent interactions.


Prompt: Show the complete markdown content


Prompt: Show the complete content about how the pipeline works


# LAM Quick Start Guide Summary

This documentation covers setting up LAM, a Gaussian Splatting asset renderer with voice capabilities. Here are the key points:

## Core Components

The system uses several integrated handlers: a WebSocket client for LAM, Silero for voice activity detection, SenseVoice for speech recognition, OpenAI-compatible LLM support, Bailian's CosyVoice for text-to-speech, and LAM's audio-to-expression avatar handler.

## Key Features

"语音使用百炼上的 CosyVoice，只有 VAD 和 ASR 运行在本地 GPU" — the setup relies on cloud-based voice synthesis while keeping voice processing local, making it lightweight for multi-channel deployment.

## Setup Process

Getting started involves three straightforward steps: installing dependencies via a configuration file, downloading necessary models for LAM, and launching the demo application. All commands use the `uv` package manager with specific configuration and script files.

This approach balances local processing efficiency with cloud services for voice generation, suitable for resource-constrained environments requiring multiple concurrent streams.


# Open Avatar Chat Pipeline Overview

## Core Architecture

The system employs "a modular Handler architecture" that combines different components. The main modules include:

- **Client Handler**: Manages WebRTC audio/video streaming
- **VAD Handler**: Detects when users are speaking
- **ASR Handler**: Converts speech to text
- **LLM Handler**: Generates conversational responses
- **Agent Handler**: Handles multi-turn tool interactions (Beta feature)
- **TTS Handler**: Synthesizes text into speech
- **Avatar Handler**: Creates facial animations synchronized with audio

## Processing Flow

The interaction sequence follows these steps:

1. Browser transmits audio/video via WebRTC
2. Voice activity detection identifies speech
3. Speech recognition converts audio to text
4. Language model or agent generates responses
5. Text-to-speech creates audio output
6. Avatar engine produces matching facial movements
7. Synthesized media returns through WebRTC

## Performance Metrics

Testing on high-end hardware (i9-13900KF + RTX 4090) showed "average latency of approximately 2.2 seconds." This measurement spans from when users finish speaking until the avatar begins responding, encompassing network transmission delays, VAD processing time, and computational overhead throughout the entire pipeline.


Prompt: Show the complete documentation about the LAM client - what protocol it uses, how it communicates, WebSocket details, data format


Prompt: Show the complete documentation about the LAM avatar handler


# LAM Client Documentation Summary

Based on the provided content, here's what the documentation reveals about the LAM client:

## Protocol & Communication
The LAM client handler extends the "RTC Client Handler" and operates as a WebSocket-based solution. The module reference indicates it uses `ws_lam_client_handler`, suggesting WebSocket as the underlying communication protocol.

## Key Capabilities
The system supports multiple simultaneous connections through a configurable concurrency limit. The implementation allows selection from pre-trained character models for rendering purposes.

## Configuration
Users can specify character assets via configuration file:
- **Module path**: `client/ws_lam_client/ws_lam_client_handler`
- **Asset format**: ZIP files containing model data
- **Example asset**: `lam_samples/barbara.zip`
- **Concurrency control**: Adjustable connection limits

## Limitations of Available Information
The provided documentation excerpt doesn't include specific details about:
- Exact WebSocket message formats or data structures
- Protocol handshake procedures
- Payload specifications for client-server communication
- Detailed architectural diagrams

For comprehensive protocol specifications and data format details, you would need to consult the full documentation or the LAM project repository directly.


# LAM Avatar Handler Documentation

## Overview
The LAM digital avatar handler enables audio-driven character animation capabilities.

## Model Dependencies

The handler requires two key models:

**1. wav2vec2-base-960h**
This speech recognition model can be downloaded from HuggingFace or ModelScope (recommended for users in mainland China). Users may clone the repository directly using git commands provided in the documentation.

**2. LAM_audio2exp**
This model converts audio to facial expressions. It's available through HuggingFace or alternatively via Alibaba Cloud OSS for improved download speeds in certain regions.

## Installation Methods

**Automatic Setup:**
Run the download script specifying the LAM handler. Mainland Chinese users should add the ModelScope source parameter for faster downloads.

**Manual Installation:**
Detailed instructions are provided for both models, including git clone commands for the speech model and wget/tar extraction commands for the audio-to-expression model from multiple mirror sources.

The documentation emphasizes accessibility for international users while providing optimized download options for specific regions, making deployment flexible across different network environments.


Prompt: Show the complete YAML configuration for LAM chat mode


# LAM Chat Mode YAML Configuration

Based on the provided configuration, here's the complete setup for LAM (Live Avatar Mode) chat:

## Core Components

**Service Layer:**
- Host: `0.0.0.0`, Port: `8282`
- SSL certificates configured for secure connections

**Chat Engine:**
- Model directory: `models`
- Maximum concurrent sessions: `5`

## Handler Configuration

The LAM setup includes these key handlers:

1. **LamClient** - Manages WebSocket connections with `connection_ttl: 900` seconds
2. **SileroVad** - Voice activity detection with configurable thresholds
3. **SenseVoice** - ASR module for speech recognition
4. **CosyVoice** - Text-to-speech synthesis (voice: "longxiaocheng")
5. **LLMOpenAICompatible** - Language model integration using Qwen-Plus
6. **LAM_Driver** - Avatar handler for audio-to-expression conversion

## System Behavior

The system is configured to produce "brief two-to-three sentence responses with appropriate punctuation," operating as an interactive AI assistant through the LAM avatar framework with real-time speech processing and synthesis capabilities.


Prompt: Extract all content about the WebGL renderer - what protocol it uses to receive avatar data, how it renders Gaussian splats in browser, WebSocket data format, JavaScript API


# LAM_WebRender: WebGL Renderer Analysis

Based on the GitHub repository content provided, here's what's documented about the renderer:

## Core Technology
The project describes itself as a **"Lightweight WebGL Renderer"** for real-time 3D avatar rendering. It's implemented in TypeScript (83.2% of codebase) with HTML components.

## Data Integration
The renderer accepts avatar model data as ZIP files. The documentation shows: **"./asset/arkit/p2-1.zip"** as the example model format, and facial animation data via JSON files like **"./asset/test_expression_1s.json"** for expression control.

## API Usage
The NPM package provides a straightforward JavaScript interface:

```javascript
const render = await GaussianSplats3D.GaussianSplatRenderer.getInstance(div, assetPath);
```

The renderer instantiates with a DOM element target and asset path pointing to model files.

## Limitations in Available Documentation
The provided content does **not** detail:
- Specific WebSocket protocols or real-time data formats
- Internal Gaussian splatting rendering algorithms
- Binary data structures for streaming
- Network communication specifics

The repository appears focused on integration and usage rather than technical architecture documentation. For implementation details, consulting the actual source code in the `/src` directory or the [NPM package documentation](https://www.npmjs.com/package/gaussian-splat-renderer-for-lam) would be necessary.


Prompt: Show the complete README content


Prompt: List all file paths in the repository


# LAM_WebRender Overview

LAM_WebRender is a lightweight WebGL renderer designed for real-time 3D Gaussian Splatting, specifically built to work with LAM avatars and facial animation systems.

## Key Capabilities

The engine offers "real-time rendering support: Interactive LAM avatars with LAM_Audio2Expression facial animations." It's distributed as an NPM package for easy integration into web projects.

## Getting Started

Installation requires three simple steps: install dependencies via npm, launch the development server, and access it through a local browser connection at port 5173.

## Core Functionality

The system integrates three complementary technologies:
- **Avatar generation** via the LAM project
- **Expression synthesis** through LAM_Audio2Expression (converting audio to ARKit blendshapes)
- **Real-time visualization** using this rendering engine

## Usage

Developers can integrate the package by importing the renderer and specifying asset paths for avatar models (ZIP files) and expression data (JSON format).

## Advanced Features

The documentation notes that "custom avatars" can be created by "generating new models via LAM and replacing ZIP files," allowing for extensibility beyond pre-built examples.

The project operates under MIT License terms.


# File Paths in LAM_WebRender Repository

Based on the GitHub API response, here are all the files and directories:

**Root Level Files:**
- .gitignore
- LICENSE
- README.md
- index.html
- package.json
- tsconfig.json
- vite.config.ts

**Directories:**
- asset/
- asset/arkit/
- src/

**Asset Files:**
- asset/arkit/p2-1.zip
- asset/test_expression_1s.json

**Source Files:**
- src/gaussianAvatar.ts
- src/main.ts

This appears to be a web rendering project using TypeScript and Vite, with Gaussian avatar functionality and test assets included.


Prompt: Show the COMPLETE TypeScript source code


Prompt: Show the COMPLETE TypeScript source code


# TypeScript Source Code Analysis

Based on the provided snippet, here's what the complete TypeScript implementation would likely include:

```typescript
import { GaussianAvatar } from './gaussianAvatar';

const div = document.getElementById('LAM_WebRender');
const assetPath = './asset/arkit/p2-1.zip';

const gaussianAvatar = new GaussianAvatar(div, assetPath);
gaussianAvatar.start();
```

## Key Components

The code demonstrates:

1. **Import Statement**: References a `GaussianAvatar` class from a local module
2. **DOM Selection**: Targets an element with ID "LAM_WebRender"
3. **Asset Configuration**: Points to a compressed asset file (p2-1.zip)
4. **Initialization**: Creates an instance and invokes the start method

## Missing Context

To provide the **complete** TypeScript source code, I would need:

- The `GaussianAvatar` class definition (constructor, methods, properties)
- Type definitions for the parameters
- Any additional configuration or error handling
- The full module structure

The snippet shown represents only the instantiation layer. The actual implementation details of the `GaussianAvatar` class aren't visible in this excerpt.


# GaussianAvatar TypeScript Source Code

The provided code presents a complete TypeScript class for rendering a Gaussian Splat 3D avatar. Here's the full source:

```typescript
import * as GaussianSplats3D from "gaussian-splat-renderer-for-lam"
import bsData from "../asset/test_expression_1s.json"

export class GaussianAvatar {
  private _avatarDivEle: HTMLDivElement;
  private _assetsPath = "";
  public curState = "Idle";
  private _renderer: GaussianSplats3D.GaussianSplatRenderer;

  constructor(container: HTMLDivElement, assetsPath: string) {
    this._avatarDivEle = container;
    this._assetsPath = assetsPath;
    this._init();
  }

  private _init() {
    if (!this._avatarDivEle || !this._assetsPath) {
      throw new Error("Lack of necessary initialization parameters");
    }
  }

  public start() {
    this.render();
  }

  public async render() {
    this._renderer = await GaussianSplats3D.GaussianSplatRenderer.getInstance(
      this._avatarDivEle,
      this._assetsPath,
      {
        getChatState: this.getChatState.bind(this),
        getExpressionData: this.getArkitFaceFrame.bind(this),
        backgroundColor: "0xff0000",
        alpha: 0.2
      },
    );
    this.startTime = performance.now() / 1000;
    setTimeout(() => { this.curState = "Listening" }, 5000);
    setTimeout(() => { this.curState = "Thinking" }, 6000);
    setTimeout(() => { this.curState = "Responding" }, 10000);
  }

  expressitionData: any;
  startTime = 0

  public getChatState() {
    return this.curState;
  }

  public getArkitFaceFrame() {
    const length = bsData["frames"].length
    const frameInfoInternal = 1.0 / 30.0;
    const currentTime = performance.now() / 1000;
    const calcDelta = (currentTime - this.startTime) % (length * frameInfoInternal);
    const frameIndex = Math.floor(calcDelta / frameInfoInternal)
    this.expressitionData = {};

    bsData["names"].forEach((name: string, index: number) => {
      this.expressitionData[name] = bsData["frames"][frameIndex]["weights"][index]
    })
    return this.expressitionData;
  }
}
```

**Key functionality:** The class manages a 3D avatar renderer with state transitions (Idle → Listening → Thinking → Responding) and facial expression data mapped from frame-based animation data.


Prompt: Show the complete JSON structure - what keys exist at top level, what each frame looks like, what the names array contains


Prompt: Show complete source code


The server returned HTTP 404 Not Found.

The response body was not retrieved. If this URL requires authentication, use an authenticated tool (e.g. `gh` for GitHub, or an MCP-provided fetch tool) instead of WebFetch.


# JSON Structure Analysis

## Top-Level Keys
The JSON object contains three primary keys:

1. **`names`** - Array of facial expression/animation target names
2. **`frames`** - Array of animation keyframes
3. (Implied structure suggests this is animation data)

## Names Array
Contains 52 facial blend shape identifiers controlling facial features:

- **Brow controls**: browDownLeft, browDownRight, browInnerUp, browOuterUpLeft, browOuterUpRight
- **Cheek controls**: cheekPuff, cheekSquintLeft, cheekSquintRight
- **Eye controls**: eyeBlinkLeft, eyeBlinkRight, eyeLookDownLeft/Right, eyeLookInLeft/Right, eyeLookOutLeft/Right, eyeLookUpLeft/Right, eyeSquintLeft/Right, eyeWideLeft/Right
- **Jaw controls**: jawForward, jawLeft, jawOpen, jawRight
- **Mouth controls**: mouthClose, mouthDimpleLeft/Right, mouthFrownLeft/Right, mouthFunnel, mouthLeft/Right, mouthLowerDownLeft/Right, mouthPressLeft/Right, mouthPucker, mouthRollLower/Upper, mouthShrugLower/Upper, mouthSmileLeft/Right, mouthStretchLeft/Right, mouthUpperUpLeft/Right
- **Nose controls**: noseSneerLeft, noseSneerRight
- **Tongue**: tongueOut

## Frame Structure
Each frame object contains:

- **`weights`** - Array of 52 numeric values (0.0–1.0 range) corresponding to each name, representing blend shape intensities
- **`time`** - Float timestamp indicating frame position in animation sequence
- **`rotation`** - Empty array (currently unused in provided data)

This represents facial animation keyframe data, likely for character rigging systems like those used in 3D graphics or game engines.


Prompt: Show complete source code


Prompt: Show the complete Python source code shown in this GitHub file view


Prompt: Return the content or download_url field from this API response


Prompt: Show the complete Python source code - especially the INFER class and infer_streaming_audio method


# Audio2ExpressionInfer Class Overview

The provided code shows the complete implementation of the `Audio2ExpressionInfer` class, which is registered via the `@INFER.register_module()` decorator. Here's a summary of key components:

## Main Inference Method

The `infer()` method processes audio input to generate facial expression parameters. It:
- Loads audio at 16kHz sample rate using librosa
- Optionally extracts vocal tracks using Spleeter
- Passes audio through the model with identity encoding
- Applies post-processing including "smooth_mouth_movements" and "apply_random_brow_movement"

## Streaming Audio Processing

The `infer_streaming_audio()` method handles real-time audio input with context management:

**Key features:**
- Maintains a rolling context buffer with "max_frame_length" of 64 frames
- Resamples incoming audio to match the model's expected sample rate
- Concatenates previous audio segments with new input for temporal coherence
- Returns expression parameters along with an updated context dictionary

**Processing pipeline:**
```
Audio resampling → Audio concatenation → Model inference →
Expression post-processing → Context state update
```

## Post-Processing Pipeline

The `apply_expression_postprocessing()` method executes sequential transformations:
- "smooth_mouth_movements" for audio synchronization
- "apply_frame_blending" for temporal smoothing
- Savitzky-Golay filtering for noise reduction
- "symmetrize_blendshapes" for facial symmetry
- "apply_random_eye_blinks_context" for natural eye movement

The code is licensed under Apache License 2.0 by Alibaba's 3DAIGC Team.


Prompt: Show the COMPLETE raw Python source code. Show every line including the infer_streaming_audio signature with parameter types, context structure, return type, and what model.forward() receives


# Audio2ExpressionInfer: Complete Source Code Analysis

## Method Signature with Types

```python
def infer_streaming_audio(self,
                         audio: np.ndarray,
                         ssr: float,
                         context: dict) -> tuple[dict, dict]:
```

## Context Structure

The context dictionary maintains streaming state:

```python
context = {
    'is_initial_input': bool,
    'previous_audio': np.ndarray | None,
    'previous_expression': np.ndarray | None,
    'previous_volume': np.ndarray | None,
    'first_input_flag': bool
}
```

Default initialization uses `DEFAULT_CONTEXT.copy()`.

## Model Forward Input

The model receives:

```python
input_dict = {
    'id_idx': torch.Tensor,  # One-hot encoded identity [1, num_identity_classes]
    'input_audio_array': torch.Tensor  # Audio signal [1, audio_samples]
}

output_dict = self.model(input_dict)
# Contains: output_dict['pred_exp']  # [frames, 52] blendshape parameters
```

## Return Structure

```python
return {
    "code": str,  # RETURN_CODE['SUCCESS']
    "expression": np.ndarray,  # [frames, 52] processed expressions
    "headpose": None
}, output_context  # Updated context dict
```

## Processing Pipeline

Audio undergoes resampling, concatenation with context history (max 64 frames), model inference, then "full post-processing pipeline" including mouth smoothing, frame blending, Savitzky-Golay filtering, blendshape symmetrization, and eye blink synthesis.


I now have all the information needed for a comprehensive answer. Let me compile the full picture.

Here is a comprehensive technical report on the LAM + OpenAvatarChat pipeline for real-time talking avatar integration.

---

## Pipeline Architecture Overview

The full stack has three distinct layers: **Audio2Expression** (Python, server-side), **LAM Gaussian Splatting Renderer** (either Python server-side render *or* WebGL client-side), and a **WebRTC/WebSocket frontend**.

---

## 1. Real-Time Audio-Driven Avatar Pipeline

The end-to-end flow in OpenAvatarChat (`HumanAIGC-Engineering/OpenAvatarChat`, not `aigc3d/OpenAvatarChat`) is:

```
Browser audio (mic)
  → WebRTC → Python server
    → VAD (Silero) → ASR (SenseVoice) → LLM → TTS (CosyVoice)
      → Audio bytes → LAM Audio2Expression → ARKit blendshapes [52 floats/frame @ 30fps]
        → WebSocket to browser → gaussian-splat-renderer-for-lam (WebGL)
          → Canvas render
```

For your TTS→Avatar use case, the VAD/ASR/LLM modules are bypassed, and TTS audio feeds directly into Audio2Expression.

---

## 2. Audio2Expression Module (`aigc3d/LAM_Audio2Expression`)

**Key repo:** `https://github.com/aigc3d/LAM_Audio2Expression`

**Input format:** Raw NumPy float32 audio at **16 kHz mono**, fed in 1-second chunks (16,000 samples per call).

**Python callable API:**
```python
from engines.defaults import default_argument_parser, default_config_parser, default_setup
from engines.infer import INFER

cfg = default_config_parser('configs/lam_audio2exp_config_streaming.py', options)
cfg = default_setup(cfg)
infer = INFER.build(dict(type=cfg.infer.type, cfg=cfg))
infer.model.eval()

context = None
# For each 1-second audio chunk:
output, context = infer.infer_streaming_audio(audio_chunk_np, sample_rate=16000, context)
# output['expression'] → np.ndarray shape [N_frames, 52]  (30fps ARKit blendshapes)
```

**Streaming context structure:**
```python
context = {
    'is_initial_input': bool,
    'previous_audio': np.ndarray | None,
    'previous_expression': np.ndarray | None,
    'previous_volume': np.ndarray | None,
    'first_input_flag': bool
}
```

**Output:** `[N_frames, 52]` NumPy array. Each frame = 52 ARKit blendshape weights (0.0–1.0). The 52 names are the standard Apple ARKit face channels: `browDownLeft`, `browDownRight`, `browInnerUp`, `cheekPuff`, `eyeBlinkLeft`, `jawOpen`, `mouthSmileLeft`, `tongueOut`, etc.

**Required models:** `wav2vec2-base-960h` (audio encoder) + `LAM_audio2exp` weights (as `LAM_audio2exp.tar` — **note: as of early 2026 this tarball is not yet publicly released**, per open issue #91 in the LAM repo).

---

## 3. Browser Rendering: WebGL + WebSocket (not WebRTC for avatar frames)

**Key repo:** `https://github.com/aigc3d/LAM_WebRender`

The browser rendering is done via the NPM package `gaussian-splat-renderer-for-lam`. It is **WebGL-based Gaussian Splatting**, not video streaming. The avatar geometry (Gaussian Splat model) is loaded once as a ZIP file; only the expression data streams per frame.

**JavaScript API:**
```typescript
import * as GaussianSplats3D from "gaussian-splat-renderer-for-lam";

const renderer = await GaussianSplats3D.GaussianSplatRenderer.getInstance(
  divElement,          // HTMLDivElement canvas container
  "./avatar.zip",      // Pre-exported LAM avatar (GLB+Gaussian data)
  {
    getChatState: () => "Responding",  // "Idle"|"Listening"|"Thinking"|"Responding"
    getExpressionData: () => ({        // Called every frame; return dict of 52 blendshape name→value
      jawOpen: 0.4,
      mouthSmileLeft: 0.2,
      // ...all 52 ARKit channels
    }),
    backgroundColor: "0x000000",
    alpha: 0.0
  }
);
```

The renderer **polls `getExpressionData()` each animation frame** — there is no WebSocket push from server to renderer. This means your Python backend feeds blendshapes to a JS bridge (your own WebSocket), and the JS side passes them into `getExpressionData()` on each rAF tick.

**Avatar asset format:** A ZIP file containing the LAM-exported GLB (Gaussian Splat geometry baked from a source photo). Generated via `app_lam.py --blender_path /path/to/blender` with the "Export ZIP for Chatting Avatar" checkbox enabled. Requires Blender 4.0+ and the FBX SDK.

---

## 4. OpenAvatarChat WebRTC: for Audio I/O Only

**The WebRTC layer** (`gradio-webrtc`) is used *only for browser microphone audio input and TTS audio output back to the browser* — not for streaming avatar frames. The avatar render happens entirely in WebGL client-side. The LAM client handler is a **WebSocket** (`ws_lam_client_handler`) that delivers blendshape data from Python to the browser's JavaScript renderer.

---

## 5. LAM Core Model: Python-Importable Inference

The LAM 3D Gaussian model itself (`lam/models/modeling_lam.py`) is callable programmatically:

```python
from lam.runners.infer.lam import LAMInferrer

inferrer = LAMInferrer()
# Takes: source image + pre-computed FLAME params (from motion sequences)
# Returns: rendered RGB frames [Nv, H, W, 3]
```

**FLAME parameter keys** (`gs_renderer.py`):
- `expr`: [B, Nv, 100] — expression coefficients
- `betas`: [B, 100] — shape (constant per identity)
- `rotation`, `neck_pose`, `jaw_pose`, `eyes_pose`, `translation` — pose per frame
- `teeth_bs` (optional) — teeth blendshapes

However, for your use case you **do not need to call the LAM Gaussian renderer in Python at all** — the WebGL renderer does the rendering client-side from the pre-exported ZIP. The Python side only needs Audio2Expression.

---

## 6. Key Files to Study for Integration

| File | Repo | Purpose |
|---|---|---|
| `engines/infer.py` | `aigc3d/LAM_Audio2Expression` | `infer_streaming_audio()` — core callable API |
| `models/network.py` | `aigc3d/LAM_Audio2Expression` | `Audio2Expression` model (Wav2Vec2 → 52 blendshapes) |
| `models/utils.py` | `aigc3d/LAM_Audio2Expression` | `ARKitBlendShape` list + `export_blendshape_animation()` |
| `inference_streaming_audio.py` | `aigc3d/LAM_Audio2Expression` | Reference streaming usage |
| `src/gaussianAvatar.ts` | `aigc3d/LAM_WebRender` | JS renderer API and expression data protocol |
| `handlers/avatar/lam/avatar_handler_lam_audio2expression.py` | `HumanAIGC-Engineering/OpenAvatarChat` | How audio bytes → blendshapes → WebSocket works in production |
| `config/chat_with_lam.yaml` | `HumanAIGC-Engineering/OpenAvatarChat` | Full handler stack configuration |
| `app_lam.py` | `aigc3d/LAM` | Avatar export (ZIP) with Blender |

---

## 7. Integration Plan for Your Use Case

Your pipeline (TTS audio → animated avatar in browser canvas):

1. **Python backend**: Load `Audio2ExpressionInfer` once at startup. For each TTS response, convert audio to 16kHz numpy, call `infer_streaming_audio()` in 1-second chunks, buffer output blendshape frames.
2. **WebSocket**: Stream blendshape frames as JSON `{jawOpen: 0.4, eyeBlinkLeft: 0.1, ...}` to the browser at 30fps.
3. **Browser JS**: Load `gaussian-splat-renderer-for-lam` with the pre-exported avatar ZIP. Wire `getExpressionData()` to read from the WebSocket buffer. The renderer calls this each animation frame and deforms the Gaussian Splat mesh live in WebGL.

**Critical blocker to verify:** The `LAM_audio2exp` model weights (`LAM_audio2exp.tar`) appear to not be publicly available as of February 2026 (GitHub issue #91 in `aigc3d/LAM` is open and unanswered). You may need to contact the maintainers directly or monitor the repo for a release.