# AI Search

{% hint style="info" %}
**需要 AI Search 插件。** 此功能需要安裝並啟用 [AI Search](https://eagle.cool/support/article/ai-search) 插件。
{% endhint %}

***

## AI Search 插件簡介

「AI Search」是一款提供 AI 語意搜尋功能的插件，支援文字語意搜尋、以圖搜圖等智慧搜尋能力。透過整合此插件，開發者可以在自己的插件中輕鬆實現強大的 AI 搜尋功能。

### 主要功能

* **文字語意搜尋** - 使用自然語言描述，搜尋相關圖片
* **以圖搜圖** - 使用圖片搜尋相似的圖片
* **Item ID 搜尋** - 根據已有項目搜尋相似圖片

***

## 如何使用 AI Search

使用 `eagle.extraModule.aiSearch` 來呼叫 AI Search 插件提供的功能。

### 狀態查詢

在呼叫搜尋方法前，建議先檢查服務狀態：

```javascript
eagle.onPluginCreate(async (plugin) => {
    const aiSearch = eagle.extraModule.aiSearch;

    // 檢查插件是否已安裝
    const isInstalled = await aiSearch.isInstalled();
    console.log('已安裝:', isInstalled);

    // 檢查服務是否就緒
    const isReady = await aiSearch.isReady();
    console.log('服務就緒:', isReady);

    // 檢查是否正在啟動中
    const isStarting = await aiSearch.isStarting();
    console.log('啟動中:', isStarting);

    // 檢查是否正在同步資料
    const isSyncing = await aiSearch.isSyncing();
    console.log('同步中:', isSyncing);
});
```

### 服務控制

```javascript
eagle.onPluginCreate(async (plugin) => {
    const aiSearch = eagle.extraModule.aiSearch;

    // 開啟 AI Search 插件（若未安裝會提示安裝）
    await aiSearch.open();

    // 檢查服務健康狀態
    const isHealthy = await aiSearch.checkServiceHealth();
    console.log('服務健康:', isHealthy);

    // 取得同步狀態詳情
    const syncStatus = await aiSearch.getSyncStatus();
    console.log('同步狀態:', syncStatus);
});
```

***

## 搜尋方法

### searchByText(query, options) - 文字語意搜尋

使用自然語言描述搜尋相關圖片。

* `query` string - 搜尋關鍵字或描述
* `options` Object (可選) - 搜尋選項
  * `limit` number - 結果數量限制，預設 20
* 返回 `Promise<Object>` - 搜尋結果
  * `results` Array - 搜尋結果陣列
    * `item` Item - 完整的 Item 物件
    * `score` number - 相似度分數

```javascript
eagle.onPluginCreate(async (plugin) => {
    const aiSearch = eagle.extraModule.aiSearch;

    // 檢查服務是否就緒
    if (!await aiSearch.isReady()) {
        console.log('AI Search 服務尚未就緒');
        return;
    }

    // 文字語意搜尋
    const result = await aiSearch.searchByText('一隻橘色的貓咪', {
        limit: 10
    });

    // 走訪搜尋結果
    result.results.forEach(r => {
        console.log('相似度:', r.score);
        console.log('檔案名稱:', r.item.name);
        console.log('標籤:', r.item.tags);
    });
});
```

### searchByBase64(base64, options) - Base64 圖片搜尋

使用 Base64 編碼的圖片搜尋相似圖片。

* `base64` string - Base64 編碼的圖片字串
* `options` Object (可選) - 搜尋選項
  * `limit` number - 結果數量限制，預設 20
* 返回 `Promise<Object>` - 搜尋結果

```javascript
eagle.onPluginCreate(async (plugin) => {
    const aiSearch = eagle.extraModule.aiSearch;

    // 使用 Base64 圖片搜尋
    const base64Image = 'data:image/jpeg;base64,/9j/4AAQSkZJRg...';
    const result = await aiSearch.searchByBase64(base64Image, {
        limit: 20
    });

    console.log('找到', result.results.length, '個相似圖片');

    result.results.forEach(r => {
        console.log(`${r.item.name} - 相似度: ${(r.score * 100).toFixed(1)}%`);
    });
});
```

### searchByItemId(itemId, options) - 以現有項目搜尋

使用已存在的 Eagle 項目 ID 搜尋相似圖片。

* `itemId` string - Eagle 項目 ID
* `options` Object (可選) - 搜尋選項
  * `limit` number - 結果數量限制，預設 20
* 返回 `Promise<Object>` - 搜尋結果

```javascript
eagle.onPluginCreate(async (plugin) => {
    const aiSearch = eagle.extraModule.aiSearch;

    // 取得當前選中的項目
    const selectedItems = await eagle.item.get({ isSelected: true });

    if (selectedItems.length === 0) {
        console.log('請先選擇一個項目');
        return;
    }

    // 使用選中項目的 ID 搜尋相似圖片
    const result = await aiSearch.searchByItemId(selectedItems[0].id, {
        limit: 30
    });

    console.log('找到', result.results.length, '個相似圖片');

    // 結果中的 item 是完整的 Item 物件，可以直接使用其方法
    for (const r of result.results) {
        console.log(`${r.item.name} (${r.item.ext}) - 相似度: ${r.score}`);

        // 可以直接使用 Item 的方法
        // await r.item.save();
    }
});
```

***

## 完整範例

### 建立相似圖片搜尋功能

```javascript
eagle.onPluginCreate(async (plugin) => {
    const aiSearch = eagle.extraModule.aiSearch;

    // 1. 檢查服務狀態
    if (!await aiSearch.isInstalled()) {
        // 開啟安裝提示
        await aiSearch.open();
        return;
    }

    if (!await aiSearch.isReady()) {
        console.log('請等待 AI Search 服務啟動完成');
        return;
    }

    // 2. 執行搜尋
    try {
        const result = await aiSearch.searchByText('日落時的海灘風景');

        if (result.results.length === 0) {
            console.log('沒有找到相關圖片');
            return;
        }

        // 3. 處理搜尋結果
        const topResults = result.results
            .filter(r => r.score > 0.5)  // 只保留相似度 > 50% 的結果
            .slice(0, 10);               // 取前 10 個

        console.log(`找到 ${topResults.length} 個高相關度圖片：`);

        topResults.forEach((r, index) => {
            console.log(`${index + 1}. ${r.item.name}`);
            console.log(`   相似度: ${(r.score * 100).toFixed(1)}%`);
            console.log(`   尺寸: ${r.item.width} x ${r.item.height}`);
            console.log(`   標籤: ${r.item.tags.join(', ') || '無'}`);
        });

        // 4. 可以進一步操作這些項目
        // 例如：選中這些項目
        const itemIds = topResults.map(r => r.item.id);
        await eagle.item.select(itemIds);

    } catch (error) {
        console.error('搜尋失敗:', error.message);
    }
});
```

***

## API 參考

### 狀態查詢方法

| 方法              | 返回類型               | 說明                   |
| --------------- | ------------------ | -------------------- |
| `isInstalled()` | `Promise<boolean>` | 檢查 AI Search 插件是否已安裝 |
| `isReady()`     | `Promise<boolean>` | 檢查服務是否就緒可用           |
| `isStarting()`  | `Promise<boolean>` | 檢查服務是否正在啟動中          |
| `isSyncing()`   | `Promise<boolean>` | 檢查是否正在同步資料           |

### 服務控制方法

| 方法                     | 返回類型               | 說明              |
| ---------------------- | ------------------ | --------------- |
| `open()`               | `Promise<void>`    | 開啟 AI Search 插件 |
| `checkServiceHealth()` | `Promise<boolean>` | 檢查服務健康狀態        |
| `getSyncStatus()`      | `Promise<Object>`  | 取得詳細的同步狀態       |

### 搜尋方法

| 方法                                 | 返回類型              | 說明            |
| ---------------------------------- | ----------------- | ------------- |
| `searchByText(query, options?)`    | `Promise<Object>` | 文字語意搜尋        |
| `searchByBase64(base64, options?)` | `Promise<Object>` | Base64 圖片搜尋   |
| `searchByItemId(itemId, options?)` | `Promise<Object>` | 以項目 ID 搜尋相似圖片 |

### 搜尋結果格式

```javascript
{
    // ... 其他欄位
    results: [
        {
            item: Item,    // 完整的 Item 物件，包含所有屬性和方法
            score: number  // 相似度分數 (0-1)
        },
        // ...
    ]
}
```

{% hint style="info" %}
**提示**：搜尋結果中的 `item` 是完整的 Item 物件實例，可以直接使用 `save()`、`refreshThumbnail()` 等所有 Item 方法。
{% endhint %}
