# AI SDK

{% hint style="warning" %}
注意：この機能は Eagle 4.0 Build20 以上のバージョンで利用可能です（現在未リリース、詳細なリリース日程は Eagle 公式サイトをご確認ください）
{% endhint %}

***

## AI SDK 依存プラグインの概要 <a href="#introduction" id="introduction"></a>

<figure><img src="https://1611209449-files.gitbook.io/~/files/v0/b/gitbook-x-prod.appspot.com/o/spaces%2FMvbOurypjZWfptd5H280%2Fuploads%2FFtxs1DQRfG7P490Z0z3J%2Fimage.png?alt=media&#x26;token=0395ae72-1d33-4289-a4b7-dd8e3176da10" alt=""><figcaption></figcaption></figure>

「AI SDK 依存プラグイン」はプラグイン開発者向けの開発ツールキットであり、統一された AI モデル設定センターを提供します。主要な AI モデルをサポートし、一度設定すればどこでも利用可能です。AI SDK を統合することで、開発者は自身のプラグインにテキスト生成、構造化オブジェクト生成、ストリーミング処理などの AI 機能を簡単に実装できます。

### 統一設定センター：一度の設定でどこでも利用可能

AI SDK プラグインは以下の 8 つの Provider をサポートしています：

**商用モデル**：

* OpenAI（GPT-5.2、GPT-5、o3 など）
* Anthropic Claude（Claude Sonnet 4.6、Claude Opus 4.6 など）
* Google Gemini（Gemini 3 Pro、Gemini 3 Flash など）
* DeepSeek（DeepSeek V3、DeepSeek R1 など）
* Tongyi Qwen (通義千問)（Qwen3 シリーズ）

**ローカルモデル**（完全オフライン実行）：

* Ollama（Llama 4、Qwen3、Gemma 3 などをサポート）
* LM Studio（GUI 搭載、初心者にも使いやすい）

**OpenAI 互換プロトコル**：

* OpenAI Compatible — OpenAI API プロトコルに互換性のある任意のサービスエンドポイント（Groq、Together AI、Fireworks、vLLM など）に接続可能です。Base URL を入力するだけで利用でき、API Key は任意です。

今後のバージョンでさらに多くの主要モデルサービスプロバイダーのサポートを順次追加する予定です。

一度設定すれば、すべての AI 関連プラグインがそのまま利用でき、重複した設定は不要です。例えば、「AI 翻訳」と「AI リネーム」プラグインをインストールした場合、どちらも AI SDK で設定した内容を自動的に共有し、それぞれ異なるモデルを選択することもできます。API Key を再入力する必要はありません。

### オープンな開発環境

