Skip to content

EP-027 daily_article_ai_chat_send(日別記事 AI 相談送信) ​

← EP-一覧 · EP-028 セッション削除 · EP-031 セッション作成 · EP-032 セッション読込

概要 ​

日別記事の編集画面から、ホールと前半・後半考察を指定して AI に相談する。ハンドラは返信文と欄別下書きを JSON で返す。考察欄の post meta へは自動保存しない(画面上のエディタ末尾への挿入はフロントが行う)。会話履歴は db_daily_article_ai_chat_message にセッション単位で保存する(session_id 必須。LLM 履歴も当該セッションのみ)。

LLM のプロバイダ・モデル・API キーは ADM-028 の設定を再利用する。システムプロンプトは ADM-028 の日別記事 AI 相談用 option(mycustom_daily_article_ai_chat_system_prompt / PaidArticleAiOptions)を参照する。空のときは DailyArticleAiChatServiceCopy::DEFAULT_SYSTEM_PROMPT にフォールバックする(一括生成用システムプロンプト mycustom_paid_article_ai_system_prompt は使わない)。ツールは同イベント関係日一覧・同じ日にちの機種差枚・6の日の機種差枚・同イベントの機種差枚・編集メモ検索・編集メモ保存・機種名解決・機種の期間差枚・ホールの期間合計差枚・機種別差枚(日付リスト)・公開済み過去考察・店舗調査(X 投稿取得 fetch_hall_x_posts/Grok 調査 investigate_hall_with_grok。契約は 店舗調査 AI ツール)(有料記事 AI のツールカタログは使わない。店舗調査ツールのみ同じインスタンスを共有する)。

差枚系ツールの引数と役割分担 ​

ツール主な用途任意の機種指定
resolve_kishu_name略称・通称を正式名称 / kishu_id へ事前解決(差枚は返さない)必須 kishu(string 1 件)。共通 ArticleAiKishuNameResolver。未解決・曖昧時は status / candidates
fetch_kishu_samai_for_dates指定した日付リスト×ホールの日単位差枚kishu(公式名の文字列配列・最大20)/ kishu_ids(整数配列・最大20)。省略時は合計差枚 TOP N。指定時は該当機種のみ(TOP 外も可)。データ無しの日×ホールは machines: []
fetch_same_calendar_day_results / fetch_six_day_results / fetch_same_event_results関連日(同じ日にち・6の日・同イベント)ごとの日単位差枚同上。ヘルパー経由で同一契約
fetch_period_kishu_samai期間全体の合計・平均差枚(相対期間は考察日から Y-m-d に直して呼ぶ)機種は必須。編集メモ → 機種マスタ名・ヒートマップ略称・機種表示マッピング(共通 ArticleAiKishuNameResolver)→ 期間内部分一致で通称解決。未解決・曖昧時は差枚を返さず status。日単位・関連日の列挙には使わない

fetch_kishu_samai_for_dates および関連日系ツールの kishu は有効な機種マスタの公式名完全一致で ID 解決し(一覧を一括取得して照合)、kishu_ids とマージする。1 件でも未解決の機種名があれば JSON error(KISHU_NOT_IN_MASTER)。件数超過は KISHU_TOO_MANY / KISHU_IDS_TOO_MANY。部分成功(一部名だけ捨てて返す)はしない。

fetch_period_kishu_samai の機種解決は上記の公式名完全一致フィルタとは別経路(共通 Resolver + 編集メモ + 期間内部分一致)である。resolve_kishu_name は Resolver 単体の結果を返す(編集メモや期間内部分一致は使わない)。

セッションタイトルが空のとき、初回送信のユーザー文先頭 40 文字で自動設定する。

POST パラメータ ​

フィールド必須型・制約説明
action○文字列daily_article_ai_chat_send
_wpnonce○文字列daily_article_ai_chat で発行した nonce。nonce でも受け付ける
post_id○正整数対象の daily_article 投稿 ID
session_id○正整数対象セッション(当該 post_id に属すること)
message○非空文字列ユーザーの相談文
halls○文字列配列、または JSON 配列文字列island / espasu / bigapple を 1 つ以上
fields○文字列配列、または JSON 配列文字列pre / after を 1 つ以上
field_contents−JSON オブジェクト文字列(meta キー → HTML)画面上の現行考察本文。省略時は空マップ

成功時 data ​

論理名物理名型説明
返信文replystringチャットに表示する説明文
下書きdraftsobject選択された {hall}_{pre|after} キー → 段落 HTML(空オブジェクト可)
根拠sourcesarray今回の返答で呼んだツール根拠(下記)。ツール未使用時は空配列
セッション一覧sessionsarray当該投稿のセッション一覧(タイトル更新後)
アクティブセッションactiveSessionIdnumber送信に使ったセッション ID
履歴messagesarray当該セッションの保存後メッセージ(下記)

