Để tích hợp **AI Panel** điều khiển dự án DAW (Digital Audio Workstation) của bạn dựa trên yêu cầu từ Prompt, hệ thống cần được thiết kế theo kiến trúc **Copilot Agent / Command Orchestrator**.

Thay vì để AI can thiệp trực tiếp vào dữ liệu dự án, AI sẽ đóng vai trò **Bộ não điều hướng (Brain)**: Nhận nhận ngôn ngữ tự nhiên từ Prompt $\rightarrow$ Dịch ra định dạng lệnh chuẩn dạng JSON/Function Call $\rightarrow$ Gửi về cho **DAW Core Engine** thực thi.

Dưới đây là thiết kế kiến trúc, kỹ thuật và thuật toán chi tiết cho hệ thống này.

---

## 1. Kiến trúc Tổng thể (System Architecture)

Hệ thống nên chia làm 4 lớp (Layers) rõ ràng:

```text
[ User Interface (AI Panel) ]
            │ (User Prompt + Current App Context)
            ▼
[ LLM Gateway & Function Routing ] 
            │ (JSON Intent / Function Calling)
            ▼
[ DAW Command Manager / State Engine ] ──► [ Local Python DSP Server ] (Xử lý âm thanh/DSP nặng)
            │ (Mutation Protocol)
            ▼
[ Frontend State Engine (JS/Canvas) ] (Cập nhật UI & MIDI Viewport)

```

### A. AI Panel UI & Model Gateway

* **UI Controls:** Nơi nhập Prompt, nút chọn Provider (OpenAI, Anthropic, Gemini, Local Ollama) & Model (GPT-4o, Claude Sonnet, Llama 3, v.v.).
* **Context Aggregator:** Thu thập **Trạng thái hiện tại của DAW (State)** truyền kèm vào Prompt để AI "hiểu" ngữ cảnh (VD: track nào đang chọn, Tempo bao nhiêu, đang chọn khoảng thời gian nào).

### B. Command Manager & State Engine (Bộ điều khiển chính)

* Không cho LLM viết trực tiếp vào State của DAW. LLM chỉ trả về một danh sách các **Action Descriptor (Lệnh hành động)**.
* **Command Pattern & Undo/Redo Engine:** Mọi hành động AI trả về đều đi qua Dispatcher để có thể `Undo` (`Ctrl + Z`) dễ dàng.

---

## 2. Kỹ thuật "Function Calling / Structured Outputs" (Cốt lõi)

Để AI trả về chính xác lệnh điều khiển hệ thống mà không nói "lan man", bạn áp dụng kỹ thuật **Function Calling / Schema Enforcement**.

### Định nghĩa các Tool / Command Protocol cho AI:

Bạn sẽ định nghĩa danh sách API dưới dạng **JSON Schema** cho AI:

```json
{
  "tools": [
    {
      "name": "create_track",
      "description": "Tạo một track mới trong dự án",
      "parameters": {
        "type": "object",
        "properties": {
          "name": { "type": "string" },
          "type": { "type": "string", "enum": ["audio", "midi"] }
        },
        "required": ["name", "type"]
      }
    },
    {
      "name": "add_midi_item",
      "description": "Thêm một MIDI item/clip vào track",
      "parameters": {
        "type": "object",
        "properties": {
          "track_id": { "type": "string" },
          "start_bar": { "type": "number" },
          "length_bars": { "type": "number" }
        },
        "required": ["track_id", "start_bar", "length_bars"]
      }
    },
    {
      "name": "modify_midi_notes",
      "description": "Thêm, chỉnh sửa hoặc xóa các note MIDI trong item",
      "parameters": {
        "type": "object",
        "properties": {
          "item_id": { "type": "string" },
          "notes": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "pitch": { "type": "string", "description": "VD: C4, D#3, F5" },
                "start_time": { "type": "number", "description": "Tính bằng Bar hoặc Giây" },
                "duration": { "type": "number" },
                "velocity": { "type": "integer", "minimum": 0, "maximum": 127 }
              }
            }
          }
        },
        "required": ["item_id", "notes"]
      }
    },
    {
      "name": "process_audio_dsp",
      "description": "Gửi yêu cầu chỉnh sửa âm thanh sang Python DSP Backend",
      "parameters": {
        "type": "object",
        "properties": {
          "track_id": { "type": "string" },
          "action": { "type": "string", "enum": ["normalize", "invert_phase", "gain", "pitch_shift"] },
          "params": { "type": "object" }
        }
      }
    }
  ]
}

```

---

## 3. Thuật toán Context Injection (Bơm ngữ cảnh DAW vào Prompt)

AI không thể sửa MIDI hay tạo Track chính xác nếu không biết trạng thái hiện tại. Do đó, trước khi gửi prompt của người dùng lên LLM, hệ thống phải chạy **Thuật toán đóng gói Context**:

### Thuật toán đóng gói Context:

