チャットWebコンポーネント
WippyのチャットUIは合成可能なカスタム要素のセットとして提供されており、任意のマイクロフロントエンド(または子コンテキストで動作する任意のページ)が、タグを置くだけで稼働中のWippyチャットを組み込めます。Vueもimportも登録も不要です。これらは、ホスト自身のチャットが使っているのと同じコンポーネント(単一の真実の源)をラップし、同じ ChatTransport → SessionManager のデータレイヤーに支えられています。
これらは消費するための出来合いの要素です。自分で作るWebコンポーネントとは異なり、記述も登録も行いません。ホストがすべての子でタグとして利用可能にします(読み込みの仕組みを参照)。
自分のページやパネルの中にチャットのサーフェスを置きたいときにこれらを使用してください。代わりにホスト自身のチャットパネルを命令的に開くには、
@wippy-fe/proxyのhost.startChat(token)/host.openSession(sessionUUID)を使用します(プロキシAPIを参照)。
要素
| タグ | レンダリング内容 | 主な属性 | イベント |
|---|---|---|---|
<wippy-chat> |
完全なチャット — ヘッダー + メッセージ + 入力 | session-id, start-token, agent, show-selector, hide-header |
session-started, error |
<wippy-chat-messages> |
メッセージ一覧のみ | session-id |
— |
<wippy-chat-input> |
コンポーザーのみ | session-id |
— |
<wippy-session-selector> |
セッションピッカー | active-session-id |
select |
すべての要素は、インスタンスごとのテーマ属性 custom-css と css-variables も受け付けます。これらはテーマで扱います。
読み込みの仕組み
チャット要素は<wippy-loading>とまったく同じように配信されます。小さなシェルである @wippy-fe/chat.js(約21 KB)が4つのタグすべてを自動登録し、ホストの scripts 配列を介して(loading.js や proxy.js とともに)すべての子コンテキストに注入されます。そのため、これらのタグはアプリごとの登録なしで、どの子マイクロフロントエンドからでも名前で利用できます。パッケージのインストールも customElements.define() の呼び出しも不要です。
重い内部実装(VueツリーとPrimeVue、Shiki、markdownレンダラー、約2 MB)は別の chat-internals.[hash].js チャンクにコード分割され、最初のマウント時に遅延読み込みされます。チャンクのダウンロード中、要素は <wippy-loading> のプレースホルダーを表示します。読み込みに失敗した場合は <wippy-error> を表示します。チャットタグを一切使わないページが内部実装のコストを負うことはありません。
<wippy-chat>
リアクティブなセッション制御にはWeb Host 1.0.51 以降が必要です。対応する
@wippy-fe/* 0.0.51+ のパッケージファミリーをピン留めしてください。それより古い
注入済みチャット要素は、初回マウントしか確実にサポートしません。
チャットのサーフェス一式: ヘッダー、スクロール可能なメッセージ一覧、コンポーザー。
| 属性 | 型 | デフォルト | 説明 |
|---|---|---|---|
session-id |
string | — | この既存セッション(セッションUUID)をレンダリングする。 |
start-token |
string | — | エージェントのstart token。session-id が設定されていない場合、マウント時に新しいセッションを開始する。 |
agent |
string | — | セッションが開いていないときに表示される空状態で、あらかじめ選択するエージェント名(またはタイトル)。 |
show-selector |
boolean | false |
組み込みのセッションセレクタをヘッダーにレンダリングする。 |
hide-header |
boolean | false |
エージェント/モデルのヘッダーバーを隠す(コンパクトな埋め込み向け)。 |
イベント(要素上で CustomEvent としてディスパッチされます。event.detail を読んでください):
| イベント | detail |
発生タイミング |
|---|---|---|
session-started |
{ sessionId: string } |
セッションが開始されたとき。マウント時の start-token によるもの、またはユーザー操作によるもの。 |
error |
{ message: string } |
セッションの初期化に失敗したとき(例: 不正な start-token)。 |
<!-- エージェントのstart tokenから新しいセッションを開始 -->
<wippy-chat start-token="agent-start-token" agent="researcher"></wippy-chat>
<!-- 既存のセッションに固定 -->
<wippy-chat session-id="019eb2ae-1234-5678-abcd-ef1234567890"></wippy-chat>
<!-- 組み込みセレクタあり、ヘッダーバーなし -->
<wippy-chat show-selector hide-header></wippy-chat>
document.querySelector('wippy-chat')
.addEventListener('session-started', (e) => {
console.log('session:', e.detail.sessionId)
})
再マウントなしのリアクティブ制御
1つの <wippy-chat> 要素をマウントしたまま、その属性を更新します。session-id を
変更すると、その場でそのセッションが開きます。session-id="" を設定するか、
制御していた属性を削除することは、明示的な新規チャットへの遷移です。固定された
セッションと共有のアクティブセッションの両方をクリアします。一度も session-id を
持たなかった要素は、代わりにセレクタ駆動のままです。初回マウント時に属性がないことは
明確な指示ではありません。
start-token が存在する場合、session-id をクリアするとそのトークンから再び開始します。
トークンを変更した場合もその場で開始します。要素はカスタム要素ホストごとにトークンを
一度だけ消費するため、同じ要素を再接続したり移動したりしても、稼働中の開始が
再生されることはありません。実行中の開始処理が、より新しいトークン、制御されたセッション、
手動選択、切断によって取って代わられた場合、古い結果が現在のセッションを置き換えることは
できません。遅れて作成されたセッションは閉じられます。
const chat = document.querySelector('wippy-chat')
chat.setAttribute('session-id', existingSessionId)
// エージェント付きの新規チャット。要素の差し替えは不要。
chat.setAttribute('start-token', agentStartToken)
chat.removeAttribute('session-id')
マネージドレイアウトのコンポーネントリゾルバは、既存のカスタム要素上でpropsを
更新・削除します。再マウントするのは tagName が変わったときだけで、パネルの更新を
またいでチャット入力、スクロール位置、要素が所有するライフサイクル状態を保持します。
<wippy-chat-messages> と <wippy-chat-input>
メッセージ一覧とコンポーザーを別々の要素として提供するので、自分でレイアウトできます。それぞれ1つの session-id を取ります。明示的な session-id がない場合は、<wippy-session-selector> が設定する共有アクティブセッションに従います。どちらもイベントを発行しません。
<!-- カスタムレイアウト: 上にメッセージ、下にコンポーザー -->
<div style="display:flex; flex-direction:column; height:100%;">
<wippy-chat-messages session-id="019eb2ae-…"></wippy-chat-messages>
<wippy-chat-input session-id="019eb2ae-…"></wippy-chat-input>
</div>
<wippy-session-selector>
セッションピッカーです。他の要素が従う共有アクティブセッションを駆動します。
| 属性 | 型 | デフォルト | 説明 |
|---|---|---|---|
active-session-id |
string | — | このセッションをアクティブとしてハイライトする。 |
イベント:
| イベント | detail |
発生タイミング |
|---|---|---|
select |
{ sessionId: string } |
ユーザーがセッションを選んだとき。選ばれたセッションが共有アクティブセッションになる。 |
<wippy-session-selector></wippy-session-selector>
document.querySelector('wippy-session-selector')
.addEventListener('select', (e) => {
console.log('picked:', e.detail.sessionId)
})
合成と共有セッション
明示的な session-id を持たない要素は、マネージャーの共有 activeSessionId を介して <wippy-session-selector> の選択に従います。そのため、1つのページ上のセレクタとチャット(またはセレクタと分離したメッセージ + 入力)は同期を保ちます。セレクタでセッションを選ぶと、他が更新されます。明示的な session-id(または start-token)を持つ要素は固定され、セレクタを無視します。
<!-- セレクタ + チャット: チャットは選ばれたセッションに従う -->
<wippy-session-selector></wippy-session-selector>
<wippy-chat></wippy-chat>
<!-- セレクタ + 分割されたメッセージ一覧 / コンポーザー。すべてセレクタに従う -->
<wippy-session-selector></wippy-session-selector>
<wippy-chat-messages></wippy-chat-messages>
<wippy-chat-input></wippy-chat-input>
<!-- セレクタ駆動のものと並ぶ固定チャット -->
<wippy-chat session-id="019eb2ae-…"></wippy-chat> <!-- セレクタを無視 -->
<wippy-chat></wippy-chat> <!-- セレクタに従う -->
テーマ
各要素はshadow root内にレンダリングされるため、ホストページのスタイルは内外に漏れません。テーマの適用には2つのメカニズムがあります:
- 継承されるCSS変数。 テーマのカスタムプロパティ(
--p-primary-*、--p-text-colorなど)はホストのテーマからshadow境界を越えて継承されるため、チャットはアクティブなパレットとダーク/ライトモードを自動的に受け取ります。セレクタベースのスタイル(PrimeVue、markdown、Tailwind)はchat-elements.cssシートにバンドルされ、shadow rootに注入されます。PrimeVuePluginは、デフォルトのbody/nullのPortalターゲットを、所有するshadow root内に固定されたオーバーレイレイヤーへリダイレクトします。appendTo: 'self'を常用してはいけません。これは明示的なインライン配置のオプトインであり、スクロールするDialogやDrawerのコンテンツ内でクリップされることがあります。トーストはshadow内でレンダリングされるのではなく、プロキシ経由でホストのネイティブトーストに委譲されます。 - インスタンスごとのオーバーライド。 すべての要素が2つの属性を受け付けます:
| 属性 | 型 | 効果 |
|---|---|---|
custom-css |
string | 要素のshadow rootに最後に追加される生のCSS。順序により優先される。 |
css-variables |
object (JSON) | :host に適用されるインスタンスごとのCSS変数オーバーライド。キーは先頭の -- を省略できる。 |
<wippy-chat
session-id="019eb2ae-…"
custom-css=".message-item { max-width: 80%; }"
></wippy-chat>
css-variables を省略するのが、ファサードを尊重する通常の経路です。インスタンスごとの色のオーバーライドは、意図的な埋め込みの分離のためのものであり、日常的な再スタイリングのためのものではありません。
テーマモデル全体(セマンティック変数、ダーク/ライトの切り替え、ホストがshadow DOMにCSSを注入する方法)については、テーマ: Webコンポーネントを参照してください。
ランタイムの配線
Web Hostの子の内部では、これらの要素にセットアップは不要です。認証と設定は、ホストが既に注入しているプロキシのグローバル(window.__WIPPY_APP_CONFIG__ / window.__WIPPY_APP_API__)から得られます。RESTとWebSocketは設定内の環境URLを使用します。チャットタグをページに置くだけで十分です。シェルがそれを登録し、内部実装が遅延読み込みされ、チャットは子の既存セッションで接続します。
関連項目
- Webコンポーネント (
view.component) — 自分のカスタム要素を作る - @wippy-fe パッケージ — ホストのimport mapと注入される要素シェル(
@wippy-fe/chat、@wippy-fe/loading) - テーマ: Webコンポーネント — shadow DOMのCSSとセマンティック変数
- プロキシAPI —
host.startChat/host.openSessionと@wippy-fe/proxyのその他 - プロキシと分離 — ホストが子にスクリプトと設定を注入する方法