sessions[] ​

論理名物理名型説明
IDidnumberセッション ID
タイトルtitlestring空なら UI で「新しいチャット」
作成日時created_atstringMySQL datetime
更新日時updated_atstringMySQL datetime

sources[] / messages[].sources[] ​

assistant メッセージのみ。ツール未使用は空配列 []、旧データ・user は null(パネル非表示)。

論理名物理名型説明
ツール名toolstringTool Use の name(例: fetch_six_day_results)
表示名labelstring日本語ラベル
引数要約argsstring呼び出し引数の短い要約(例: date=…, halls=[…])
結果要約summarystringツール結果の短い要約(件数・日付・記事ID・機種例など)

messages[] ​

論理名物理名型説明
IDidnumber行 ID
セッションIDsession_idnumber所属セッション
役割rolestringuser / assistant
本文bodystringユーザー文または reply
ホールhallsstring[]送信時点の選択ホール
欄fieldsstring[]送信時点の選択欄(pre / after)
下書きdraftsobject|nullassistant のみ。user は null
根拠sourcesarray|nullassistant のみ。ツール未使用は []、旧データは null
作成日時created_atstringMySQL datetime

失敗・ブロック(success: false) ​

条件message の内容
AJAX コンテキスト外・nonce 不正Messages::AUTH_FAILED
post_id が不正、または投稿タイプが daily_article でないDailyArticleAiChatAjaxCopy::INVALID_POST
edit_post 権限なしMessages::PERMISSION_DENIED
session_id が欠落・0DailyArticleAiChatAjaxCopy::SESSION_REQUIRED
session_id が当該投稿に属さないDailyArticleAiChatServiceCopy::SESSION_INVALID(Ajax 経由でそのまま返却)
message が空DailyArticleAiChatAjaxCopy::MESSAGE_REQUIRED
halls が空DailyArticleAiChatAjaxCopy::HALLS_REQUIRED
halls に許可外 slug が含まれるDailyArticleAiChatAjaxCopy::HALLS_INVALID
fields が空DailyArticleAiChatAjaxCopy::FIELDS_REQUIRED
fields に許可外値が含まれるDailyArticleAiChatAjaxCopy::FIELDS_INVALID
Claude / Gemini 両方の API キー未設定(Service 例外)DailyArticleAiChatServiceCopy::API_KEY_MISSING または GEMINI_API_KEY_MISSING(保存済みプロバイダ側の文言。詳細は error_log にも記録)
HTTP 429 / quota(Service 例外)Messages::AI_LLM_CLAUDE_RATE_LIMITED / AI_LLM_GEMINI_RATE_LIMITED(応答から取れた待ち秒が 1〜120 なら「(約 N 秒後)」を付与。生レスポンスは出さない)
HTTP 401 / 403(Service 例外)Messages::AI_LLM_CLAUDE_AUTH_FAILED / AI_LLM_GEMINI_AUTH_FAILED
HTTP タイムアウト・経過上限(Service 例外)Messages::AI_LLM_CLAUDE_TIMEOUT / AI_LLM_GEMINI_TIMEOUT
接続失敗(WP_Error、タイムアウト以外)(Service 例外)Messages::AI_LLM_CLAUDE_CONNECTION_FAILED / AI_LLM_GEMINI_CONNECTION_FAILED
その他の HTTP 非 200(Service 例外)Messages::AI_LLM_CLAUDE_HTTP_ERROR / AI_LLM_GEMINI_HTTP_ERROR(ステータスコードのみ。例: …(HTTP 500)。)
応答切れ・履歴保存失敗・形式不正・ループ上限・セッション上限など対応する DailyArticleAiChatServiceCopy の固定文言(詳細は error_log)
上記以外の Service 例外DailyArticleAiChatAjaxCopy::NOTICE_GENERIC_ERROR(詳細は error_log)

上流 API のレスポンス本文や WP_Error の生メッセージは画面・JSON に載せない(Issue #3866)。ArticleAiLlmClient は ArticleAiLlmHttpErrorMode::ClientSafe で固定文言だけを例外に入れ、DailyArticleAiChatAjaxHandler は ArticleAiLlmClientErrorFilter で許可した文言以外を汎用文言に置き換える。上流の詳細は ExternalApiErrorLogFormatter の要約(HTTP ステータス・短い要約・ハッシュ)で error_log に残す。

権限 ​

  • ログイン必須(wp_ajax_ のみ。nopriv は付けない)
  • capability: edit_post(対象 post_id)

関連 ​

  • セッション削除: EP-028
  • セッション作成: EP-031
  • セッション読込: EP-032
  • LLM キー・プロバイダ: ADM-028
  • テーブル: db_daily_article_ai_chat_session / db_daily_article_ai_chat_message