```javascript
function buildAIPromptContext(userPrompt) {
  const currentState = {
    tempo: dawState.bpm,
    timeSignature: dawState.timeSignature,
    selectedTrackId: dawState.activeTrackId,
    selectedItemId: dawState.activeItemId,
    playheadPosition: dawState.playheadTime,
    tracks: dawState.tracks.map(t => ({
      id: t.id,
      name: t.name,
      type: t.type,
      itemsCount: t.items.length
    }))
  };

  return {
    system_instruction: "Bạn là trợ lý AI cho DAW. Hãy phân tích yêu cầu người dùng và phản hồi BẰNG DẠNG FUNCTION CALLS phù hợp với Context dự án.",
    daw_context: currentState,
    user_prompt: userPrompt
  };
}

```

### Ví dụ xử lý kịch bản thực tế:

* **User Prompt:** *"Thêm một hợp âm C Major (Đô trưởng) vào đầu track 2 dạng MIDI item dài 2 bar"*
* **LLM nhận Prompt + Context** $\rightarrow$ **AI trả về JSON:**
```json
[
  {
    "function": "add_midi_item",
    "args": { "track_id": "track_02", "start_bar": 1, "length_bars": 2 }
  },
  {
    "function": "modify_midi_notes",
    "args": {
      "item_id": "new_created_item_id",
      "notes": [
        { "pitch": "C4", "start_time": 0, "duration": 2, "velocity": 100 },
        { "pitch": "E4", "start_time": 0, "duration": 2, "velocity": 100 },
        { "pitch": "G4", "start_time": 0, "duration": 2, "velocity": 100 }
      ]
    }
  }
]

```



---

## 4. Phân chia xử lý giữa Backend (Python) và Frontend (JS)

Vì dự án của bạn là **Hybrid (HTML5/JS Frontend + Python Server)**, luồng công việc sẽ phân chia như sau:

| Thao tác | Đơn vị xử lý | Mô tả thuật toán / Kỹ thuật |
| --- | --- | --- |
| **1. Chỉnh sửa MIDI (Thêm/Sửa note, Item)** | **Frontend (JS)** | Sửa mảng JSON chứa dữ liệu MIDI trên JS State $\rightarrow$ Gọi hàm `requestAnimationFrame()` để render lại Piano Roll / Canvas. **Không cần gửi về Python** để tối ưu tốc độ realtime. |
| **2. Chỉnh sửa Audio (DSP, Pitch Shift, Cut/Norm)** | **Backend (Python)** | JS gửi request kèm file path/audio buffer sang Python. Python dùng `librosa` / `pydub` / `scipy` thực hiện tính toán DSP $\rightarrow$ Trả về file WAV mới hoặc Array Buffer mới cho Frontend render lại Waveform. |
| **3. Tạo nhạc tự động (Music Generation)** | **Backend (Python)** | Nếu Prompt yêu cầu *"Tạo 1 đoạn Beat Lofi 8 bar"*, Python gọi các model AI chuyên biệt local (như **MusicGen**, **AudioLDM**) để tạo ra file Audio / File MIDI thực tế $\rightarrow$ Trả về Frontend. |

---

## 5. UI/UX cho phần AI Panel (Dựa trên Ảnh Mockup)

Để UI ở phần dưới hiển thị tốt như hình bạn đính kèm:

1. **Nút bấm Chọn Provider & Model:**
* Mở Menu Popup (Popover) cho phép chọn:
* **Provider:** OpenAI, Anthropic, Google Gemini, Ollama (Local).
* **Model:** GPT-4o, Claude 3.5 Sonnet, Llama 3.
* **API Key input** (lưu ở `localStorage`).




2. **Luồng chỉ báo phản hồi (Visual Feedback):**
* Khi AI đang suy luận: Hiện trạng thái `AI đang phân tích lệnh...`.
* Khi AI thực thi xong: Hiển thị danh sách các hành động đã làm, ví dụ:
* `[v] Đã tạo Track 3 (MIDI)`
* `[v] Đã thêm 4 MIDI Notes (C4, E4, G4, B4)`


* Nút **Undo** nhanh ngay trên AI Panel nếu AI thực hiện chưa đúng ý.



---

## 6. Lộ trình triển khai khuyến nghị

1. **Bước 1 (Protocol):** Viết lớp `DAWCommandDispatcher` ở Frontend JS để có thể gọi các hàm dạng `Dispatcher.execute('CREATE_TRACK', payload)` trước.
2. **Bước 2 (LLM Integration):** Tích hợp SDK API (OpenAI/Gemini/Claude) vào JS/Python, cấu hình `tools` (Function Calling).
3. **Bước 3 (Context Injection):** Viết hàm xuất cấu trúc `dawState` hiện tại ra JSON ngắn gọn để làm Context cho Prompt.
4. **Bước 4 (MIDI & Audio Execution):** Map kết quả Function Calling từ AI trả về vào `DAWCommandDispatcher` để cập nhật UI & gửi lệnh DSP qua Python.