少し前にChatGPTやGeminiのテキスト生成をStrapiのエディターから呼び出すプラグインを作って公開しました。
が、こちらで使ってるnpmのセキュリティアラートが飛んできたので、アプデついでにStrapi v4からv5にアップデートしました。加えて、最近appium周りの知識を少々得たのでこのプラグインのテストをappiumでやってみます。
プラグインはnpm i strapi-plugin-prompt-editorでインストールできます。
strapi-plugin-prompt-editorとは
StrapiのカスタムフィールドでOSSのblocknoteを追加し、インタラクティブに記事を生成することができます。prompt-editorという名称が今思えば非常にナンセンスが気がしますが、npmに公開してしまったのでこのままいきます・・。
イメージはこんな感じで、Notionライクなリッチエディター上に/でメニューを表示し、最上部にあるChatGPT/Geminiを選択するとテキストエリアがモワッと出てきます。gifだとなんか微妙ですね。
設定画面では今のところモデルなどの最低限のパラメータのみに対応しています。ちなみに設定はシステム全体ではなく、ユーザー1人ずつ個別です。
ストリーミングかどうか
前回の記事と繋がります。ChatGPTやGeminiといったLLMのAPIではストリーミングでレスポンスを逐次受け取るか、全ての結果をまとめて受け取るかの2択になります。
前回の記事では、レスポンスサイズが限られているので結果を全て受け取ってからUI側で見た目を調整していると書きました。一方、本プラグインではユーザーが入力するプロンプトによっては長文の結果になることが想定されるため、ストリーミングの方式を採用しました。
ただ、ストリーミングはSSE(Server-Sent Events)ではなく古来から伝わる'Transfer-Encoding': 'chunked'で実装。SSEだとGET限定&HTTPヘッダーを使えないという制約により、Authorizationに設定してるトークンをURLのクエリに含めるしかないのでは?という懸念が。管理画面の有効期限はデフォルトで30日なので、サーバーのアクセスログに残るのがたまらなく嫌なんですよね。こういう感覚はセキュリティ目線というより潔癖症に近いような気がします。
トークンがログに残っちゃう問題を避けるために一度だけ有効なワンタイムトークンみたいなのを生成してログイントークの代わりに使う方法が考えられますが、いまいちしっくりこないので一旦見送り。で、後から知ったんですがクライアント側でEventSourceのAPIを使わずfetchでごにょごにょすればHTTPヘッダー渡したりPOSTでもいけそう(非推奨のようですが)とのことで、この辺はまた別の機会でちゃんと検証してみようと思います。
appiumでe2eテスト
Strapiの管理画面でe2eテストをするのはなかなか厳しいものがあります。理由は、管理画面がstyled-componentsで実装されており、固定のidやclassはほとんど使われていないためです。
結論を言うと、なんとかログインからエディター入力&保存まで実行できたので動画でお見せします。
Chromeが立ち上がり何やら画面が動いていますが、私の方でマウスやキーボードをいじっているわけではなく下記のコードで操作しています。
strapi-plugin-prompt-editor/tests/e2e.js at main · yasudacloud/strapi-plugin-prompt-editor · GitHub
まるで一筆書きの如く一気に書いていますが、途中で期待の画面が出なかったりタイムアウトしたら例外でちゃんと落ちるので意外とこういう書き方が理にかなってる・・・といいんですがね( ´Д`)y━・~~
これをGitHub Actionsに組み込んでStrapiの新バージョンが出るたびに実行するようなことをしたかったんですが、利用者がいない段階でやることではないので保留。
strapi-plugin-ssoは利用者が割と多いみたいなので自動テスト入れたいんですが、GoogleとかAzureのOAuth画面は何らかの利用規約に抵触すると思います。ボット対策とかでプログラムによるアクセスを禁止しているはず。サービス固有のエラーや不具合もあるのでスタブにしてもあんまり意味がない可能性もあり、似たような機能作ってる方々はどうやってるんだろう。。
まとめ
StrapiConf2025によれば、年内にAI関連の機能がリリースされるようです。ただ、これも何らかの有料プランになるような印象があって現時点では何とも言えませんね。
appiumのドライバーやプラグインのコードを眺めてたんですが、結構面白いのでもう少しキャッチアップしてから掘り下げたいと思います。