[ai-sdk.dev](https://ai-sdk.dev/) 標準（AI SDK v6）に基づき、AI SDK プラグインは開発者にクリーンで安定した基盤を提供します。開発者は API Key の保存、モデルの切り替え、エラー処理などの基本設定に手間をかける必要がなく、プラグインの機能革新に集中できます。唯一の違いは Provider の取得方法です——より良い安定性とユーザー体験を確保するため、独自開発の Provider を使用しています。

{% hint style="info" %}
**バージョン説明**：このプラグインは AI SDK v6 をベースに構築されており、[ai-sdk.dev](https://ai-sdk.dev/) の公式ドキュメントと同期しています。
{% endhint %}

***

## インストールと設定 <a href="#installation" id="installation"></a>

### インストール手順

1. Eagle プラグインセンターを開きます
2. 「AI SDK」プラグインを検索します
3. インストールをクリックします
4. インストール完了後、**環境設定**を開き、左側のサイドバーで「**AI モデル**」を見つけます
5. 右側の設定エリアでモデルサービスプロバイダーを設定し、**デフォルトモデル**（言語モデル、ビジョンモデル）を設定します

{% hint style="info" %}
ユーザーが AI SDK 依存のプラグインをインストールすると、Eagle は自動的に「AI SDK 依存プラグイン」のインストールを促します。そのため、開発者がインストール用のコードを別途記述する必要はなく、システムが関連する依存関係がインストールされていることを自動的に確認してからプラグインの実行を許可します。
{% endhint %}

### manifest.json で依存関係を宣言する

プラグインの `manifest.json` に `dependencies` フィールドを追加します：

```json
{
    "id": "YOUR_PLUGIN_ID",
    "version": "1.0.0",
    "platform": "all",
    "arch": "all",
    "name": "マイ AI プラグイン",
    "logo": "/logo.png",
    "keywords": [],
    "dependencies": ["ai-sdk"],
    "devTools": false,
    "main": {
        "url": "index.html",
        "width": 640,
        "height": 480
    }
}
```

重要な設定は `"dependencies": ["ai-sdk"]` です。これにより Eagle はこのプラグインが AI SDK を必要とすることを認識します。

***

## クイックスタート <a href="#quickstart" id="quickstart"></a>

AI SDK モジュールの取得：

```javascript
const ai = eagle.extraModule.ai;
```

### 推奨方法：デフォルトモデルを使用する

ユーザーは通常、環境設定の「AI モデル」で、好みの言語モデルとビジョンモデルを事前に選択しています。`getDefaultModel()` でユーザーの選択をそのまま継承するのが、最もシンプルで推奨される方法です：

```javascript
eagle.onPluginCreate(async (plugin) => {
    const ai = eagle.extraModule.ai;
    const { generateText } = ai;

    // ユーザーが設定したデフォルト言語モデルを取得（同期、await 不要）
    // getDefaultModel("image") でユーザーのデフォルトビジョンモデルも取得可能
    const defaultLLM = ai.getDefaultModel("chat");

    if (!defaultLLM) {
        console.log("AI SDK の設定でデフォルト言語モデルを選択してください");
        ai.open(); // 環境設定のモデル設定パネルを自動的に開く
        return;
    }

    // provider::model 文字列でモデルを直接取得
    const model = ai.getModel(defaultLLM);

    // テキスト生成
    const result = await generateText({
        model,
        prompt: "デジタルアートについて一言で紹介してください",
    });

    console.log(result.text);
});
```

{% hint style="success" %}
**🦄 ベストプラクティス：** コード内に特定の Provider やモデル名をハードコーディングするのではなく、`getDefaultModel("chat")` でユーザーの好みのモデルを優先的に取得してください。これには 2 つの大きな利点があります：

1. **開発が楽になる**——モデルセレクターを自分で実装する必要がなく、AI SDK でのユーザーの設定をそのまま継承できます。
2. **設定の問題を回避**——コード内で `openai("gpt-5")` を指定しても、ユーザーが OpenAI を設定していなければエラーになります。デフォルトモデルを使用すれば、ユーザーが既に設定・検証済みであることが保証されます。
   {% endhint %}

### 特定の Provider を指定する

プラグインが特定の Provider を必要とする場合（例：OpenAI のみがサポートする機能）、直接指定することもできます：

```javascript
eagle.onPluginCreate(async (plugin) => {
    const ai = eagle.extraModule.ai;
    const { generateText } = ai;

    // 特定の Provider を取得（同期、await 不要）
    const openai = ai.getProvider("openai");

    const result = await generateText({
        model: openai("gpt-5"),
        prompt: "デジタルアートについて一言で紹介してください",
    });

    console.log(result.text);
});
```

***

## コアコンセプト <a href="#core-concepts" id="core-concepts"></a>

### Provider と Model の関係

AI SDK は二層構造を採用しています：**Provider**（プロバイダー）は API 接続と認証を管理し、**Model**（モデル）は実際に AI タスクを実行する単位です。

```
Provider（例：openai）
  └── Model（例：gpt-5）
  └── Model（例：gpt-5.2）
```

### provider::model 形式

{% hint style="danger" %}
**重要：** Provider と Model の間は**ダブルコロン** `::` で区切ります。シングルコロンやスラッシュではありません。
{% endhint %}

```javascript
// ✅ 正しい
"openai::gpt-5"
"anthropic::claude-sonnet-4-6-20250514"
"google::gemini-3-flash"

// ❌ 誤り
"openai/gpt-5"
"openai:gpt-5"
```

この形式は `getModel()` や `getDefaultModel()` などのメソッドで使用されます。

### 同期 vs 非同期メソッド

AI SDK のメソッドは同期と非同期に明確に分類されています：

**同期メソッド**（`await` 不要）：

* `getProviders()`、`getProvider()`、`getAvailableProviders()`、`getModel()`
* `getDefaultModel()`

**非同期メソッド**（`await` が必要）：

* `generateText()`、`generateObject()`、`streamText()`、`streamObject()`
* Provider インスタンスの `verify()`、`getModels()`、`hasModel()`

### Model を取得する 3 つの方法

```javascript
const ai = eagle.extraModule.ai;

// ⭐ 推奨：デフォルトモデルを使用し、ユーザーの好みをそのまま継承
const defaultLLM = ai.getModel(ai.getDefaultModel("chat"));   // デフォルト言語モデル
const defaultVLM = ai.getModel(ai.getDefaultModel("image"));  // デフォルトビジョンモデル

// 方法 2：provider::model 形式で直接取得
const model = ai.getModel("openai::gpt-5");

// 方法 3：先に Provider を取得し、次に Model を指定
const openai = ai.getProvider("openai");
const model = openai("gpt-5");
```

{% hint style="success" %}
**🦄 ベストプラクティス：** プラグインに特別な要件（例：特定の Provider のみがサポートする機能）がない限り、`getDefaultModel()` でユーザーの好みのモデルを優先的に使用してください。
{% endhint %}

***

## generateText() — 基本テキスト生成 <a href="#generate-text" id="generate-text"></a>

指定したモデルを使用してテキスト応答を生成します。

### 基本的な使い方（prompt）

```javascript
const ai = eagle.extraModule.ai;
const { generateText } = ai;

// デフォルト言語モデルを使用
const model = ai.getModel(ai.getDefaultModel("chat"));

const result = await generateText({
    model,
    prompt: "デジタルアートに関するクリエイティブな紹介文を書いてください",
});

console.log(result.text);
```

### messages 配列の使用

`messages` を使用してシステムプロンプトとマルチターン会話を設定できます：

```javascript
const model = ai.getModel(ai.getDefaultModel("chat"));

const result = await generateText({
    model,
    messages: [
        {
            role: "system",
            content: "あなたはプロのアート評論家です。",
        },
        {
            role: "user",
            content: "印象派の色彩表現の特徴を分析してください。",
        },
    ],
});

console.log(result.text);
```

### マルチモーダル（テキスト + 画像）

```javascript
// デフォルトビジョンモデルを使用（画像理解をサポート）
const model = ai.getModel(ai.getDefaultModel("image"));

const result = await generateText({
    model,
    messages: [
        {
            role: "user",
            content: [
                {
                    type: "text",
                    text: "この画像の内容を説明してください",
                },
                {
                    type: "image",
                    image: "https://example.com/sample-image.jpg",
                },
            ],
        },
    ],
});

console.log(result.text);
```

{% hint style="info" %}
`generateText` の高度な使い方（`maxTokens`、`temperature` などのパラメータ）については、[AI SDK 公式ドキュメント](https://ai-sdk.dev/docs/ai-sdk-core/generating-text)を参照してください。
{% endhint %}

***

## generateObject() — 構造化オブジェクト生成 <a href="#generate-object" id="generate-object"></a>

指定した Schema に従って AI に構造化 JSON オブジェクトを返させます。

### Zod Schema の使用

```javascript
const ai = eagle.extraModule.ai;
const { generateObject } = ai;
const { z } = require("zod");

// テキストのみのタスクにはデフォルト言語モデルを使用
const model = ai.getModel(ai.getDefaultModel("chat"));

const result = await generateObject({
    model,
    schema: z.object({
        tags: z.array(z.object({
            name: z.string(),
            reason: z.string(),
        })),
        description: z.string(),
    }),
    prompt: "夕焼けのビーチ写真に 5 つのタグと説明を生成してください",
});

console.log(result.object.tags);
console.log(result.object.description);
```

### JSON Schema の使用

```javascript
const model = ai.getModel(ai.getDefaultModel("chat"));

const result = await generateObject({
    model,
    schema: {
        type: "object",
        properties: {
            tags: {
                type: "array",
                items: {
                    type: "object",
                    properties: {
                        name: { type: "string" },
                        reason: { type: "string" },
                    },
                },
            },
            description: { type: "string" },
        },
    },
    prompt: "夕焼けのビーチ写真に 5 つのタグと説明を生成してください",
});

console.log(result.object.tags);
console.log(result.object.description);
```

### 画像分析の例

```javascript
// 画像理解を伴うため、デフォルトビジョンモデルを使用
const model = ai.getModel(ai.getDefaultModel("image"));

const result = await generateObject({
    model,
    schema: {
        type: "object",
        properties: {
            colors: { type: "array", items: { type: "string" } },
            style: { type: "string" },
            mood: { type: "string" },
        },
    },
    messages: [
        {
            role: "system",
            content: "あなたはプロの画像分析エキスパートです。",
        },
        {
            role: "user",
            content: [
                { type: "text", text: "この画像の色彩、スタイル、感情を分析してください。" },
                { type: "image", image: "https://example.com/artwork.jpg" },
            ],
        },
    ],
});

console.log(result.object);
```

{% hint style="info" %}
`generateObject` の高度な使い方については、[AI SDK 公式ドキュメント](https://ai-sdk.dev/docs/ai-sdk-core/generating-structured-data)を参照してください。
{% endhint %}

***

## streamText() — ストリーミングテキスト生成 <a href="#stream-text" id="stream-text"></a>

ストリーミング方式で AI の応答を段階的に受信します。リアルタイムで結果を表示する必要がある場面に適しています。

```javascript
const ai = eagle.extraModule.ai;
const { streamText } = ai;
const model = ai.getModel(ai.getDefaultModel("chat"));

const { textStream } = streamText({
    model,
    prompt: "デジタルアートの発展の歴史を詳しく紹介してください",
});

// 非同期イテレータでテキストを段階的に受信
for await (const textPart of textStream) {
    console.log(textPart); // リアルタイム表示
}
```

### UI にリアルタイム表示する

```javascript
let fullText = "";

const { textStream } = streamText({
    model,
    prompt: "短いエッセイを書いてください",
});

for await (const textPart of textStream) {
    fullText += textPart;
    // UI 要素を更新
    document.getElementById("output").textContent = fullText;
}
```

{% hint style="info" %}
`streamText` の高度な使い方については、[AI SDK 公式ドキュメント](https://ai-sdk.dev/docs/ai-sdk-core/generating-text#streamtext)を参照してください。
{% endhint %}

***

## streamObject() — ストリーミングオブジェクト生成 <a href="#stream-object" id="stream-object"></a>

ストリーミング方式で構造化オブジェクトを段階的に受信します。各イテレーションで現時点までに解析された部分オブジェクトを受け取ります。

```javascript
const ai = eagle.extraModule.ai;
const { streamObject } = ai;
const model = ai.getModel(ai.getDefaultModel("chat"));

const { partialObjectStream } = streamObject({
    model,
    schema: {
        type: "object",
        properties: {
            analysis: {
                type: "object",
                properties: {
                    colors: { type: "array", items: { type: "string" } },
                    style: { type: "string" },
                    mood: { type: "string" },
                    suggestions: { type: "array", items: { type: "string" } },
                },
            },
        },
    },
    prompt: "このアート作品の色彩、スタイル、感情を分析し、改善提案を提供してください。",
});

for await (const partialObject of partialObjectStream) {
    console.log("現在の結果:", partialObject);
    // partialObject は段階的にフィールドが追加されます。例：
    // { analysis: { colors: ["赤"] } }
    // { analysis: { colors: ["赤", "青"], style: "印象派" } }
    // { analysis: { colors: ["赤", "青"], style: "印象派", mood: "静寂" } }
}
```

{% hint style="success" %}
**🦄 ベストプラクティス：** `streamObject` は UI 上で分析結果を段階的に表示する場面に適しており、AI の処理が完了する前からユーザーに部分的な結果を表示できます。
{% endhint %}

{% hint style="info" %}
`streamObject` の高度な使い方については、[AI SDK 公式ドキュメント](https://ai-sdk.dev/docs/ai-sdk-core/generating-structured-data#streamobject)を参照してください。
{% endhint %}

***

## Provider 管理メソッド <a href="#provider-management" id="provider-management"></a>

以下のメソッドはすべて**同期メソッド**であり、`await` は不要です。

***

### getProviders() <a href="#get-providers" id="get-providers"></a>

登録済みのすべての Provider の配列を取得します。

* 戻り値 `ProviderFunction[]` — すべての Provider の配列

```javascript
const ai = eagle.extraModule.ai;

// ✅ 正しい：配列を返す
const providers = ai.getProviders();
console.log(providers.length); // 8

providers.forEach(provider => {
    console.log(provider.name); // "openai", "anthropic", "google", ...
});
```

{% hint style="danger" %}
**注意：** `getProviders()` が返すのは**配列**であり、オブジェクトではありません。以下の書き方は誤りです：

```javascript
// ❌ 誤り：オブジェクトとして分割代入できない
const { openai, anthropic } = ai.getProviders();

// ❌ 誤り：await は不要
const providers = await ai.getProviders();
```

{% endhint %}

***

### getProvider(providerName) <a href="#get-provider" id="get-provider"></a>

指定した名前の Provider を取得します。

* `providerName` string — Provider 名（例：`"openai"`、`"google"`）
* 戻り値 `ProviderFunction | undefined` — 見つかった Provider。存在しない場合は `undefined` を返します

```javascript
const openai = ai.getProvider("openai");
const google = ai.getProvider("google");

if (openai) {
    const model = openai("gpt-5");
}
```

{% hint style="info" %}
特定の Provider を取得する場合、`getProviders()` よりも `getProvider()` を使用する方がコードが簡潔になります。ただし、ほとんどの場合は `getDefaultModel()` を直接使用するのがより良い選択です。
{% endhint %}

***

### getAvailableProviders() <a href="#get-available-providers" id="get-available-providers"></a>

設定済み（ユーザーが設定を完了した）すべての Provider を取得します。

* 戻り値 `ProviderFunction[]` — 設定済みの Provider の配列

```javascript
const available = ai.getAvailableProviders();

if (available.length === 0) {
    console.log("AI プロバイダーがまだ設定されていません。AI SDK の設定で設定してください。");
} else {
    console.log(`${available.length} 個のプロバイダーが設定済み：`);
    available.forEach(p => console.log(`- ${p.name}`));
}
```

{% hint style="info" %}
このメソッドと `getProviders()` の違い：`getProviders()` はすべての 8 つの Provider（未設定を含む）を返しますが、`getAvailableProviders()` はユーザーが設定を完了した Provider のみを返します。
{% endhint %}

***

### getModel(providerAndModel) <a href="#get-model" id="get-model"></a>

`provider::model` 形式でモデルインスタンスを直接取得します。

* `providerAndModel` string — `"provider::model"` 形式
* 戻り値 `Model` — `generateText()` などのメソッドに直接渡せるモデルオブジェクト

```javascript
// モデルを直接取得
const model = ai.getModel("openai::gpt-5");

const result = await generateText({
    model: model,
    prompt: "Hello!",
});
```

{% hint style="danger" %}
**注意：** Provider と Model 名の区切りには必ず `::` ダブルコロンを使用してください。そうしないとエラーがスローされます。
{% endhint %}

***

## 設定とリロード <a href="#settings" id="settings"></a>

***

### open() <a href="#open" id="open"></a>

環境設定の「AI モデル」設定パネルを開きます。プラグインインターフェースに「モデル設定」ボタンを設置し、ユーザーがモデルサービスプロバイダーとデフォルトモデルを素早く設定できるようにするのに適しています。

* 戻り値 `void`

```javascript
const ai = eagle.extraModule.ai;

// 例：プラグインインターフェースに「モデル設定」ボタンを配置
document.getElementById("settings-btn").addEventListener("click", () => {
    ai.open(); // システムが自動的に環境設定のモデル設定エリアを表示
});
```

{% hint style="success" %}
**🦄 ベストプラクティス：** `getDefaultModel()` が `undefined` を返す場合（ユーザーがまだデフォルトモデルを設定していない場合）、プラグインインターフェースにメッセージを表示し、`open()` を呼び出すボタンを提供して、ユーザーを設定完了に導いてください。
{% endhint %}

***

### reload() <a href="#reload" id="reload"></a>

AI SDK の設定をリロードします。ユーザーが `open()` で設定パネルを開いて設定を変更した後、このメソッドを呼び出すことで最新の設定を読み取れます。

* 戻り値 `void`

```javascript
const ai = eagle.extraModule.ai;

// ユーザーを設定に導いた後、設定をリロード
ai.open();

// ユーザーが設定を完了した後、リロードして最新の設定を取得
ai.reload();

const defaultLLM = ai.getDefaultModel("chat"); // ユーザーが設定したばかりのモデルを取得
```

{% hint style="info" %}
`open()` はプログラムの実行をブロックしないため、ユーザーが設定を完了するタイミングをシステムは把握できません。モデルを使用する必要がある時に `reload()` を呼び出して、最新の設定を確実に読み取ることを推奨します。
{% endhint %}

***

## デフォルトモデルメソッド <a href="#default-model" id="default-model"></a>

AI SDK はデフォルトモデルの設定と読み取りをサポートしており、ユーザーは環境設定の「AI モデル」で好みのモデルを統一的に指定できます。

***

### getDefaultModel(type) <a href="#get-default-model" id="get-default-model"></a>

指定した型のデフォルトモデルを取得します。これは**同期メソッド**です。

* `type` string — モデルの型。選択可能な値：`"chat"`（言語モデル）または `"image"`（ビジョンモデル）
* 戻り値 `string | undefined` — デフォルトモデルの `"provider::model"` 文字列。未設定の場合は `undefined` を返します

```javascript
// ユーザーのデフォルト言語モデルを取得
const defaultLLM = ai.getDefaultModel("chat");

if (defaultLLM) {
    console.log(`デフォルト言語モデル：${defaultLLM}`); // "openai::gpt-5"
    const model = ai.getModel(defaultLLM);
    const result = await generateText({ model, prompt: "Hello!" });
}

// ユーザーのデフォルトビジョンモデルを取得
const defaultVLM = ai.getDefaultModel("image");

if (defaultVLM) {
    console.log(`デフォルトビジョンモデル：${defaultVLM}`); // "openai::dall-e-3"
}
```

{% hint style="info" %}
ユーザーは環境設定の「AI モデル」で**言語モデル**（`"chat"`）と**ビジョンモデル**（`"image"`）をそれぞれ選択でき、プラグインは必要に応じてそれぞれを取得できます。
{% endhint %}

***

## Provider インスタンスメソッド <a href="#provider-instance-methods" id="provider-instance-methods"></a>

`getProvider()` で取得した Provider インスタンスは、関数として呼び出して Model を取得できるほか、以下のメソッドも提供しています。

***

### verify() <a href="#verify" id="verify"></a>

Provider の接続と認証が有効かどうかを検証します。ユーザーの現在の設定で正常に接続できるかを確認するために使用します。

* 戻り値 `Promise<VerifyResult>` — 検証結果オブジェクト
  * `ok` boolean — 検証が成功したかどうか
  * `error` APIError（オプション） — 失敗時のエラー詳細

```javascript
const openai = ai.getProvider("openai");

const result = await openai.verify();

if (result.ok) {
    console.log("接続成功！");
} else {
    console.error("接続失敗：", result.error.message);
    console.error("HTTP ステータスコード：", result.error.status);
}
```

{% hint style="danger" %}
**注意：** `verify()` が返すのは `boolean` ではなく、`ok` と `error` を含むオブジェクトです。

```javascript
// ❌ 誤り
const isValid = await openai.verify();
if (isValid) { ... }

// ✅ 正しい
const result = await openai.verify();
if (result.ok) { ... }
```

{% endhint %}

***

### getModels() <a href="#get-models" id="get-models"></a>

この Provider で利用可能なすべてのモデルリストを取得します。

* 戻り値 `Promise<string[]>` — モデル ID の配列

```javascript
const openai = ai.getProvider("openai");
const models = await openai.getModels();

console.log(models);
// ["gpt-5.2", "gpt-5", "o3", ...]
```

{% hint style="info" %}
このメソッドは Provider の API にリクエストを送信します。ユーザーが該当 Provider の設定を完了していることを確認してください。未設定の場合は `APIError` がスローされます。
{% endhint %}

***

### hasModel(modelId) <a href="#has-model" id="has-model"></a>

この Provider に指定したモデルが含まれているかを確認します。

* `modelId` string — モデル ID（例：`"gpt-5"`）
* 戻り値 `Promise<boolean>` — 存在するかどうか

```javascript
const openai = ai.getProvider("openai");
const exists = await openai.hasModel("gpt-5");

if (exists) {
    console.log("このモデルは利用可能です");
}
```

***

## Provider インスタンスプロパティ <a href="#provider-instance-properties" id="provider-instance-properties"></a>

以下は Provider インスタンスの読み取り専用プロパティです：

***

### `name` string

Provider の名前です。

```javascript
const openai = ai.getProvider("openai");
console.log(openai.name); // "openai"
```

***

### `baseURL` string | undefined

現在設定されている API エンドポイントです。

```javascript
const openai = ai.getProvider("openai");
console.log(openai.baseURL); // "https://api.openai.com" または undefined
```

***

## サポート対象 Provider 一覧 <a href="#supported-providers" id="supported-providers"></a>

| Provider           | 名前                    | 種類            | デフォルト Base URL                                      |
| ------------------ | --------------------- | ------------- | --------------------------------------------------- |
| OpenAI             | `"openai"`            | 商用（クラウド）      | 手動設定が必要                                             |
| Anthropic          | `"anthropic"`         | 商用（クラウド）      | 手動設定が必要                                             |
| Google Gemini      | `"google"`            | 商用（クラウド）      | 手動設定が必要                                             |
| DeepSeek           | `"deepseek"`          | 商用（クラウド）      | 手動設定が必要                                             |
| Tongyi Qwen (通義千問) | `"tongyi"`            | 商用（クラウド）      | `https://dashscope.aliyuncs.com/compatible-mode/v1` |
| Ollama             | `"ollama"`            | ローカル          | `http://localhost:11434/v1`                         |
| LM Studio          | `"lmstudio"`          | ローカル          | `http://localhost:1234/v1`                          |
| OpenAI Compatible  | `"openai-compatible"` | カスタム（互換プロトコル） | 手動設定が必要（API Key は任意）                                |

{% hint style="info" %}
**OpenAI Compatible** は、OpenAI API プロトコルを実装するすべてのサービスで動作します。ユーザーは Base URL を入力するだけで利用でき、API Key は任意です（一部のクラウドサービスでは必要ですが、ローカルサーバーでは通常不要です）。URL の末尾に `/v1` が含まれていない場合、システムが自動的に追加します。
{% endhint %}

{% hint style="danger" %}
**注意：** Google Gemini の Provider 名は `"google"` であり、`"gemini"` **ではありません**。

```javascript
// ✅ 正しい
const google = ai.getProvider("google");
ai.getModel("google::gemini-3-flash");

// ❌ 誤り
const gemini = ai.getProvider("gemini");
ai.getModel("gemini::gemini-3-flash");
```

{% endhint %}

***

## エラー処理 <a href="#error-handling" id="error-handling"></a>

### APIError クラス

AI SDK は API リクエストが失敗した際に `APIError` をスローし、完全なエラー情報を含みます。

#### プロパティ

| プロパティ          | 型                     | 説明                               |
| -------------- | --------------------- | -------------------------------- |
| `message`      | `string`              | エラーメッセージ                         |
| `status`       | `number \| undefined` | HTTP ステータスコード（例：401、403、500）     |
| `statusText`   | `string \| undefined` | HTTP ステータステキスト（例："Unauthorized"） |
| `code`         | `string \| undefined` | エラーコード（レスポンス内容から抽出）              |
| `provider`     | `string \| undefined` | Provider 名                       |
| `url`          | `string \| undefined` | リクエスト URL                        |
| `responseBody` | `unknown`             | サーバーが返した元のエラー内容                  |

#### メソッド

| メソッド         | 説明                               |
| ------------ | -------------------------------- |
| `toJSON()`   | 完全なエラー詳細オブジェクトを返します（ログ記録に適しています） |
| `toString()` | エラーメッセージ文字列を返します                 |

### エラー処理の例

```javascript
const ai = eagle.extraModule.ai;
const { generateText, APIError } = ai;

try {
    const model = ai.getModel(ai.getDefaultModel("chat"));
    const result = await generateText({
        model,
        prompt: "Hello!",
    });
    console.log(result.text);
} catch (error) {
    if (error instanceof APIError) {
        console.error("API エラー：", error.message);
        console.error("ステータスコード：", error.status);       // 401, 429, 500...
        console.error("Provider：", error.provider);    // "openai"

        // ステータスコードに基づく処理
        switch (error.status) {
            case 401:
                console.error("API Key が無効です。AI SDK の設定を確認してください");
                break;
            case 429:
                console.error("リクエスト頻度が高すぎます。しばらくしてから再試行してください");
                break;
            case 500:
                console.error("サーバー内部エラー");
                break;
        }

        // 完全なログを記録
        console.log(JSON.stringify(error.toJSON(), null, 2));
    } else {
        console.error("予期しないエラー：", error);
    }
}
```

### ネットワークエラー

Provider に接続できない場合（例：ローカルの Ollama が起動していない場合）も `APIError` が発生します：

```javascript
const ollama = ai.getProvider("ollama");
const result = await ollama.verify();

if (!result.ok) {
    console.error(result.error.message);
    // "[ollama] Network error: fetch failed"
}
```

***

## ベストプラクティス <a href="#best-practices" id="best-practices"></a>

### 1. デフォルトモデルを優先的に使用する

これが最も重要な推奨事項です。コード内に特定の Provider やモデルをハードコーディングするのではなく、`getDefaultModel()` で AI SDK 設定インターフェースでのユーザーの好みを直接継承してください：

```javascript
const ai = eagle.extraModule.ai;
const { generateText } = ai;

// ⭐ 推奨：ユーザーは AI SDK で好みのモデルを既に設定済み
const defaultLLM = ai.getDefaultModel("chat");

if (!defaultLLM) {
    console.log("AI SDK の設定でデフォルト言語モデルを選択してください");
    return;
}

const model = ai.getModel(defaultLLM);
const result = await generateText({ model, prompt: "..." });
```

**なぜモデルをハードコーディングすべきでないのか？** コード内で `ai.getProvider("openai")("gpt-5")` を指定しても、ユーザーが OpenAI を設定していなければエラーになります。「Provider が未設定」というエッジケースを追加で処理する必要があり、これは面倒です。デフォルトモデルを使用すれば、ユーザーが既に設定・検証済みであることが保証され、大量の防御的コードを省けます。

### 2. verify() の結果を正しく処理する

```javascript
// ✅ 正しい：result.ok をチェック
const result = await openai.verify();
if (result.ok) {
    // 接続成功
} else {
    console.error(result.error.message);
}

// ❌ 誤り：boolean として直接使用しない
if (await openai.verify()) { ... }
```

### 3. ストリーミングは長文テキスト生成に適している

応答が長くなることが予想される場合、`streamText()` を使用するとより良いユーザー体験を提供できます：

```javascript
const { textStream } = streamText({
    model: ai.getModel(ai.getDefaultModel("chat")),
    prompt: longPrompt,
});

for await (const chunk of textStream) {
    appendToUI(chunk);
}
```

***

## 完全な例 <a href="#full-example" id="full-example"></a>

以下は AI SDK の主要な機能の正しい使い方を示す総合的なプラグインの例です：

```javascript
eagle.onPluginCreate(async (plugin) => {
    const ai = eagle.extraModule.ai;
    const { generateText, generateObject, streamText, APIError } = ai;

    // 1. ユーザーが環境設定で選択したデフォルト言語モデルを取得
    const defaultLLM = ai.getDefaultModel("chat");

    if (!defaultLLM) {
        console.log("AI SDK の設定でデフォルト言語モデルを選択してください");
        return;
    }

    const model = ai.getModel(defaultLLM);
    console.log(`使用するデフォルトモデル：${defaultLLM}`);

    // 2. 基本テキスト生成
    try {
        const result = await generateText({
            model,
            prompt: "このプラグインの機能を一言で説明してください",
        });
        console.log("生成結果：", result.text);
    } catch (error) {
        if (error instanceof APIError) {
            console.error(`API エラー [${error.status}]：${error.message}`);
        }
    }

    // 3. 構造化オブジェクト生成
    try {
        const result = await generateObject({
            model,
            schema: {
                type: "object",
                properties: {
                    tags: { type: "array", items: { type: "string" } },
                    category: { type: "string" },
                },
            },
            prompt: "猫の写真に 3 つのタグとカテゴリを生成してください",
        });
        console.log("タグ：", result.object.tags);
        console.log("カテゴリ：", result.object.category);
    } catch (error) {
        console.error("オブジェクト生成に失敗：", error.message);
    }

    // 4. ストリーミングテキスト生成
    try {
        const { textStream } = streamText({
            model,
            prompt: "デジタルアートの制作テクニックを 5 つ挙げてください",
        });

        let fullText = "";
        for await (const chunk of textStream) {
            fullText += chunk;
        }
        console.log("ストリーミング結果：", fullText);
    } catch (error) {
        console.error("ストリーミング生成に失敗：", error.message);
    }
});
```

***

## API クイックリファレンス <a href="#api-cheatsheet" id="api-cheatsheet"></a>

### AI SDK トップレベルメソッド

| メソッド                        | 同期/非同期 | 戻り値の型                           | 説明                 |
| --------------------------- | ------ | ------------------------------- | ------------------ |
| `getProviders()`            | 同期     | `ProviderFunction[]`            | すべての Provider を取得  |
| `getProvider(name)`         | 同期     | `ProviderFunction \| undefined` | 指定した Provider を取得  |
| `getAvailableProviders()`   | 同期     | `ProviderFunction[]`            | 設定済みの Provider を取得 |
| `getModel(provider::model)` | 同期     | `Model`                         | モデルインスタンスを取得       |
| `getDefaultModel(type)`     | 同期     | `string \| undefined`           | デフォルトモデルを取得        |
| `open()`                    | 同期     | `void`                          | 環境設定のモデル設定パネルを開く   |
| `reload()`                  | 同期     | `void`                          | 最新の設定をリロード         |
| `generateText(options)`     | 非同期    | `Promise<GenerateTextResult>`   | テキストを生成            |
| `generateObject(options)`   | 非同期    | `Promise<GenerateObjectResult>` | 構造化オブジェクトを生成       |
| `streamText(options)`       | 非同期    | `StreamTextResult`              | ストリーミングテキスト生成      |
| `streamObject(options)`     | 非同期    | `StreamObjectResult`            | ストリーミングオブジェクト生成    |

### Provider インスタンスメソッド

| メソッド                | 同期/非同期 | 戻り値の型                   | 説明             |
| ------------------- | ------ | ----------------------- | -------------- |
| `provider(modelId)` | 同期     | `Model`                 | モデルを取得（関数呼び出し） |
| `verify()`          | 非同期    | `Promise<VerifyResult>` | 接続と認証を検証       |
| `getModels()`       | 非同期    | `Promise<string[]>`     | モデルリストを取得      |
| `hasModel(modelId)` | 非同期    | `Promise<boolean>`      | モデルの存在を確認      |

### Provider インスタンスプロパティ

| プロパティ     | 型                     | 説明                  |
| --------- | --------------------- | ------------------- |
| `name`    | `string`              | Provider 名（読み取り専用）  |
| `baseURL` | `string \| undefined` | API エンドポイント（読み取り専用） |

### VerifyResult

| プロパティ   | 型                       | 説明            |
| ------- | ----------------------- | ------------- |
| `ok`    | `boolean`               | 検証が成功したかどうか   |
| `error` | `APIError \| undefined` | 失敗時のエラーオブジェクト |
