BluePeriod Docs
開発

API仕様書

Honoフレームワーク基盤のAPIエンドポイント仕様

API仕様書 (05_api_specification.md)

本ドキュメントは、Hono フレームワークに集約された新 API 構造に基づいて記載されています。

1. 概要

本アプリケーションのバックエンドは、Next.jsのAPI Routes機能を利用して構築されています。これにより、フロントエンドと同じプロジェクト内でサーバーサイドロジックを管理し、特に外部のLLM(大規模言語モデル)プロバイダーとの連携を担います。

  • 設計思想:
    • API RoutesはBFF (Backend For Frontend) として機能し、クライアントからのリクエストを整形して各種LLMプロバイダーへ仲介します。
    • APIキーなどの機密情報は、原則としてサーバーサイド(環境変数)で管理しますが、ユーザーがクライアントサイドで入力したキーを優先的に使用する「Bring Your Own Key (BYOK)」モデルもサポートします。

2. 内部API (/api/*)

フロントエンドとバックエンドの間の通信に使用されるRPC風の内部APIです。

エンドポイントHTTPメソッド主な役割分類 (サブアプリ)
/api/chatPOST汎用的なAIとの対話、エージェント実行chat.ts
/api/ai/reviewPOST作品原稿の査読レポート生成ai.ts
/api/ai/metadata-generatePOST作品のメタデータ案(タイトル等)生成ai.ts
/api/ai/metadata-translatePOSTメタデータの多言語翻訳ai.ts
/api/ai/structure-plotPOSTプロットの構造化ai.ts
/api/ai/refine-plot-chunkPOSTプロットアイテムの改修ai.ts
/api/publishPOST作品のクラウド公開publish.ts
/api/projects/statusPOSTプロジェクトの公開・非公開状態管理projects.ts
/api/libraryGET/POST本棚(ライブラリ)のアイテム取得・操作library.ts
/api/tools/web-searchPOSTWeb検索のプロキシtools.ts
/api/tools/open-urlPOSTURLの読込とMarkdown変換tools.ts
/api/tools/aditPOSTAIによる決定論的テキスト編集 (Adit)tools.ts
/api/models/openrouterGETOpenRouter のモデル一覧取得models.ts
/api/current-timeGETサーバー時刻の取得infra.ts
/api/seo/sitemapGETサイトマップの動的生成seo.ts

3. RESTful API (/v1/*)

RESTful規約に準拠した外部公開APIです。API Key認証が必須です。

3.1. 認証方式

API Key認証: Authorization: Bearer <key> ヘッダーによる認証

  • 発行: Settings画面の「Developer API Keys」セクションから発行可能
  • 権限スコープ: ["read"](読み取り専用)、["read", "write"](読み書き)
  • レートリミット: API Key単位のリクエスト制限(read: 300/hour, write: 60/hour)

3.2. Public API(読み取り専用)

エンドポイントHTTPメソッド説明クエリパラメータ
/v1/projectsGET公開プロジェクト一覧page, q, tags
/v1/projects/:idGETプロジェクト詳細(profiles JOIN付き)-
/v1/projects/:id/contentGET原稿内容lang(言語絞り)
/v1/projects/:id/tocGET目次(story ID + 文字数 + 対応言語)-
/v1/projects/:id/stories/:storyIdGET1話分の本文lang
/v1/users/:idGETユーザープロフィール(公開情報のみ)-
/v1/tagsGETローカライズ済みタグ一覧lang

3.3. Developer API(認証付き / 管理操作)

エンドポイントHTTPメソッド説明必要権限
/v1/users/meGET認証済みユーザー情報-
/v1/users/me/projectsGET自分の出版プロジェクト一覧-
/v1/users/me/libraryGETライブラリ一覧-
/v1/projects/:idDELETE出版プロジェクトの非公開化write
/v1/projects/:idPATCH出版済みプロジェクトのメタデータ更新write

3.4. OpenAPI・Scalar UI

  • OpenAPI仕様書: /v1/openapi.json — @hono/zod-openapi で自動生成
  • APIドキュメント: /v1/docs — Scalar UI で表示(認証テスト可能)

4. エンドポイント仕様詳細

3.1. GET /api/projects/[id]/metadata

指定されたprojectIdの公開済みメタデータ(title, synopsis, tagsなど)をSupabaseから取得します。

  • 目的: 公開済みプロジェクトを更新する際に、既存のメタデータをフォームの初期値として表示するために使用します。
  • 認証: 不要 (RLSにより公開データのみ返却されるため)
  • リクエストパラメータ (params):
    • id (必須): string。取得するプロジェクトのUUID。
  • 処理フロー:
    1. projectIdが存在しない場合は400 Bad Requestを返します。
    2. published_projectsテーブルから、指定されたidのプロジェクトのメタデータ(title, headline, synopsis, original_language, default_language, localizations, cover_image_url)を取得します。
    3. プロジェクトが見つからない場合(PGRST116エラーコード)、null200 OKを返します。
  • 成功レスポンス (200 OK):
    {
      "title": "作品タイトル(英語)",
      "headline": "キャッチコピー(英語)",
      "synopsis": "あらすじ(英語)",
      "original_language": "ja",
      "default_language": "en",
      "localizations": {
        "ja": { "title": "日本語タイトル", "headline": "...", "synopsis": "...", "tags": ["タグ1"] },
        "en": { "title": "English Title", "tags": ["tag1", "tag2"] }
      },
      "cover_image_url": "https://..."
    }
    • プロジェクトが見つからない場合は null
  • エラーレスポンス:
    • Status Code: 400 Bad Request, 500 Internal Server Error
    • Body:
      {
        "error": "エラーの概要",
        "details": "詳細なエラーメッセージ"
      }

3.2. PATCH /api/projects/[id]/metadata

指定されたprojectIdの公開済みメタデータを部分的に更新します。多言語対応(英語と原典言語)のメタデータ編集をサポートします。

  • 目的: マイワークス画面の「メタデータを編集」モーダルから、タイトル、あらすじ、カバー画像などを更新する際に使用します。
  • 認証: 必須。auth.users.idがプロジェクトの所有者(user_id)と一致する場合のみ更新が許可されます。
  • リクエストパラメータ (params):
    • id (必須): string。更新するプロジェクトのUUID。
  • リクエストボディ (JSON):
    {
      "title": "作品タイトル(英語)",
      "headline": "キャッチコピー(英語)", // (任意)
      "synopsis": "あらすじ(英語)", // (任意)
      "localizations": {
        "ja": { "title": "日本語タイトル", "headline": "キャッチコピー", "synopsis": "あらすじ", "tags": ["タグ1"] },
        "en": { "title": "English Title", "tags": ["tag1", "tag2"] }
      }, // (任意) localizations JSONBによる多言語メタデータ
      "cover_image_url": "https://..." // (任意) nullの場合は削除
    }
  • 成功レスポンス (200 OK):
    {
      "message": "Metadata updated successfully"
    }
  • エラーレスポンス:
    • Status Code: 400 Bad Request (バリデーションエラー), 401 Unauthorized (未認証), 404 Not Found (プロジェクトなし/権限なし), 500 Internal Server Error
    • Body:
      {
        "error": "エラーメッセージ"
      }

3.3. POST /api/publish

査読済みの作品をSupabaseのデータベースとストレージに保存し、公開状態にします。

  • 目的: フロントエンドの公開ウィザードから送信された作品データを受け取り、永続化します。
  • 認証: 必須。リクエストヘッダーのCookieを元にSupabaseのサーバーサイドクライアントでセッションを検証します。
  • リクエストボディ (FormData):
    • file (任意): Fileオブジェクト。作品のカバー画像。
    • data (必須): string。以下の構造を持つJSONオブジェクトを文字列化したもの。
      {
        "id": "project-uuid-string",
        "title": "作品タイトル(英語フォールバック)",
        "headline": "キャッチコピー(英語フォールバック)",
        "synopsis": "あらすじ(英語フォールバック)",
        "original_language": "ja", // (任意) 原典言語コード
        "localizations": {
          "ja": { "title": "日本語タイトル", "headline": "日本語見出し", "synopsis": "日本語あらすじ", "tags": ["タグ1"] },
          "en": { "title": "English Title", "headline": "English Headline", "synopsis": "English Synopsis", "tags": ["tag1"] }
        },
        "content": { ... }, // ProjectContent型の完全なオブジェクト
        "review_report": { ... } // (任意) AI査読レポート
      }
  • 処理フロー:
    1. ユーザーセッションを検証し、未認証の場合は401 Unauthorizedを返します。
    2. FormDataを解析します。dataフィールドが存在しない場合は400 Bad Requestを返します。
    3. データ構造検証: ProjectContentSchema(Zodスキーマ)によるランタイム検証と、構造整合性検証(孤立原稿・未執筆セクション・空原稿・空プロットの検出)を実行します。検証に失敗した場合は400 Bad Requestを返します。
    4. fileが存在する場合、Supabase Storageのcoversバケットに{user_id}/{project_id}.{ext}のパスでアップロードし、公開URLを取得します。
    5. データ順序の保証: content.manuscriptsのキーをstructuredPlotの階層順序に基づいて並べ替えます(reorderManuscriptsByPlotヘルパー関数を使用)。これにより、JSON出力時のキー順序がプロット順になり、Reader ViewerやAPIレスポンスでの表示順序が保証されます。データ形式はオブジェクト {[sectionId]: {versions}} のまま変更しません。
    6. published_projectsテーブルに、変換後のコンテンツと画像の公開URLをupsertします。
  • 成功レスポンス (200 OK):
    {
      "success": true,
      "projectId": "project-uuid-string"
    }
  • エラーレスポンス:
    • Status Code: 400 Bad Request, 401 Unauthorized, 500 Internal Server Error
    • Body:
      {
        "error": "エラーの概要",
        "details": "詳細なエラーメッセージ"
      }
    • バリデーションエラー時 (400 Bad Request):
      {
        "error": "Invalid project structure",
        "details": [
          { "path": "structuredPlot", "message": "プロット構造が空です" }
        ],
        "warnings": [
          { "path": "manuscripts.orphan-id", "message": "プロットに存在しないセクションIDの原稿です" }
        ]
      }

3.2. POST /api/ai/review

作品原稿をAIが査読し、品質と安全性の評価レポートを生成します。レポートは常に英語で生成されます。

  • 目的: 作品の公開前に、AIによる自動査読を行い、公開可否の判断材料を提供します。
  • 認証: 必須。
  • リクエストボディ (JSON):
    {
      "manuscripts": { ... }, // ProjectContent.manuscripts と同形式
      "structuredPlot": { ... }, // StructuredPlot と同形式
      "apiKey": "gemini-api-key" // ユーザーのGemini APIキー
    }
    • manuscripts (必須): 査読対象の原稿データ。
    • structuredPlot (必須): 原稿の構造化されたプロットデータ。
    • apiKey (必須): Gemini APIキー。
  • 処理フロー:
    1. 提供された原稿とプロットから、査読のためのコンテキストを生成します。
    2. Gemini AIモデルを呼び出し、査読レポートを生成させます。
  • 成功レスポンス (200 OK):
    {
      "overall_assessment": {
        "is_publishable": true,
        "summary": "..."
      },
      "completion_status": {
        "is_complete": true,
        "reasoning": "..."
      },
      "prohibitions": [],
      "warnings": [],
      "dynamic_detailed_ratings": []
    }
    • ReviewReport スキーマに準拠したJSONオブジェクト。
  • エラーレスポンス:
    • Status Code: 400 Bad Request, 500 Internal Server Error
    • Body:
      {
        "error": "Failed to review content",
        "details": "詳細なエラーメッセージ"
      }

3.3. POST /api/ai/metadata-generate

作品のタイトル、あらすじ、タグなどのメタデータ案を、AIが原典言語で3つ生成します。

  • 目的: 作者の母語でのメタデータ作成をAIが支援し、ユーザーの負担を軽減します。
  • 認証: 必須。
  • リクエストボディ (JSON):
    {
      "manuscripts": { ... }, // ProjectContent.manuscripts と同形式
      "structuredPlot": { ... }, // StructuredPlot と同形式
      "apiKey": "api-key", // フォールバック用APIキー
      "provider": "google", // (省略可) プロバイダーID
      "model": "gemini-2.5-flash", // (省略可) モデル名
      "userApiKeys": { "google": "key" }, // (省略可) プロバイダー別APIキー
      "temperature": 0.7, // (省略可)
      "topP": 0.9 // (省略可)
    }
    • manuscripts (必須): メタデータ生成の参考となる原稿データ。
    • structuredPlot (必須): メタデータ生成の参考となるプロットデータ。
    • apiKey (必須): フォールバック用APIキー。
    • provider / model / userApiKeys (省略可): マルチプロバイダー対応。userApiKeys[provider] → 環境変数 → apiKeyの順で解決。
  • 処理フロー:
    1. 提供された原稿とプロットから、メタデータ生成のためのコンテキストを生成します。
    2. 指定されたプロバイダー/モデルでメタデータ提案を3つ生成させます。
  • 成功レスポンス (200 OK):
    {
      "proposals": [
        {
          "title": "提案タイトル1",
          "headline": "提案キャッチコピー1",
          "synopsis": "提案あらすじ1",
          "tags": ["タグ1", "タグ2"]
        },
        // ... 他2つの提案
      ]
    }
    • MetadataGenerationResponse スキーマに準拠したJSONオブジェクト。
  • エラーレスポンス:
    • Status Code: 400 Bad Request, 500 Internal Server Error
    • Body:
      {
        "error": "Failed to generate metadata",
        "details": "詳細なエラーメッセージ"
      }

3.4. POST /api/ai/metadata-translate

確定した原典言語のメタデータを、AIが指定言語に翻訳します。

  • 目的: グローバル公開のために、原典言語のメタデータを高品質な翻訳に変換します。
  • 認証: 必須。
  • リクエストボディ (JSON):
    {
      "metadata": {
        "title": "原典タイトル",
        "headline": "原典キャッチコピー",
        "synopsis": "原典あらすじ",
        "tags": ["原典タグ1", "原典タグ2"]
      },
      "originalLanguage": "ja", // 原典言語コード (例: 'ja')
      "targetLanguage": "en", // (省略可、デフォルト: 'en')
      "apiKey": "api-key", // フォールバック用APIキー
      "provider": "google", // (省略可) プロバイダーID
      "model": "gemini-2.5-flash", // (省略可) モデル名
      "userApiKeys": { "google": "key" }, // (省略可) プロバイダー別APIキー
      "temperature": 0.5, // (省略可)
      "topP": 0.8 // (省略可)
    }
    • metadata (必須): 翻訳対象の原典言語メタデータ。
    • originalLanguage (必須): 原典言語のBCP 47言語タグ(例: ja, en, zh-Hans)。
    • targetLanguage (省略可): 翻訳先言語。デフォルトは en
    • apiKey (必須): フォールバック用APIキー。
    • provider / model / userApiKeys (省略可): マルチプロバイダー対応。
  • 処理フロー:
    1. 指定されたプロバイダー/モデルでメタデータを翻訳します。
  • 成功レスポンス (200 OK):
    {
      "title": "Translated Title",
      "headline": "Translated Headline",
      "synopsis": "Translated synopsis...",
      "tags": ["Translated Tag1", "Translated Tag2"]
    }
    • TranslatedMetadata スキーマに準拠したJSONオブジェクト。
  • エラーレスポンス:
    • Status Code: 400 Bad Request, 500 Internal Server Error
    • Body:
      {
        "error": "Failed to translate metadata",
        "details": "詳細なエラーメッセージ"
      }

3.5. POST /api/chat

汎用的なLLMとの対話を実現するエンドポイントです。ストリーミングと非ストリーミングの両方に対応しています。

  • 目的: ユーザーからのメッセージ履歴を受け取り、選択されたLLMプロバイダーとモデルに応じた設定でAPIを呼び出し、AIの応答を返却します。

  • リクエストボディ (JSON):

    {
      "messages": [
        { "role": "system", "content": "..." },
        { "role": "user", "content": "..." },
        { "role": "assistant", "content": "..." }
      ],
      "provider": "openai" | "google" | "anthropic" | "openrouter",
      "model": "gpt-4o",
      "userApiKeys": {
        "openai": "sk-...",
        "google": "..."
      },
      "temperature": 0.7,
      "topP": 0.95,
      "stream": true
    }
    • messages (必須): LangChain形式のメッセージ配列。
    • provider (必須): 使用するLLMプロバイダーID。
    • model (必須): 使用するモデル名。
    • userApiKeys (任意): ユーザーが提供したAPIキーのオブジェクト。
    • temperature (任意): 生成時の温度。デフォルトは0.7
    • topP (任意): トップPサンプリング。デフォルトは0.95
    • stream (任意): ストリーミング応答を要求するかどうか。デフォルトはtrue
  • 成功レスポンス:

    • ストリーミング (stream: true):
      • Content-Type: text/plain; charset=utf-f
      • Body: AIからの応答テキストがチャンク形式で逐次送信される。
    • 非ストリーミング (stream: false):
      • Content-Type: application/json
      • Body:
        {
          "content": "AIからの完全な応答テキスト"
        }
  • エラーレスポンス:

    • Status Code: 400 Bad Request, 500 Internal Server Error
    • Body:
      {
        "error": "エラーメッセージ",
        "details": "詳細情報"
      }

3.3. GET /api/models/openrouter

OpenRouter.aiで利用可能なLLMのモデルID一覧を取得します。

  • 目的: クライアントサイドのモデル選択UIに、動的に最新のモデルリストを提供します。

  • リクエスト: なし

  • 成功レスポンス:

    • Content-Type: application/json
    • Body:
      {
        "models": [
          "openai/gpt-4o",
          "google/gemini-2.5-pro",
          "anthropic/claude-3.5-sonnet",
          ...
        ]
      }
  • エラーレスポンス:

    • Status Code: 500 Internal Server Error
    • Body:
      {
        "error": "Failed to fetch models from OpenRouter.",
        "details": "詳細なエラーメッセージ"
      }

3.4. POST /api/refine-plot-chunk

指定されたプロットの単一アイテム(Part, Arc, Chapterなど)を、ユーザーの指示に基づきAIが改善(リファイン)し、更新されたJSONオブジェクトを返します。

  • 目的: ユーザーがプロットの特定の部分に集中し、AIと対話しながらその内容を洗練させることを可能にする。

  • リクエストボディ (JSON):

    {
      "targetItem": { ... },
      "itemType": "part" | "arc" | "chapter" | "story" | "section",
      "context": { ... },
      "instruction": "ユーザーからの具体的な指示テキスト...",
      "baseMessages": [
        { "role": "system", "content": "..." }
      ],
      "provider": "google",
      "model": "gemini-2.5-pro",
      "userApiKeys": { ... },
      "temperature": 0.7,
      "topP": 0.95
    }
    • targetItem (必須): リファイン対象となるプロットアイテムのJSONオブジェクト。
    • itemType (必須): targetItemの階層を示す文字列。
    • context (必須): 周辺の文脈を理解するための、プロジェクト全体のプロットオブジェクト。
    • instruction (必須): AIに対する具体的な改善指示。
    • baseMessages (必須): 執筆プロンプトなど、AIの振る舞いを規定するシステムメッセージ配列。
    • provider, model, userApiKeys, temperature, topP: /api/chatと同様。
  • 成功レスポンス:

    • Content-Type: application/json
    • Body: itemTypeで指定されたスキーマに準拠した、更新後のプロットアイテムのJSONオブジェクト。
      {
        "id": "...", // IDは変更されない
        "chapter_number": 1,
        "chapter_title": "(改善されたタイトル)",
        "theme": "(改善されたテーマ)",
        ...
      }
  • エラーレスポンス:

    • Status Code: 400 Bad Request, 500 Internal Server Error
    • Body:
      {
        "error": "Failed to refine plot chunk",
        "details": "詳細なエラーメッセージ"
      }

3.5. POST /api/structure-plot

自然言語で記述されたプロットを、Zodスキーマに基づいた厳密な階層構造のJSONオブジェクトに変換します。

  • 目的: ユーザーが自由形式で入力した小説のプロット案を、アプリケーションが解釈可能な形式的なデータ構造に変換し、執筆プロセスを支援します。

  • リクエストボディ (JSON):

    {
      "plotInput": "ユーザーが入力したプロットのテキスト...",
      "baseMessages": [
        { "role": "system", "content": "..." }
      ],
      "provider": "google",
      "model": "gemini-2.5-pro",
      "userApiKeys": { ... },
      "temperature": 0.5,
      "topP": 1.0,
      "plotConfig": {
        "parts": 1,
        "arcsPerPart": 2,
        "chaptersPerArc": 3,
        "storiesPerChapter": 2,
        "sectionsPerStory": 4,
        "wordsPerSection": 3000
      },
      "plotMetrics": {
        "totalStories": 12,
        "totalSections": 48,
        "totalWords": 144000,
        "wordsPerStory": 12000
      }
    }
    • plotInput (必須): 構造化対象のプロットテキスト。ユーザーは物語のコンセプト・設定のみを記述する。構成パラメータはplotConfig経由で別途注入される。
    • baseMessages (必須): プロンプトカードなどから生成されたシステムプロンプトを含むメッセージ配列。
    • provider, model, userApiKeys, temperature, topP: /api/chatと同様。
    • plotConfig (任意): 構成パラメータ(部数、編数、章数、話数、節数、各節文字数)。指定時はplotPromptTemplate.tsのテンプレートを用いてユーザープロンプトが動的生成される。未指定時は従来のフォールバックプロンプトが使用される。
    • plotMetrics (任意): plotConfigからplotConfigCalculator.tsで算出された指標(総話数、総文字数、1話あたり文字数など)。plotConfigとセットで使用される。
  • 成功レスポンス:

    • Content-Type: application/json

    • Body: types.tsで定義されたStructuredPlot型に準拠したJSONオブジェクト。

      {
        "language": "ja",
        "parts": [
          {
            "id": "a1b2c3d4-...",
            "part_number": 1,
            "part_title": "...",
            "arcs": [
              {
                "id": "e5f6g7h8-...",
                "arc_number": 1,
                "arc_title": "...",
                "chapters": [ ... ]
              }
            ]
          }
        ]
      }

      UUID保証: 全階層(Part, Arc, Chapter, Story, Section)のidフィールドには、アプリケーション側で機械的に生成された一意なUUID v4が設定されます。LLMの出力に依存しないため、一意性が保証されます。

  • エラーレスポンス:

    • Status Code: 400 Bad Request, 500 Internal Server Error
    • Body:
      {
        "error": "Failed to structure plot",
        "details": "詳細なエラーメッセージ"
      }

4. 小説執筆生成の実装仕様(/api/chat の使用例)

小説のセクション執筆生成(generateSection)および翻訳(translateSection)は、専用のAPIエンドポイントではなく、汎用 /api/chat をプロンプトベースで使用しています。これにより、柔軟なプロンプト調整が可能ですが、仕様書への明記を怠ると実装の理解が難しくなります。

4.1. セクション生成 (generateSectionAtom の処理フロー)

  • トリガー: LeftPanel.tsx 内の生成ボタン(Playアイコン)から generateSectionAtom を呼び出し、addJob でジョブ化。
  • API呼び出し: POST /api/chat
  • 主なリクエストパラメータ(抜粋):
    {
      "messages": [
        // writingPromptsAtom から baseMessages を構築 (執筆プロンプトカード)
        { "role": "system", "content": "執筆ガイドライン..." },
        {
          "role": "user",
          "content": "# OVERALL PLOT STRUCTURE (全体プロットJSON)\n# 直近の文脈 (先行セクション)\n# 今回執筆する節 (章/話/節詳細, 目標文字数)\n# 言語生成モジュール規則 (読点控えめ, 繰り返し禁止)\n\n小説テキストのみ出力。"
        }
      ],
      "provider": "google|openai|anthropic|openrouter",
      "model": "gemini-2.5-pro|gpt-4o|...",
      "userApiKeys": { "google": "...", ... },
      "temperature": 0.7,
      "topP": 0.95,
      "stream": true
    }
  • 文脈構築: writingContextWindowAtom で制限した先行セクションのマヌスクリプト + 全体プロットJSON。
  • レスポンス処理: ストリーミングで manuscriptsAtom に更新、デバッグ情報記録 (debugInfo.prompt 等)。

4.2. セクション翻訳 (translateSectionAtom)

  • トリガー: Globeドロップダウンから translateSectionAtom
  • プロンプト: 「プロの文芸翻訳家。直前文脈 + 原典テキスト を自然な[targetLang]に翻訳。テキストのみ出力。」

詳細実装: next-app/src/stores/aiGenerationAtoms.ts

将来的に専用API(/api/ai/generate-section)化を検討。

4.3. POST /api/tools/web-search

AIエージェントによるWeb検索機能を提供するエンドポイントです。Tavily Search APIをプロキシし、最新のWeb情報を取得します。

  • 目的: エージェントモードのチャットで、AIが自律的にWeb検索を行えるようにします。

  • リクエストボディ (JSON):

    {
      "query": "検索クエリ文字列",
      "apiKey": "tvly-..." // ユーザーのTavily APIキー
    }
    • query (必須): 検索クエリ。
    • apiKey (必須): Tavily APIキー。
  • 成功レスポンス (200 OK):

    • Content-Type: application/json
    • Body:
      {
        "results": [
          {
            "title": "ページタイトル",
            "url": "https://example.com",
            "content": "ページ内容の要約...",
            "score": 0.95
          },
          ...
        ]
      }
  • エラーレスポンス:

    • Status Code: 400 Bad Request, 500 Internal Server Error
    • Body:
      {
        "error": "Failed to perform web search",
        "details": "詳細なエラーメッセージ"
      }

詳細実装: next-app/src/app/api/tools/web-search/route.ts


関連ドキュメント:

  • 12_ai_agent_architecture.md - エージェントアーキテクチャの詳細

On this page