dogfood アプリで使う SDK 導線

顧客のプロバイダーキーを保持せずに Vela を追加する。

@vela/sdk で Hosted Connect を開き、アプリが選んだ顧客委任を結び付け、 モデル実行ごとに認可し、OpenAI Compatible relay を呼び出し、監査用に結果を報告します。

  • Vela は委任、失効、利用上限、監査の control plane に集中します。
  • 短命 relay access の背後にある execution backend は OpenRouter のままです。
  • SDK は framework 側のコードを小さく保ち、ID、セッション、チャット UI、モデル履歴はアプリが持ちます。
MVP 境界

顧客の生プロバイダーキーを開発者アプリに保存しません。アプリは customerTenantIddelegationId を保存し、 モデル呼び出しの直前に Vela へスコープ付き relay access を要求します。

導入フロー

  1. 1

    アプリを登録

    開発者コンソールが SDK client で使う App ID と App token を発行します。

  2. 2

    顧客を接続

    Hosted Connect が顧客の委任を作成または再利用します。

  3. 3

    スコープを保存

    アプリは選択された顧客 ID と委任 ID を保存し、必要なときに復元します。

  4. 4

    呼び出しを準備

    Vela は実行前に状態、ポリシー、モデル、ZDR、利用額を確認します。

  5. 5

    結果を報告

    アプリは完了または失敗した実行結果を監査へ返します。

クイックスタート

まず @vela/sdk から始めます。チャットモデルと stream callback の配線 helper が必要な AI SDK ルート だけ @vela/ai-sdk を追加してください。

1. インストール
package manager
pnpm add @vela/sdk
pnpm add @vela/ai-sdk ai
2. サーバー環境変数を設定
.env.local
VELA_APP_ID=app_example
VELA_APP_TOKEN=vela_sk_example
# ローカル Vela API 開発時のみ任意で設定します。
VELA_BASE_URL=http://localhost:4000
最小のサーバー route 構成 Fetch API 互換
import { createVelaClientFromEnvironment, createVelaEnvironmentDiagnosticsResponse, createVelaErrorResponse, createVelaIntegration, getVelaEnvironmentDiagnostics } from "@vela/sdk";

const CHAT_ESTIMATED_COST_USD = 0.05;

export async function POST(req: Request) {
  const environment = getVelaEnvironmentDiagnostics({ env: process.env });

  if (!environment.ok) {
    return createVelaEnvironmentDiagnosticsResponse(environment);
  }

  try {
    const executionScope = await resolveExecutionScopeForRequest(req);

    if (!executionScope) {
      return Response.json({ error: "Vela execution scope が未設定です。" }, { status: 400 });
    }

    const client = createVelaClientFromEnvironment({ env: process.env });
    const vela = createVelaIntegration({ client, executionScope });
    const prepared = await vela.prepareExecutionWithResponse({
      estimatedCostUsd: CHAT_ESTIMATED_COST_USD,
    });

    if (prepared.outcome !== "allow") {
      return prepared.response;
    }

    const result = await callModel({
      model: prepared.openAiCompatibleModel,
      ...prepared.openAiCompatibleClientOptions,
    });

    await prepared.reportCompletedWithUsage(extractUsage(result));
    return Response.json({ result });
  } catch (error) {
    return createVelaErrorResponse(error, {
      fallbackMessage: "Vela chat で予期しないエラーが発生しました。",
    });
  }
}