CopilotKit x ADK: セッションへの再接続
やりたいこと
フロントエンドから、時間がかかるエージェントを実行し、その後別のページを閲覧し、再度戻ってきたときにエージェントに再接続したい
これができれば、タブを閉じてもいいし、じっと待っていなくてもよくなる。
バージョン
frontend
@copilotkit/* 1.52.1
@ag-ui/client 0.0.42
backend
ag-ui-adk: 0.3.6
google-adk: 1.18.0
結論
結論としては、
useCopilotKit の copilotkit.connectAgent({ agent }) を使う
再接続したい threadId をセットした agent を渡す
実際にやってみる
CopilotKit (Next.js) と ADK のセットアップ をもとにセットアップ
agent/.env に GOOGLE_API_KEY の設定もする
エージェントの作成
agent/book_deep_research/ には、GitHub リポジトリのような deep_research エージェントを配置する
tamago324.icon 今ちょうど作っていたものをそのまま持ってきた。
今回はこれがメインではないため、コードは載せない
ADK と AG-UI の接続
agent/main.pyの編集
add_adk_fastapi_endpoint で追加する
これも載せない
フロントエンド
ページを作る
せっかくなので Streamdown を使った
各 state が存在するかどうかで、進捗を表示している
実際のコードは GitHub の方を見てもらうとして....
ポイント
1. useAgent() の agent.threadId を設定
今回は localStorage にしているけど、本来は DB から取得したものをセットする
2. useCopilotKit の copoilotkit.connectAgent で再接続
ag_ui_adk 側で、指定した threadId から ADK の sessionId を紐づけて、接続してくれる!
code:ts
const { agent } = useAgent({
agentId: "my_agent",
});
...
const { copilotkit } = useCopilotKit();
const isReconnecting, setIsReconnecting = useState(false);
// localStorage から thradId を取得し、再接続
useEffect(() => {
const threadId = localStorage.getItem("book_deep_research_thread_id");
if (!threadId) {
return;
}
setIsReconnecting(true);
const reconnect = async () => {
agent.threadId = threadId;
try {
await copilotkit.connectAgent({
agent,
});
} catch (error) {
console.error("エージェントの再接続に失敗しました:", error);
} finally {
setIsReconnecting(false);
}
};
void reconnect();
}, agent, copilotkit);
この実装は、 CopilotChat の実装を参考にしている
https://github.com/CopilotKit/CopilotKit/blob/740d21a0aa6103f3acd2d2fed328671b30760eb3/packages/v2/react/src/components/chat/CopilotChat.tsx#L86-L101
https://scrapbox.io/files/69a449b2f1c53c17321ce285.mp4
MEMO
tamago324.icon ADK での Session は、CopilotKit での Thread の概念と同じものを指している。
扱う単位としては同じになっている。
ADK を使う場合は、ag_ui_adk のミドルウェアが threadId と sessionId を変換してくれているため、ADK 側では sessionId として扱えるようになっている
コード
https://github.com/tamago324/sandbox-adk-session-reconnect-0301
#adk #copilotkit