What Can You Build?
Connect Kit gets a talking 3D avatar on screen in under 15 minutes — and gives you a full platform to extend it as far as you need. Here is what is available today and what is on the roadmap.
Everything you need for a lifelike avatar experience — ready to deploy the moment you pick your configuration.
Avatar Catalog
Curated cast of realistic humans, cartoon characters, and VRM avatars. Pick one from the catalog and it's on-screen in minutes.
Voice — Azure & Google TTS
Rich, human-sounding voices from Azure and Google TTS. Speech automatically drives the avatar's lip-sync — no extra setup required.
Chatbot
Upload a knowledge file, wire simple tool calls, and pair with the 3D Avatar for a fully voiced AI agent — no extra backend required.
Built to Run Everywhere
Focus on building your product — we handle the rest. All features run reliably on Chrome, Safari, and Edge across desktop and mobile with no platform workarounds needed.
Bring Your Own LLM
Use any LLM. Embed motion cues inline via Markup Motion Language so the avatar's body language matches the conversation.
Bring Your Own Voice
Pass your own audio (an ArrayBuffer from any
TTS service or pre-recorded clip) directly via
presenter.presentWithAudio(). The avatar
lip-syncs to your audio and the Motion Director still
drives gestures and expressions from the text — no Perxona
TTS required.
Bring Your Own Avatar (VRM 1.0)
Upload a VRM 1.0 character to match your brand or audience and make it speak.
Real-time avatar performances that stream instantly — no large
file downloads, no video buffering, no game-engine install.
The avatar responds the moment you call
present().
In-house Motion Director
The engine reads the text and selects matching body motion and facial expressions automatically — the avatar's face and body react to what it's saying.
Be your own Motion Director
Override motion timing at the sentence level using Markup Motion Language — full creative control in plain text.
// Presentation Engine — available now
const presenter = document.querySelector("sv-presenter");
button.addEventListener("click", async () => {
await presenter.resumeAudioPlayback();
await presenter.initialize(connectToken, { avatarId, sceneId, voiceId });
presenter.present("Hello world! I'm Perxona agent and I can talk to you.");
});
你能用 Connect Kit 做什麼?
不到 15 分鐘,一個會說話的 3D 虛擬人就能上線——還有完整的平台供你持續擴展。以下是現在可用的功能,以及即將推出的能力。
打造生動虛擬人體驗所需的一切——選好設定,立即上線。
Avatar 目錄
精選的寫實人物、卡通風格、VRM 角色,從目錄挑選一個,幾分鐘內就在螢幕上。
語音 — Azure & Google TTS
來自 Azure 與 Google TTS 的豐富真人語音。語音自動驅動角色的口型同步(Lip-sync)——無需額外設定。
Chatbot
上傳 knowledge file、設定簡單的 tool call,搭配 3D Avatar 打造全語音 AI 代理——不需要自建後端。
隨處穩定運作
你只需專注在打造自己的產品,其餘的我們來處理。所有功能穩定運作在 Chrome、Safari、Edge 的桌機與手機上,無需任何平台相容性處理。
接入你的 LLM
使用任何 LLM。透過 Markup Motion Language 在對話文字中內嵌動作指令,讓角色肢體語言與對話同步。
接入你的語音
透過
presenter.presentWithAudio()
直接傳入自己的音訊(任何 TTS 服務或預錄音檔的
ArrayBuffer)。 Avatar 對你的音訊做
口型同步,Motion Director
仍根據文字驅動肢體動作與表情——不需要 Perxona TTS。
接入你的 Avatar(VRM 1.0)
上傳 VRM 1.0 角色,讓你的產品更貼近你的品牌與客戶需求。
即時串流的角色表演——不用像影片串流或遊戲引擎一樣事先下載大型檔案。呼叫
present() 的瞬間,角色立即回應。
內建 Motion Director
引擎讀取文字語意,自動挑選最合適的肢體動作與臉部表情——角色的表情和動作會配合說話內容即時反應。
自訂 Motion Director
透過 Markup Motion Language 在句子層級自訂動作時間點——用純文字就能完全掌控角色表演。
// 表演引擎 — 現在就可以用
const presenter = document.querySelector("sv-presenter");
button.addEventListener("click", async () => {
await presenter.resumeAudioPlayback();
await presenter.initialize(connectToken, { avatarId, sceneId, voiceId });
presenter.present("我想要吃早餐。");
});
Connect Kit で何が作れる?
15 分以内にしゃべる 3D アバターをオンラインにできます——さらに必要なだけ拡張できるプラットフォームも揃っています。現在利用可能な機能と近日公開予定の機能をご紹介します。
リアルなアバター体験に必要なすべてが揃っています——設定を選ぶだけですぐにデプロイできます。
アバターカタログ
リアル系・カートゥーン系・VRM キャラの厳選キャスト。カタログから選ぶだけで数分で画面に登場します。
音声 — Azure & Google TTS
Azure と Google TTS のリアルな人声。音声がアバターのリップシンクを自動駆動——追加設定は不要です。
チャットボット
ナレッジファイルをアップロードし、シンプルなツールコールを設定して 3D アバターと組み合わせると、フルボイスの AI エージェントが完成——バックエンド不要。
どこでも安定動作
開発者は自分のプロダクト作りに集中するだけ。すべての機能が Chrome・Safari・Edge のデスクトップ/モバイルで安定して動作し、プラットフォームごとの対応は不要です。
独自 LLM を接続
任意の LLM が使えます。Markup Motion Language でモーションキューをテキスト中に埋め込み、会話とアバターの動きを同期させます。
独自音声を使用
presenter.presentWithAudio() に任意の TTS
サービスや録音済み音声の
ArrayBuffer
を直接渡すだけ。アバターがリップシンクし、 Motion Director
がテキストから動きと表情を自動生成します——Perxona TTS
は不要です。
独自アバター(VRM 1.0)
VRM 1.0 キャラをアップロードして、ブランドや顧客に合ったアバターで話させることができます。
リアルタイムのアバターパフォーマンスを即座にストリーミング——動画バッファリングもゲームエンジンのインストールも不要。present()
を呼んだ瞬間にアバターが応答します。
インハウス Motion Director
エンジンがテキストの意味を読み取り、最適なボディモーションと表情を自動選択——アバターの顔と体が発話内容に合わせてリアルタイムに反応します。
カスタム Motion Director
Markup Motion Language を使って文単位でモーションのタイミングを制御——プレーンテキストで完全な演出が可能です。
// プレゼンテーションエンジン — 今すぐ使えます
const presenter = document.querySelector("sv-presenter");
button.addEventListener("click", async () => {
await presenter.resumeAudioPlayback();
await presenter.initialize(connectToken, { avatarId, sceneId, voiceId });
presenter.present("朝ごはんが食べたいです。");
});
Perxona Connect Kit
Build AI-powered avatars in minutes.
A minimal, self-contained sample that integrates the
Perxona Connect API and the
<sv-presenter> avatar Web Component. Pick
an avatar, scene, and voice — make it speak. Clone to talking
avatar in 5–15 minutes.
整合 Perxona Connect API 與
<sv-presenter> 虛擬人 Web Component
的輕量範例。選擇 Avatar、場景與聲音,讓虛擬人開口說話。從
clone 到說話的虛擬人,只需 5–15 分鐘。
Perxona Connect API と
<sv-presenter> アバター Web
コンポーネントを統合した軽量サンプルです。アバター・シーン・ボイスを選んでしゃべらせましょう。クローンからしゃべるアバターまで
5〜15 分で完成します。
What is Perxona Connect Kit?
The Connect Kit is a ready-to-run Express + vanilla JS sample
app that demonstrates the end-to-end integration of the
Perxona Presentation Service (Connect API) and
the
<sv-presenter> Web Component. It is built for hackathons and partner integrations — fast to
clone, easy to read, and designed as a starting point rather
than a production-ready app.
There are two moving parts:
-
server.mjs— an Express backend that authenticates with the Connect API using your service credentials, caches a bearer token, and exposes a small proxy API for the browser. -
public/demos/basic/app.js— a zero-dependency vanilla JS frontend that drives the<sv-presenter>Web Component loaded from Perxona's CDN.
什麼是 Perxona Connect Kit?
Connect Kit 是一個可立即執行的 Express + 原生 JS
範例應用程式,展示了
Perxona Presentation Service(Connect API)與
<sv-presenter> Web Component
的完整端到端整合流程。專為黑客松與合作夥伴整合設計——快速
clone、易於閱讀,是起點而非生產就緒應用程式。
Avatar 指的是同一個角色資源。為了與
Avatar 下拉選單、API 欄位及程式碼保持一致,這些技術名稱會維持
英文 Avatar。
主要有兩個部分:
-
server.mjs— 使用服務憑證向 Connect API 進行身份驗證的 Express 後端,快取 Bearer Token,並為瀏覽器公開小型代理 API。 -
public/demos/basic/app.js— 驅動從 Perxona CDN 載入的<sv-presenter>Web Component 的零依賴原生 JS 前端。
Perxona Connect Kit とは?
Connect Kit は、Perxona Presentation Service(Connect API)と
<sv-presenter> Web コンポーネントのエンドツーエンド統合を示す、すぐに動かせる Express + バニラ
JS
サンプルアプリです。ハッカソンやパートナー統合向けに設計されており、素早くクローンでき、コードが読みやすく、出発点として使うことを想定しています。
主な構成要素は 2 つです:
-
server.mjs— サービス認証情報で Connect API に認証し、Bearer トークンをキャッシュして、ブラウザ向けプロキシ API を提供する Express バックエンド。 -
public/demos/basic/app.js— Perxona の CDN から読み込まれた<sv-presenter>Web コンポーネントを操作するゼロ依存のバニラ JS フロントエンド。
Get Your API Credentials
Before you can run the Connect Kit sample, you need a Perxona account. Registration is fully self-service — no approval or invite required. The three steps below take about two minutes.
-
Request a signup token
Send your email address to the signup endpoint. The server returns
201with no body and sends a plain-text token to your inbox.curl -X POST https://console.perxona.ai/asia/api/v1/connect/auth/signup \ -H "Content-Type: application/json" \ -d '{"email": "you@example.com"}' -
Check your email and copy the token
Open the email from Perxona. It contains a short token string — not a clickable link. Copy the token; you will paste it in the next step.
-
Complete signup and set your password
Pass the token, your email (used as
username), and a password you choose. A successful response returns youraccess_token.curl -X POST https://console.perxona.ai/asia/api/v1/connect/auth/confirm-signup \ -H "Content-Type: application/json" \ -d '{ "token": "YOUR_TOKEN_FROM_EMAIL", "username": "you@example.com", "password": "YourPassword123!" }'Response:
{"access_token": "eyJ..."}. Your account is now active.
PERXONA_CONNECT_EMAIL and
PERXONA_CONNECT_PASSWORD in your
.env — the sample server handles all subsequent
logins for you.
取得 API 憑證
在執行 Connect Kit 範例之前,你需要一個 Perxona 帳號。註冊完全自助——無需審核或邀請碼,以下三個步驟約需兩分鐘。
-
請求 signup token
將你的 email 傳送至 signup 端點。伺服器回傳
201(無回應內容),並將 純文字 token 寄至你的信箱。curl -X POST https://console.perxona.ai/asia/api/v1/connect/auth/signup \ -H "Content-Type: application/json" \ -d '{"email": "you@example.com"}' -
收信並複製 token
開啟來自 Perxona 的信件。信中有一段短字串 token—— 不是可點擊的連結。複製這段 token,下一步會用到。
-
完成註冊並設定密碼
傳入 token、你的 email(作為
username)以及你設定的密碼。 成功後回傳access_token,帳號即啟用。curl -X POST https://console.perxona.ai/asia/api/v1/connect/auth/confirm-signup \ -H "Content-Type: application/json" \ -d '{ "token": "YOUR_TOKEN_FROM_EMAIL", "username": "you@example.com", "password": "YourPassword123!" }'回應:
{"access_token": "eyJ..."}。帳號已啟用。
API 認証情報を取得
Connect Kit サンプルを実行する前に、Perxona アカウントが必要です。登録は完全セルフサービス——承認や招待コードは不要です。以下の 3 ステップで約 2 分で完了します。
-
サインアップトークンをリクエスト
メールアドレスをサインアップエンドポイントに送信します。サーバーは
201(本文なし)を返し、受信トレイに プレーンテキストのトークンを送信します。curl -X POST https://console.perxona.ai/asia/api/v1/connect/auth/signup \ -H "Content-Type: application/json" \ -d '{"email": "you@example.com"}' -
メールを確認してトークンをコピー
Perxona からのメールを開いてください。クリック可能なリンクでは なく、短いトークン文字列が記載されています。 次のステップで使用するのでコピーしてください。
-
サインアップを完了してパスワードを設定
トークン、メールアドレス(
usernameとして使用)、 設定するパスワードを送信します。成功するとaccess_tokenが返されアカウントが有効になります。curl -X POST https://console.perxona.ai/asia/api/v1/connect/auth/confirm-signup \ -H "Content-Type: application/json" \ -d '{ "token": "YOUR_TOKEN_FROM_EMAIL", "username": "you@example.com", "password": "YourPassword123!" }'レスポンス:
{"access_token": "eyJ..."}。アカウントが有効になりました。
PERXONA_CONNECT_EMAIL と
PERXONA_CONNECT_PASSWORD を
.env
に入力してください——サンプルサーバーがその後のログインを自動で処理します。
How It Works
Architecture
Both demos share the same three-layer foundation.
<sv-presenter> is the innermost component —
the CDN Web Component that handles all speech, motion, and
lip-sync directly via the Connect API. The demos wrap it with
different application layers depending on the use case.
Basic Demo
A single-page avatar presenter. The app provides catalog UI and
a text input, then initializes
<sv-presenter> with a Connect token — all
rendering, synthesis, and playback happen inside the component.
┌─ Browser ─────────────────────────────────────────────────────┐
│ ┌─ demos/basic/app.js ──────────────────────────────────┐ │
│ │ Catalog pickers · Launch button · Text / audio input │ │
│ │ │ │
│ │ ┌─ <sv-presenter> (Web Component, CDN) ──────────┐ │ │
│ │ │ Audio synthesis · Motion playback │ │ │
│ │ │ Lip-sync rendering · Token auto-refresh │ │ │
│ │ └─────────────────────────────────────────────────┘ │ │
│ └───────────────────────────────────────────────────────┘ │
└───────────────────────────────────────────────────────────────┘
│ /api/* (proxy) │ direct (bearer token)
▼ ▼
┌─ server.mjs ────────────┐ ┌─ Connect API ─────────────┐
│ /api/config │ │ /assets (catalog) │
│ /api/connect-token │────►│ /presentation │
│ /api/avatars │ │ /voice-tokens/tts │
│ /api/scenes │ └───────────────────────────┘
│ /api/voices │
│ /api/chat (opt-in) │
└─────────────────────────┘
Browser (app.js) server.mjs Connect API
│ │ │
1. ├─ GET /api/config ───►│ │
│◄─ presenterUrl ──────┤ │
2. ├─ load <script> from presenterUrl (CDN) │
│ │ │
3. ├─ GET /api/avatars ──►│ │
├─ GET /api/scenes ───►│ │
├─ GET /api/voices ───►│ │
│◄─ catalog items ─────┤ │
4. ├─ GET /api/connect-token ────────────────────────────►│
│◄─ connect_token ─────────────────────────────────────┤
5. ├─ presenter.initialize(token, { avatarId, ... }) ────►│
│◄─ PRESENTER_STATUS: Ready ───────────────────────────┤
6. ├─ presenter.present("Hello!") ───────────────────────►│
│◄─ avatar speaks ─────────────────────────────────────┤
Chatbot Demo
Adds a full chatbot layer on top of Basic. A Chatbot Manager
handles bot CRUD, knowledge files, and function tools. The Chat
Panel drives multi-turn conversations — each AI reply is piped
straight into <sv-presenter> for live speech.
┌─ Browser ───────────────────────────────────────────────────────┐
│ ┌─ demos/chatbot/app.js ───────────────────────────────────┐ │
│ │ ┌─ Chatbot Manager ────┐ ┌─ Avatar Stage ─────────┐ │ │
│ │ │ Bot picker (CRUD) │ │ ┌─ <sv-presenter> ─┐ │ │ │
│ │ │ Knowledge upload │ │ │ (CDN Component) │ │ │ │
│ │ │ Function tools │ │ │ initialize() │ │ │ │
│ │ └──────────────────────┘ │ │ present(reply) │ │ │ │
│ │ │ └──────────────────┘ │ │ │
│ │ ┌─ Chat Panel ─────────┐ └────────────────────────┘ │ │
│ │ │ Multi-turn history │ │ │
│ │ │ User → AI reply │ │ │
│ │ └──────────────────────┘ │ │
│ └──────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
│ /api/* (proxy) │ direct (bearer token)
▼ ▼
┌─ server.mjs ───────────────────┐ ┌─ Connect API ──────────────┐
│ /api/chatbots (CRUD) │ │ /chatbots │
│ /api/chatbots/:id/chat │─►│ /chatbots/:id/chat │
│ /api/chatbots/:id/knowledge │ │ /assets · /presentation │
│ /api/connect-token │ └────────────────────────────┘
└────────────────────────────────┘
Browser (app.js) server.mjs Connect API
│ │ │
1-4. ├─ [config → catalog → connect-token → presenter.initialize()]
│ │ │
5. ├─ POST /api/chatbots ──────────────────►│ create bot
│◄─ { id, name, status } ────────────────┤
6. ├─ POST /api/chatbots/:id/knowledge ────►│ upload file
│◄─ { knowledge: { status } } ───────────┤
7. ├─ POST /api/chatbots/:id/chat ─────────►│
│ { messages: [{ role, parts }] } │ AI response
│◄─ { reply_text } ──────────────────────┤
8. ├─ presenter.present(reply_text) ───────►│
│◄─ avatar speaks ───────────────────────┤
Auth Model
.env service
account). Fine for demos and hackathons — not a production
multi-tenant design.
-
The server reads
PERXONA_CONNECT_EMAIL/PERXONA_CONNECT_PASSWORDfrom.env. - On the first request to a protected route, the server logs in and caches the bearer token in memory.
-
The browser calls
GET /api/connect-token— the server validates and returns the cached token. -
The browser passes the token into
presenter.initialize(connectToken, { avatarId, sceneId, voiceId }). -
From that point,
<sv-presenter>talks to the Connect API directly — speech and motion are handled by the component, not the server. -
If the cached token expires (
401/403from upstream), the server re-logs in and retries once — transparent to the browser.
運作原理
架構
兩個 Demo 共用相同的三層基礎。
<sv-presenter>
是最內層的核心元件——一個 CDN Web Component,直接透過 Connect API
處理語音、動作與口型同步。Demo 以不同的應用層包裝它。
Basic Demo
單頁式虛擬人 presenter。應用程式提供 catalog UI
與文字輸入框,然後以 Connect token 初始化
<sv-presenter>——所有渲染、合成與播放都在元件內部完成。
┌─ Browser ─────────────────────────────────────────────────────┐
│ ┌─ demos/basic/app.js ──────────────────────────────────┐ │
│ │ Catalog pickers · Launch button · Text / audio input │ │
│ │ │ │
│ │ ┌─ <sv-presenter> (Web Component, CDN) ──────────┐ │ │
│ │ │ Audio synthesis · Motion playback │ │ │
│ │ │ Lip-sync rendering · Token auto-refresh │ │ │
│ │ └─────────────────────────────────────────────────┘ │ │
│ └───────────────────────────────────────────────────────┘ │
└───────────────────────────────────────────────────────────────┘
│ /api/* (proxy) │ direct (bearer token)
▼ ▼
┌─ server.mjs ────────────┐ ┌─ Connect API ─────────────┐
│ /api/config │ │ /assets (catalog) │
│ /api/connect-token │────►│ /presentation │
│ /api/avatars │ │ /voice-tokens/tts │
│ /api/scenes │ └───────────────────────────┘
│ /api/voices │
│ /api/chat (opt-in) │
└─────────────────────────┘
Browser (app.js) server.mjs Connect API
│ │ │
1. ├─ GET /api/config ───►│ │
│◄─ presenterUrl ──────┤ │
2. ├─ load <script> from presenterUrl (CDN) │
│ │ │
3. ├─ GET /api/avatars ──►│ │
├─ GET /api/scenes ───►│ │
├─ GET /api/voices ───►│ │
│◄─ catalog items ─────┤ │
4. ├─ GET /api/connect-token ────────────────────────────►│
│◄─ connect_token ─────────────────────────────────────┤
5. ├─ presenter.initialize(token, { avatarId, ... }) ────►│
│◄─ PRESENTER_STATUS: Ready ───────────────────────────┤
6. ├─ presenter.present("Hello!") ───────────────────────►│
│◄─ avatar speaks ─────────────────────────────────────┤
Chatbot Demo
在 Basic 之上新增完整的 chatbot 層。Chatbot Manager 處理 bot
CRUD、knowledge file 與 function tools。Chat Panel
驅動多輪對話——每個 AI 回覆直接串接至
<sv-presenter> 即時發話。
┌─ Browser ───────────────────────────────────────────────────────┐
│ ┌─ demos/chatbot/app.js ───────────────────────────────────┐ │
│ │ ┌─ Chatbot Manager ────┐ ┌─ Avatar Stage ─────────┐ │ │
│ │ │ Bot picker (CRUD) │ │ ┌─ <sv-presenter> ─┐ │ │ │
│ │ │ Knowledge upload │ │ │ (CDN Component) │ │ │ │
│ │ │ Function tools │ │ │ initialize() │ │ │ │
│ │ └──────────────────────┘ │ │ present(reply) │ │ │ │
│ │ │ └──────────────────┘ │ │ │
│ │ ┌─ Chat Panel ─────────┐ └────────────────────────┘ │ │
│ │ │ Multi-turn history │ │ │
│ │ │ User → AI reply │ │ │
│ │ └──────────────────────┘ │ │
│ └──────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
│ /api/* (proxy) │ direct (bearer token)
▼ ▼
┌─ server.mjs ───────────────────┐ ┌─ Connect API ──────────────┐
│ /api/chatbots (CRUD) │ │ /chatbots │
│ /api/chatbots/:id/chat │─►│ /chatbots/:id/chat │
│ /api/chatbots/:id/knowledge │ │ /assets · /presentation │
│ /api/connect-token │ └────────────────────────────┘
└────────────────────────────────┘
Browser (app.js) server.mjs Connect API
│ │ │
1-4. ├─ [config → catalog → connect-token → presenter.initialize()]
│ │ │
5. ├─ POST /api/chatbots ──────────────────►│ create bot
│◄─ { id, name, status } ────────────────┤
6. ├─ POST /api/chatbots/:id/knowledge ────►│ upload file
│◄─ { knowledge: { status } } ───────────┤
7. ├─ POST /api/chatbots/:id/chat ─────────►│
│ { messages: [{ role, parts }] } │ AI response
│◄─ { reply_text } ──────────────────────┤
8. ├─ presenter.present(reply_text) ───────►│
│◄─ avatar speaks ───────────────────────┤
驗證模型
.env
的服務帳號)。適合 Demo 和黑客松——不適合生產環境的多租戶設計。
-
伺服器從
.env讀取PERXONA_CONNECT_EMAIL/PERXONA_CONNECT_PASSWORD。 - 在第一次請求受保護路由時,伺服器登入並將 Bearer Token 快取在記憶體中。
-
瀏覽器呼叫
GET /api/connect-token——伺服器驗證並回傳快取的 token。 -
瀏覽器將 token 傳入
presenter.initialize(connectToken, { avatarId, sceneId, voiceId })。 -
從此時起,
<sv-presenter>直接與 Connect API 通訊——語音和動作由元件處理,而非伺服器。 -
若快取的 token 過期(來自上游的
401/403),伺服器會重新登入並重試一次——對瀏覽器透明。
仕組み
アーキテクチャ
両方のデモは同じ 3 層構成を共有しています。
<sv-presenter>
は最内層のコアコンポーネント —— Connect API
を通じて音声・モーション・リップシンクを直接処理する CDN Web
コンポーネントです。デモは用途に応じて異なるアプリケーション層でラップします。
Basic Demo
単一ページのアバター Presenter。アプリはカタログ UI
とテキスト入力を提供し、Connect トークンで
<sv-presenter>
を初期化します——レンダリング・合成・再生はすべてコンポーネント内で行われます。
┌─ Browser ─────────────────────────────────────────────────────┐
│ ┌─ demos/basic/app.js ──────────────────────────────────┐ │
│ │ Catalog pickers · Launch button · Text / audio input │ │
│ │ │ │
│ │ ┌─ <sv-presenter> (Web Component, CDN) ──────────┐ │ │
│ │ │ Audio synthesis · Motion playback │ │ │
│ │ │ Lip-sync rendering · Token auto-refresh │ │ │
│ │ └─────────────────────────────────────────────────┘ │ │
│ └───────────────────────────────────────────────────────┘ │
└───────────────────────────────────────────────────────────────┘
│ /api/* (proxy) │ direct (bearer token)
▼ ▼
┌─ server.mjs ────────────┐ ┌─ Connect API ─────────────┐
│ /api/config │ │ /assets (catalog) │
│ /api/connect-token │────►│ /presentation │
│ /api/avatars │ │ /voice-tokens/tts │
│ /api/scenes │ └───────────────────────────┘
│ /api/voices │
│ /api/chat (opt-in) │
└─────────────────────────┘
Browser (app.js) server.mjs Connect API
│ │ │
1. ├─ GET /api/config ───►│ │
│◄─ presenterUrl ──────┤ │
2. ├─ load <script> from presenterUrl (CDN) │
│ │ │
3. ├─ GET /api/avatars ──►│ │
├─ GET /api/scenes ───►│ │
├─ GET /api/voices ───►│ │
│◄─ catalog items ─────┤ │
4. ├─ GET /api/connect-token ────────────────────────────►│
│◄─ connect_token ─────────────────────────────────────┤
5. ├─ presenter.initialize(token, { avatarId, ... }) ────►│
│◄─ PRESENTER_STATUS: Ready ───────────────────────────┤
6. ├─ presenter.present("Hello!") ───────────────────────►│
│◄─ avatar speaks ─────────────────────────────────────┤
Chatbot Demo
Basic の上に完全なチャットボット層を追加します。Chatbot Manager
がボットの
CRUD・ナレッジファイル・ファンクションツールを処理します。Chat
Panel がマルチターン会話を駆動し、各 AI の返答は直接
<sv-presenter>
に渡されてライブで発話されます。
┌─ Browser ───────────────────────────────────────────────────────┐
│ ┌─ demos/chatbot/app.js ───────────────────────────────────┐ │
│ │ ┌─ Chatbot Manager ────┐ ┌─ Avatar Stage ─────────┐ │ │
│ │ │ Bot picker (CRUD) │ │ ┌─ <sv-presenter> ─┐ │ │ │
│ │ │ Knowledge upload │ │ │ (CDN Component) │ │ │ │
│ │ │ Function tools │ │ │ initialize() │ │ │ │
│ │ └──────────────────────┘ │ │ present(reply) │ │ │ │
│ │ │ └──────────────────┘ │ │ │
│ │ ┌─ Chat Panel ─────────┐ └────────────────────────┘ │ │
│ │ │ Multi-turn history │ │ │
│ │ │ User → AI reply │ │ │
│ │ └──────────────────────┘ │ │
│ └──────────────────────────────────────────────────────────┘ │
└─────────────────────────────────────────────────────────────────┘
│ /api/* (proxy) │ direct (bearer token)
▼ ▼
┌─ server.mjs ───────────────────┐ ┌─ Connect API ──────────────┐
│ /api/chatbots (CRUD) │ │ /chatbots │
│ /api/chatbots/:id/chat │─►│ /chatbots/:id/chat │
│ /api/chatbots/:id/knowledge │ │ /assets · /presentation │
│ /api/connect-token │ └────────────────────────────┘
└────────────────────────────────┘
Browser (app.js) server.mjs Connect API
│ │ │
1-4. ├─ [config → catalog → connect-token → presenter.initialize()]
│ │ │
5. ├─ POST /api/chatbots ──────────────────►│ create bot
│◄─ { id, name, status } ────────────────┤
6. ├─ POST /api/chatbots/:id/knowledge ────►│ upload file
│◄─ { knowledge: { status } } ───────────┤
7. ├─ POST /api/chatbots/:id/chat ─────────►│
│ { messages: [{ role, parts }] } │ AI response
│◄─ { reply_text } ──────────────────────┤
8. ├─ presenter.present(reply_text) ───────►│
│◄─ avatar speaks ───────────────────────┤
認証モデル
.env
のサービスアカウント)を共有します。デモやハッカソンには適していますが、本番のマルチテナント設計には不向きです。
-
サーバーが
.envからPERXONA_CONNECT_EMAIL/PERXONA_CONNECT_PASSWORDを読み込みます。 - 保護されたルートへの最初のリクエスト時、サーバーはログインしてメモリに Bearer トークンをキャッシュします。
-
ブラウザが
GET /api/connect-tokenを呼び出し、サーバーはキャッシュしたトークンを検証して返します。 -
ブラウザがトークンを
presenter.initialize(connectToken, { avatarId, sceneId, voiceId })に渡します。 -
その後、
<sv-presenter>は Connect API と直接通信します——音声とモーションはコンポーネントが処理し、サーバーは関与しません。 -
キャッシュしたトークンが期限切れ(上流から
401/403)の場合、サーバーは再ログインして 1 回リトライします——ブラウザには透過的です。
Configuration
All configuration lives in .env. Copy
.env.example → .env and fill in your
values. Never commit .env — it is
in .gitignore.
設定
所有設定透過 .env 進行。將
.env.example 複製為
.env 並填入你的值。絕對不要提交 .env——它已在 .gitignore 中。
設定
すべての設定は .env で行います。.env.example
を .env にコピーして値を入力してください。.env は絶対にコミットしないでください——.gitignore に含まれています。
| Variable | Required必填必須 | Default預設值デフォルト | Description說明説明 |
|---|---|---|---|
PERXONA_API_BASE_URL |
✅ | — | Region-specific Connect API base URL. Ask your Perxona contact. 區域專屬的 Connect API 基底 URL。向 Perxona 聯絡人取得。 地域別の Connect API ベース URL。Perxona 担当者に確認してください。 |
PERXONA_CONNECT_EMAIL |
✅ | — | Service account email. The server signs in with this. 服務帳號 Email。伺服器以此登入。 サービスアカウントのメールアドレス。サーバーがこれでログインします。 |
PERXONA_CONNECT_PASSWORD |
✅ | — | Service account password. 服務帳號密碼。 サービスアカウントのパスワード。 |
PORT |
— | 8083 |
Port the server listens on. 伺服器監聽的連接埠。 サーバーがリッスンするポート。 |
PRESENTER_URL |
— | cdn.perxona.ai/…/presenter.js |
Presenter engine CDN URL. Override only if your Perxona contact provides a specific URL. Presenter 引擎 CDN URL。僅在 Perxona 聯絡人提供特定 URL 時覆蓋。 Presenter エンジンの CDN URL。Perxona 担当者から特定の URL が提供された場合のみ上書きしてください。 |
LLM_API_KEY |
— | — |
Set to enable the chat panel. Any OpenAI-compatible key
works, including local Ollama via
LLM_BASE_URL.
設定以啟用聊天面板。支援任何 OpenAI 相容金鑰,包括透過
LLM_BASE_URL 的本地 Ollama。
チャットパネルを有効にするために設定します。LLM_BASE_URL
経由のローカル Ollama を含む OpenAI
互換のキーが使えます。
|
LLM_BASE_URL |
— | https://api.openai.com/v1 |
LLM endpoint URL (override for Ollama or other providers). LLM 端點 URL(Ollama 或其他供應商時覆蓋)。 LLM エンドポイント URL(Ollama 等に上書き)。 |
LLM_MODEL |
— | gpt-4o-mini |
LLM model name passed to the chat endpoint. 傳遞給聊天端點的 LLM 模型名稱。 チャットエンドポイントに渡す LLM モデル名。 |
Quick Start
The sample app is a single Node/Express server that serves two
runnable browser demos, both built on the same
<sv-presenter> integration:
Presenter — the Basic demo: browse the avatar
catalog, launch the presenter, and drive speech (with optional
LLM chat); and Chatbot — full chatbot CRUD, a
persistent multi-turn conversation, and knowledge files plus
function tools. Run the server once, then open either demo. The
steps below get you from clone to a talking avatar.
>=22 and Perxona service
account credentials.
-
Clone the sample
git clone https://github.com/XRSPACE-Inc/perxona-connect-kit.git cd perxona-connect-kit -
Create your local config
cp .env.example .envOpen
.envand fill in the three required values:PERXONA_API_BASE_URL=https://console.perxona.ai/asia PERXONA_CONNECT_EMAIL=your@email.com PERXONA_CONNECT_PASSWORD=your-password -
Install dependencies
npm installRequires Node
>=22. If your Node is too old,npm installrefuses with a clear upgrade message. -
Start the server
npm run dev # with live reload (node --watch) # or npm start # without watchThe terminal prints the local URL, e.g.
http://localhost:8083. -
Launch the avatar
Open the URL in your browser. The landing page offers two demos — Basic and Chatbot — each highlighting a different set of product capabilities. Open either demo, pick an Avatar, Scene, and Voice, then click Launch. The avatar appears and speaks.
快速開始
範例應用是一個單一的 Node/Express 伺服器,提供兩個可執行的
browser demo,都建立在相同的
<sv-presenter> 整合之上:
Presenter——Basic demo:瀏覽 avatar
catalog、啟動 presenter 並驅動語音(可選搭配 LLM chat);以及
Chatbot——完整的 chatbot
CRUD、持久多輪對話,以及 knowledge file 與 function
tools。伺服器只需啟動一次,即可開啟任一 demo。以下步驟帶你從
clone 到說話的虛擬人。
>=22 與 Perxona
服務帳號憑證。
-
Clone 範例
git clone https://github.com/XRSPACE-Inc/perxona-connect-kit.git cd perxona-connect-kit -
建立本機設定檔
cp .env.example .env開啟
.env並填入三個必填值:PERXONA_API_BASE_URL=https://console.perxona.ai/asia PERXONA_CONNECT_EMAIL=your@email.com PERXONA_CONNECT_PASSWORD=your-password -
安裝依賴套件
npm install需要 Node
>=22。若版本過舊,npm install會顯示明確的升級訊息並拒絕執行。 -
啟動伺服器
npm run dev # 啟動並監聽檔案變更 # 或 npm start # 不監聽變更終端機會印出本機 URL,例如
http://localhost:8083。 -
啟動虛擬人
在瀏覽器開啟該 URL。首頁提供兩個範例—— Basic 與 Chatbot——分別展示不同的產品功能與整合能力。進入任一範例,選擇 Avatar、Scene 和 Voice,點擊 Launch,虛擬人將出現並開始說話。
クイックスタート
サンプルアプリは 1 つの Node/Express サーバーで、同じ
<sv-presenter>
統合の上に構築された 2 つの実行可能なブラウザデモを提供します:
Presenter——Basic デモ:avatar
カタログを閲覧し、presenter を起動して発話を駆動(任意で LLM
チャット);および
Chatbot——チャットボットの完全な
CRUD、永続的なマルチターン会話、ナレッジファイルと function
tools。サーバーを一度起動すれば、どちらのデモも開けます。以下の手順で、クローンからしゃべるアバターまで進めます。
>=22
と Perxona サービスアカウントの認証情報が必要です。
-
サンプルをクローン
git clone https://github.com/XRSPACE-Inc/perxona-connect-kit.git cd perxona-connect-kit -
ローカル設定ファイルを作成
cp .env.example .env.envを開いて 3 つの必須値を入力してください:PERXONA_API_BASE_URL=https://console.perxona.ai/asia PERXONA_CONNECT_EMAIL=your@email.com PERXONA_CONNECT_PASSWORD=your-password -
依存関係をインストール
npm installNode
>=22が必要です。古いバージョンの場合、npm installは明確なアップグレードメッセージとともに失敗します。 -
サーバーを起動
npm run dev # ライブリロード (node --watch) # または npm start # ウォッチなしターミナルにローカル URL(例:
http://localhost:8083)が表示されます。 -
アバターを起動
ブラウザで URL を開いてください。ランディングページには Basic と Chatbot の 2 つのデモが表示されます——それぞれ異なる製品機能と統合能力を体験できます。どちらかのデモを開き、Avatar・Scene・Voice を選択して Launch をクリックしてください。アバターが表示されてしゃべります。
Presenter
The demos/basic/ demo is the essential
<sv-presenter> integration every Connect app
needs, in ~300 lines of vanilla JS. It teaches four things:
catalog browsing (fetch avatars, scenes, and
voices), presenter initialization (exchange
server credentials for a Connect token and hand it to
initialize()),
driving speech (send text to
present(), or supply your own audio via
presentWithAudio()), and an optional
LLM chat that pipes replies back through the
presenter. Here is the page lifecycle:
-
Page load:
app.jscallsGET /api/config, dynamically injects the presenter engine<script>frompresenterUrl, then loads the catalog (/api/avatars,/api/scenes,/api/voices) to populate the dropdown selectors. -
Launch click: Calls
presenter.resumeAudioPlayback()to unlock autoplay (must be in the click handler), fetchesGET /api/connect-token, then callspresenter.initialize(connectToken, { avatarId, sceneId, voiceId }). -
Ready state: The presenter fires
PRESENTER_STATUSwithdetail = "Ready"— the UI reveals the performance controls. -
Playback: Preset buttons and the free-text
box call
presenter.present(text). The Stop button callspresenter.interruptPresentation(). -
Chat (optional): If
LLM_API_KEYis set, the chat panel appears. User messages go toPOST /api/chat, and the LLM response is spoken viapresenter.present().
Presenter
demos/basic/ demo 是每個 Connect 應用都需要的核心
<sv-presenter> 整合,以約 300 行的原生 JS
呈現。它示範四件事:catalog 瀏覽(取得
avatar、scene 與 voice)、presenter 初始化(以伺服器憑證換取 Connect token 並傳給
initialize())、驅動語音(將文字傳給
present(),或透過
presentWithAudio()
提供自己的音訊),以及可選的
LLM chat,將回覆回傳給 presenter
發話。以下是頁面生命週期:
-
頁面載入:
app.js呼叫GET /api/config,從presenterUrl動態注入 presenter 引擎<script>,然後載入 catalog(/api/avatars、/api/scenes、/api/voices)以填充下拉選單。 -
Launch 點擊:呼叫
presenter.resumeAudioPlayback()解鎖自動播放(必須在點擊處理器中),取得GET /api/connect-token,然後呼叫presenter.initialize(connectToken, { avatarId, sceneId, voiceId })。 -
就緒狀態:presenter 觸發
PRESENTER_STATUS,detail = "Ready"——UI 顯示演出控制項。 -
播放:預設按鈕和自由文字輸入框呼叫
presenter.present(text)。停止按鈕呼叫presenter.interruptPresentation()。 -
聊天(可選):若設定了
LLM_API_KEY,聊天面板出現。使用者訊息傳送至POST /api/chat,LLM 回應透過presenter.present()發話。
Presenter
demos/basic/ デモは、すべての Connect
アプリに必要な基本的な
<sv-presenter> 統合を、約 300 行のバニラ JS
で示します。次の 4
つを学べます:カタログの閲覧(avatar・scene・voice
の取得)、presenter の初期化(サーバー資格情報を Connect トークンと交換し
initialize()
に渡す)、発話の駆動(テキストを
present() に送るか、
presentWithAudio()
で独自の音声を提供)、そして任意の
LLM チャット(応答を presenter
に戻して発話)。ページのライフサイクルは以下の通りです:
-
ページ読み込み:
app.jsがGET /api/configを呼び出し、presenterUrlから presenter エンジンの<script>を動的に注入し、カタログ(/api/avatars、/api/scenes、/api/voices)を読み込んでドロップダウンを設定します。 -
Launch クリック:
presenter.resumeAudioPlayback()を呼び出して自動再生をアンロック(クリックハンドラー内で必須)、GET /api/connect-tokenを取得し、presenter.initialize(connectToken, { avatarId, sceneId, voiceId })を呼び出します。 -
準備完了状態:presenter が
detail = "Ready"でPRESENTER_STATUSを発行——UI がパフォーマンスコントロールを表示します。 -
再生:プリセットボタンとフリーテキスト入力が
presenter.present(text)を呼び出します。停止ボタンがpresenter.interruptPresentation()を呼び出します。 -
チャット(オプション):
LLM_API_KEYが設定されている場合、チャットパネルが表示されます。ユーザーのメッセージはPOST /api/chatに送信され、LLM の応答がpresenter.present()で発話されます。
Chatbot
The demos/chatbot/ demo integrates the Perxona
Connect Chatbot API with the same
<sv-presenter> stage. On top of the Presenter
demo it adds full chatbot CRUD, a persistent
multi-turn conversation, and
knowledge files plus
function tools. Every assistant reply is piped
into presenter.present(), so the avatar speaks each
response in real time. Messages use the Connect parts-based
format ({ role, parts: [{ type: 'text', text }] })
and are sent as a 20-message sliding window to avoid upstream
timeouts. Open
http://localhost:8083/demos/chatbot/. Here is the
lifecycle:
- Launch the presenter. Pick an Avatar, Scene, and Voice, then click Launch Presenter. The avatar loads in the right-hand stage — identical to the Basic demo.
-
Create or select a chatbot. Click
+ New Chatbot, enter a name and optional
system instructions, and click Save. The
chatbot is created via
POST /api/chatbotsand immediately selected. To edit or delete an existing chatbot, pick it from the dropdown. -
Chat. Type a message and press Send. The
avatar enters Thinking state while the LLM processes (
POST /api/chatbots/:id/chat). The reply appears in the chat log and is spoken aloud viapresenter.present(reply_text). If the presenter is not yet launched, chat still works as text-only. -
Optional — Knowledge file & function tools.
Upload a
.txt,.pdf,.doc,.docx, or.csvfile in the chatbot editor to ground the chatbot in your own content. Add atoolsarray when creating or updating a chatbot to let it call external HTTP APIs during a conversation.
Chatbot
demos/chatbot/ demo 將 Perxona Connect Chatbot API
整合到相同的 <sv-presenter> 舞台上。在
Presenter demo 的基礎上,它新增了完整的 chatbot
CRUD、持久的多輪對話,以及
knowledge file 與
function tools。每個助手回覆都會傳入
presenter.present(),讓 avatar 即時發話。訊息使用
Connect 的 parts 格式({ role, parts: [{ type: 'text', text }] }),並以 20 則訊息的滑動視窗送出以避免上游逾時。開啟
http://localhost:8083/demos/chatbot/。生命週期如下:
- 啟動 presenter。選擇 Avatar、Scene 和 Voice,點擊 Launch Presenter。Avatar 載入右側舞台——與 Basic Demo 完全相同。
-
建立或選取 chatbot。點擊
+ New Chatbot,輸入名稱和可選的系統指令,點擊
Save。Chatbot 透過
POST /api/chatbots建立並立即選取。若要編輯或刪除現有 chatbot,從下拉選單中選取。 -
聊天。輸入訊息並按送出。Avatar 進入 Thinking
狀態,等待 LLM 處理(
POST /api/chatbots/:id/chat)。回覆顯示在聊天記錄中,並透過presenter.present(reply_text)大聲發話。若 presenter 尚未啟動,聊天仍以純文字模式運作。 -
可選——Knowledge file 與 function tools。在
chatbot 編輯器中上傳
.txt、.pdf、.doc、.docx或.csv檔案,讓 chatbot 根據自有內容回答。建立或更新 chatbot 時傳入tools陣列,讓 chatbot 在對話中呼叫外部 HTTP API。
Chatbot
demos/chatbot/ デモは、Perxona Connect Chatbot API
を同じ
<sv-presenter>
ステージと統合します。Presenter
デモの上に、チャットボットの完全な
CRUD、永続的なマルチターン会話、そして
ナレッジファイルと
function toolsを追加します。すべてのアシスタント応答は
presenter.present()
に渡され、アバターが各応答をリアルタイムで発話します。メッセージは
Connect の parts 形式({ role, parts: [{ type: 'text', text }] })を使用し、上流のタイムアウトを避けるために 20
件のスライディングウィンドウで送信されます。
http://localhost:8083/demos/chatbot/
を開いてください。ライフサイクルは以下の通りです:
- Presenter を起動。Avatar・Scene・Voice を選択して Launch Presenter をクリック。アバターが右側のステージに読み込まれます——Basic デモと同じ手順です。
-
チャットボットを作成または選択。
+ New Chatbot
をクリックし、名前と任意のシステム指示を入力して
Save
をクリック。チャットボットが
POST /api/chatbotsで作成され、即座に選択されます。既存のチャットボットを編集・削除するにはドロップダウンから選択してください。 -
チャット。メッセージを入力して送信。LLM
が処理する間(
POST /api/chatbots/:id/chat)アバターが Thinking 状態に入ります。返答がチャットログに表示され、presenter.present(reply_text)でアバターが音声で発話します。Presenter が未起動の場合はテキストのみで動作します。 -
オプション——ナレッジファイルとファンクションツール。チャットボットエディターで
.txt・.pdf・.doc・.docx・.csvファイルをアップロードして、独自コンテンツをもとに回答させることができます。チャットボット作成・更新時にtools配列を渡すと、会話中に外部 HTTP API を呼び出せます。
API Reference
The Express server exposes these routes. All
/api/* endpoints return JSON. The server proxies
catalog reads to the Connect API using its shared cached bearer
token — there is no per-request browser auth.
API 參考
Express 伺服器公開以下路由。所有 /api/* 端點均回傳
JSON。伺服器使用其共享快取的 Bearer Token 將 catalog 讀取代理至
Connect API——不需要每個請求的瀏覽器驗證。
API リファレンス
Express サーバーは以下のルートを公開します。すべての
/api/* エンドポイントは JSON
を返します。サーバーは共有キャッシュの Bearer トークンを使って
Connect API
へカタログ読み取りをプロキシします——リクエストごとのブラウザ認証は不要です。
Direct Connect API 直接呼叫 Connect API Connect API を直接呼び出す
avatar_id and message. Optional
fields: voice_id, emotion, and
intensity.
產生單次 presentation payload。請使用 Connect Bearer Token
直接呼叫 Connect API;Express
範例伺服器不會代理此路由。必填欄位: avatar_id 與
message;選填欄位: voice_id、emotion
與 intensity。
ワンショットの presentation payload を生成します。Connect
Bearer Token を使って Connect API
を直接呼び出してください。このルートは Express
サンプルサーバーではプロキシされません。必須フィールドは
avatar_id と
message、任意フィールドは
voice_id、emotion、intensity
です。
{
"avatar_id": "YOUR_AVATAR_ID",
"voice_id": "YOUR_VOICE_ID",
"message": "Welcome to our hackathon demo!",
"emotion": "excitement",
"intensity": "high"
}
emotion sets the message's emotional tone and
intensity sets its strength. Together, they guide
facial-expression selection for suggested motions and act as
soft ranking signals for motion candidates. Both are optional;
when both are omitted, no facial expression is attached.
Supported emotion values: joy,
excitement, admiration,
caring, gratitude,
sadness, disappointment,
annoyance, embarrassment,
curiosity, surprise,
realization, and confusion.
Supported intensity values: low,
neutral, and high.
emotion 指定訊息的情緒,intensity
指定情緒強度。兩者會引導建議動作的臉部表情選擇,並作為動作候選的軟性排序訊號。
兩者皆為選填;若兩者皆省略,則不會附加臉部表情。支援的
emotion 值為:joy、
excitement、admiration、
caring、gratitude、
sadness、disappointment、
annoyance、embarrassment、
curiosity、surprise、
realization 與 confusion;支援的
intensity 值為:low、
neutral 與 high。
emotion はメッセージの感情、intensity
はその強さを指定します。両者は提案モーションの表情選択を導き、モーション候補のソフトなランキングシグナルとしても使われます。どちらも任意で、両方を省略すると表情は付与されません。対応する
emotion の値は joy、
excitement、admiration、
caring、gratitude、
sadness、disappointment、
annoyance、embarrassment、
curiosity、surprise、
realization、confusion です。
intensity の値は low、
neutral、high です。
Health & Config 健康檢查與設定 ヘルスチェックと設定
200. Response:
{ status: "ok", upstream: "reachable" | "unreachable"
}. Probes the upstream API on every call.
存活檢查與上游診斷。始終回傳 200。回應:{ status: "ok", upstream: "reachable" | "unreachable"
}。每次呼叫都會探測上游 API。
稼働状況と上流診断。常に
200 を返します。レスポンス:{ status: "ok", upstream: "reachable" | "unreachable"
}。毎回上流 API にプローブを実行します。
{ mock: boolean, chat: boolean, presenterUrl: string
}. No upstream probe — cheap to call.
chat reflects presence of
LLM_API_KEY only, never the key itself.
靜態的每個程序標誌。回應:{ mock: boolean, chat: boolean, presenterUrl: string
}。不探測上游——可低成本呼叫。chat 僅反映
LLM_API_KEY 的存在,不包含金鑰本身。
プロセスごとの静的フラグ。レスポンス:{ mock: boolean, chat: boolean, presenterUrl: string
}。上流探索なし——低コストで呼び出せます。chat は
LLM_API_KEY
の存在のみ反映し、キー自体は返しません。
Connect Token
{ connect_token: string }. Pass this directly
into
presenter.initialize(connectToken, { avatarId, sceneId,
voiceId }). Validates the cached token before returning; re-logs in on
401/403.
Cache-Control: no-store.
鑄造/重用共享 Connect Bearer JWT。回應:{ connect_token: string }。直接傳入
presenter.initialize(connectToken, { avatarId, sceneId,
voiceId })。回傳前驗證快取的 token;在 401/403
時重新登入。Cache-Control: no-store。
共有 Connect Bearer JWT
を発行/再利用します。レスポンス:{ connect_token: string }。これを直接
presenter.initialize(connectToken, { avatarId, sceneId,
voiceId })に渡します。返す前にキャッシュしたトークンを検証し、401/403
で再ログインします。Cache-Control: no-store。
Catalog 目錄 カタログ
Page { items: [{ id, name, thumbnail_urls, … }] }. (id is normalized from the upstream
avatar_id.)
列出 Avatar。回應:Page { items: [{ id, name, thumbnail_urls, … }] }。(id 從上游的
avatar_id 正規化。)
アバター一覧。レスポンス:Page { items: [{ id, name, thumbnail_urls, … }] }。(id は上流の
avatar_id から正規化されています。)
lod_urls,
lipsync_configs, etc.).
Avatar 詳細資訊(原始格式,含 lod_urls、lipsync_configs
等)。
アバター詳細(生形式、lod_urls、lipsync_configs
など含む)。
Page { items: […] }. Motions are a sub-resource
of an avatar — there is no top-level motions collection.
某個 Avatar 的動作。回應:Page { items: […] }。動作是 Avatar 的子資源——沒有頂層的 motions 集合端點。
アバターのモーション。レスポンス:Page { items: […] }。モーションはアバターのサブリソースです——トップレベルのモーションコレクションエンドポイントはありません。
Page { items: [{ id, name, … }] }. (id
normalized from scene_id.)
列出場景。回應:Page { items: [{ id, name, … }] }。(id 從 scene_id 正規化。)
シーン一覧。レスポンス:Page { items: [{ id, name, … }] }。(id は
scene_id から正規化。)
Page { items: [{ id, name, … }] }.
列出聲音。回應:Page { items: [{ id, name, … }] }。
音声一覧。レスポンス:Page { items: [{ id, name, … }] }。
Chatbot Chatbot チャットボット
Page { items: [{ id, name, status }] }.
列出所有 chatbot。回應:Page { items: [{ id, name, status }] }。
チャットボット一覧。レスポンス:Page { items: [{ id, name, status }] }。
{ name: string (required), custom_instructions?: string,
tools?: Array }. Response:
ChatBotDetailResponse { id, name, status,
custom_instructions, tools }.
建立 chatbot。請求主體:{ name: string(必填), custom_instructions?: string,
tools?: Array }。 回應:ChatBotDetailResponse { id, name, status,
custom_instructions, tools }。
チャットボットを作成します。ボディ:{ name: string(必須), custom_instructions?: string,
tools?: Array }。 レスポンス:ChatBotDetailResponse { id, name, status,
custom_instructions, tools }。
ChatBotDetailResponse (includes id,
name, custom_instructions,
status, tools).
Chatbot
詳細資訊。回應:ChatBotDetailResponse(含
id、name、
custom_instructions、status、tools)。
チャットボット詳細。レスポンス:ChatBotDetailResponse(id、name、
custom_instructions、status、tools
を含む)。
{ name?, custom_instructions?, tools? }.
Response: updated ChatBotDetailResponse.
更新 chatbot。請求主體:部分欄位
{ name?, custom_instructions?, tools? }。
回應:更新後的 ChatBotDetailResponse。
チャットボットを更新します。ボディ:部分フィールド
{ name?, custom_instructions?, tools? }。
レスポンス:更新後の
ChatBotDetailResponse。
204 No Content.
刪除 chatbot。回傳 204 No Content。
チャットボットを削除します。204 No Content
を返します。
{ filename: string, content_base64: string, mime_type?:
string }. Accepted types: .txt, .pdf,
.md, .csv (max ~7.5 MB). The server
decodes the base64 payload and forwards it to the upstream API
as multipart.
上傳 knowledge file。請求主體:{ filename: string, content_base64: string, mime_type?:
string }。
接受格式:.txt、.pdf、.md、.csv(最大約
7.5 MB)。 伺服器解碼 base64 後以 multipart 格式轉發至上游
API。
ナレッジファイルをアップロードします。ボディ:{ filename: string, content_base64: string, mime_type?:
string }。
対応形式:.txt、.pdf、.md、.csv(最大約
7.5 MB)。 サーバーが base64 をデコードして multipart で上流
API に転送します。
{ messages: Array } — Connect parts format:
[{ role: "user", parts: [{ type: "text", text: "…" }]
}]. Response: { id, status, reply_text }. Pass
reply_text to presenter.present() to
have the avatar speak it.
向 chatbot 傳送訊息。請求主體:{ messages: Array }——Connect parts 格式:
[{ role: "user", parts: [{ type: "text", text: "…" }]
}]。 回應:{ id, status, reply_text }。將
reply_text 傳入
presenter.present() 讓 avatar 發話。
チャットボットにメッセージを送信します。ボディ:{ messages: Array }——Connect parts 形式:
[{ role: "user", parts: [{ type: "text", text: "…" }]
}]。 レスポンス:{ id, status, reply_text }。reply_text
を
presenter.present()
に渡してアバターに発話させます。
Chat
{ messages: Array } (OpenAI message format).
Returns 501 until LLM_API_KEY is
set. Returns 400 if messages is
empty or absent.
可選的 LLM 聊天。請求:{ messages: Array }(OpenAI 訊息格式)。在設定 LLM_API_KEY 前回傳
501。若 messages 為空或缺失則回傳
400。
オプションの LLM チャット。リクエスト:{ messages: Array }(OpenAI メッセージ形式)。LLM_API_KEY
が設定されるまで 501 を返します。messages
が空または欠如の場合は 400。
samples/express/docs/openapi.yaml. For TypeScript
presenter types, install
@perxona/presenter-types@latest.
完整合約:上方列出的是 Express demo 的 proxy
API。如需 direct Connect API 精確的欄位格式與 schema,請參考
OpenAPI
spec:samples/express/docs/openapi.yaml。如需
TypeScript presenter 型別,請安裝
@perxona/presenter-types@latest。
完全なコントラクト:上記は Express demo の
プロキシ API です。direct Connect API の正確な
フィールド形式とスキーマは、OpenAPI spec
samples/express/docs/openapi.yaml
を参照してください。 TypeScript の presenter 型は
@perxona/presenter-types@latest
をインストールしてください。
Presenter API
The <sv-presenter> Web Component is loaded
from Perxona's CDN. Interact with it through its JavaScript API
after it upgrades in the DOM.
Loading the Component
Fetch the CDN URL from
GET /api/config → presenterUrl and inject it
dynamically — no hardcoded URLs in your HTML:
Presenter API
<sv-presenter> Web Component 從 Perxona 的
CDN 載入。在 DOM 中升級後透過其 JavaScript API 進行互動。
載入元件
從 GET /api/config → presenterUrl 取得 CDN URL
並動態注入——HTML 中不要硬編碼 URL:
Presenter API
<sv-presenter> Web コンポーネントは Perxona
の CDN から読み込まれます。DOM
でアップグレードされた後、JavaScript API を通じて操作します。
コンポーネントの読み込み
GET /api/config → presenterUrl から CDN URL
を取得して動的に注入します——HTML に URL
をハードコードしないでください:
<!-- Declare the element; do NOT load the engine script here -->
<sv-presenter hidden></sv-presenter>
const config = await fetch('/api/config').then(r => r.json());
// Load the presenter engine from the server-resolved CDN URL
await new Promise((resolve, reject) => {
const script = document.createElement('script');
script.type = 'module';
script.src = config.presenterUrl;
script.onload = resolve;
script.onerror = () => reject(new Error('Presenter engine failed to load'));
document.head.append(script);
});
const presenter = document.querySelector('sv-presenter');
Full Initialization Flow
完整初始化流程
完全な初期化フロー
// 1. Must run inside a direct user gesture (e.g. button click) to unlock autoplay
await presenter.resumeAudioPlayback();
// 2. Fetch the Connect bearer token the server minted
const { connect_token } = await fetch('/api/connect-token').then(r => r.json());
// 3. Initialize — the presenter resolves target against the Connect API directly
await presenter.initialize(connect_token, {
avatarId: '<id from GET /api/avatars>',
sceneId: '<id from GET /api/scenes>',
voiceId: '<id from GET /api/voices>', // optional
});
// 4. Listen for status changes
presenter.addEventListener('PRESENTER_STATUS', (e) => {
// e.detail: 'Uninitialized' | 'Initializing' | 'Ready'
console.log('Presenter status:', e.detail);
});
// 5. Make the avatar speak — present() never rejects; check result.success
const result = await presenter.present('Hello from Perxona!');
if (!result.success) console.warn(result.code, result.message);
// 6. Stop playback and clear the queue
presenter.interruptPresentation();
API Members
API 成員
API メンバー
| Member | Description說明説明 |
|---|---|
initialize(token, target) |
Boot the presenter. Resolves
target (avatarId/sceneId/voiceId) against
the Connect API and mints a speech token. Returns a
Promise — awaiting it means the presenter is
ready.
啟動 presenter。將
target(avatarId/sceneId/voiceId)解析至
Connect API 並鑄造語音 token。回傳 Promise——await 後表示
presenter 已就緒。
Presenter
を起動します。target(avatarId/sceneId/voiceId)を
Connect API
に解決してスピーチトークンを発行します。Promise
を返します——await 後に Presenter
が準備完了となります。
|
resumeAudioPlayback() |
Unlock browser autoplay policy.
Must be called from a direct user gesture.
Returns a Promise. Call this before
initialize() in your click handler.
解鎖瀏覽器自動播放限制。必須從直接的使用者手勢呼叫。回傳
Promise。在點擊處理器中於
initialize() 之前呼叫此函式。
ブラウザの自動再生ポリシーをアンロックします。直接のユーザージェスチャーから呼び出す必要があります。Promise
を返します。クリックハンドラー内で
initialize()
の前に呼び出してください。
|
present(content) |
Synthesize content into speech and play it
on the avatar. Returns
PresentationResult { success: boolean, code: string,
message?: string }. Never rejects — always check
result.success.
將 content 合成為語音並在 avatar
上播放。回傳
PresentationResult { success: boolean, code: string,
message?: string }。永不 reject——始終檢查
result.success。
content
を音声に合成してアバターで再生します。PresentationResult { success: boolean, code: string,
message?: string }
を返します。reject しません——常に
result.success を確認してください。
|
presentWithAudio(audio, content) |
Play caller-supplied audio on the avatar, bypassing
Perxona TTS. Pass an ArrayBuffer from any
TTS service or pre-recorded clip. The Motion Director
still runs — gestures and expressions are driven by
content. Returns
PresentationResult.
Never rejects.
直接在 Avatar 上播放自訂音訊,略過 Perxona
TTS。傳入任何 TTS 服務或預錄音檔的
ArrayBuffer。Motion Director 仍根據
content 驅動肢體動作與表情。回傳
PresentationResult。永不 reject。
Perxona TTS
を使わず、独自音声をアバターで直接再生します。任意の TTS
または録音済み音声の
ArrayBuffer を渡してください。Motion
Director は
content
に基づき動きと表情を自動生成します。PresentationResult
を返します。reject しません。
|
interruptPresentation() |
Stop the current performance and clear the queue immediately. 立即停止當前演出並清空佇列。 現在のパフォーマンスを停止してキューを即座にクリアします。 |
event PRESENTER_STATUS |
Fired as state changes. e.detail:
"Uninitialized" →
"Initializing" →
"Ready".
狀態改變時觸發。e.detail:"Uninitialized"
→ "Initializing" →
"Ready"。
状態変化時に発行されます。e.detail:"Uninitialized"
→ "Initializing" →
"Ready"。
|
event CONNECT_TOKEN_EXPIRED |
Fired when the Connect API rejects the presenter's
token. Handle by fetching a fresh token and calling
presenter.refreshConnectToken(newToken).
(Not wired in this sample — see
Known Limitations.)
當 Connect API 拒絕 presenter 的 token
時觸發。處理方式:取得新 token 並呼叫
presenter.refreshConnectToken(newToken)。(此範例未連接——見已知限制。)
Presenter のトークンを Connect API
が拒否した時に発行されます。新しいトークンを取得して
presenter.refreshConnectToken(newToken)
を呼び出して対応します。(このサンプルでは未接続——既知の制限を参照。)
|
Motion Browser
Motion Browser is a standalone developer tool that lets you explore Perxona's full motion catalog, preview every animation live on a 3D avatar, and compose scripts that mix free speech text with motion cues — all in one browser-based UI.
The core idea: the
<sv-presenter> Web Component understands
inline motion tags. Drop a [MOTION id:1] chip
anywhere in your script, and the avatar performs that animation
at exactly that point in the speech.
// The avatar says "I love", performs the wave motion, then finishes the line
await presenter.present("I love [MOTION wave:1] my avatar.");
Demo
Features
- Avatar Preview — Full-screen 3D rendering; switch characters instantly from the top selector.
- Motion Library — Browse, search, and filter every available motion. Click any card to preview it live on the avatar.
- Script Composer — Rich-text editor where you mix free speech text with motion chips. Press Play and the avatar speaks and performs motions in sequence.
- Scene & Voice switching — Bottom control bar lets you swap scene and voice style without reloading.
Getting Started
cd tools/motion-browser
cp .env.example .env # production values are pre-filled; no edits needed
pnpm install
pnpm dev
Open the URL printed by pnpm dev, sign in with your
Perxona account, and pick an avatar. The presenter
auto-initializes and the motion library loads automatically.
Composing a Script with Motion Tags
-
Write your speech text
Type the words you want the avatar to say in the Script Composer.
-
Insert a motion chip
Find the motion in the Motion Library panel. Place your cursor at the desired point in the text, then click + to insert it as a chip.
-
Press Play
The avatar speaks the full script and performs each motion at its marked position. The chip serializes to
[MOTION <id>:1]and is passed directly topresenter.present().
Motion Browser
Motion Browser 是一個獨立的開發者工具,讓你瀏覽 Perxona 完整的動作目錄、在 3D Avatar 上即時預覽每個動畫,並撰寫混合說話文字與動作指令的腳本——全在瀏覽器中完成。
核心概念:<sv-presenter> Web
Component 支援行內動作標籤。在腳本文字中任意插入
[MOTION id:1],Avatar
就會在說話的對應時間點執行該動作。
// Avatar 說 "I love" 的同時執行揮手動作,再繼續說話
await presenter.present("I love [MOTION wave:1] my avatar.");
示範
功能
- Avatar 預覽 — 全螢幕 3D 渲染,可從頂部選擇器即時切換角色。
- Motion Library — 瀏覽、搜尋、篩選所有可用動作。點擊任一卡片即可在 Avatar 上即時預覽。
- Script Composer — 富文字編輯器,可在說話文字中混入動作 chip;按下 Play,Avatar 按順序說話並執行動作。
- 場景與聲音切換 — 底部控制列可即時切換場景與聲音,無需重新載入。
快速開始
cd tools/motion-browser
cp .env.example .env # 預設值已填入正式環境設定,無需修改
pnpm install
pnpm dev
以 pnpm dev 啟動後,開啟印出的 URL,以 Perxona
帳號登入並選擇 Avatar。 Presenter 會自動初始化並載入動作庫。
在腳本中插入動作標籤
-
輸入說話文字
在 Script Composer 中輸入 Avatar 要說的話。
-
插入動作 chip
在 Motion Library 面板找到目標動作。將游標放在文字中想要插入動作的位置,點擊 + 插入為 chip。
-
按下 Play
Avatar 說完整腳本,並在每個標記位置執行對應動作。chip 會序列化為
[MOTION <id>:1]並直接傳入presenter.present()。
Motion Browser
Motion Browser は、Perxona が提供するモーションカタログを探索し、3D アバター上でアニメーションをライブプレビューし、 テキストとモーション指定を組み合わせたスクリプトを作成できる、ブラウザベースの開発者ツールです。
中核となる考え方:<sv-presenter>
Web コンポーネントはインラインモーションタグを理解します。
スクリプトテキストのどこにでも
[MOTION id:1]
を挿入すると、アバターはその発話のタイミングでモーションを実行します。
// "I love" と言う際にウェーブモーションを実行し、発話を続けます
await presenter.present("I love [MOTION wave:1] my avatar.");
デモ
機能
- アバタープレビュー — フルスクリーン 3D レンダリング。上部セレクターからキャラクターをリアルタイム切り替え。
- Motion Library — 利用可能なすべてのモーションを検索・フィルタリング。カードをクリックするとアバター上でライブプレビュー。
- Script Composer — テキストにモーションチップを混在させるリッチテキストエディター。Play を押すとアバターがシーケンス通りに発話&モーション実行。
- シーン・音声切り替え — 下部コントロールバーでシーンと音声をリロードなしに即時変更。
開始する
cd tools/motion-browser
cp .env.example .env # 本番設定が事前入力済み、編集不要
pnpm install
pnpm dev
pnpm dev 起動後、表示された URL を開いて Perxona
アカウントでサインインし、 アバターを選択します。Presenter
が自動初期化してモーションライブラリが読み込まれます。
スクリプトにモーションタグを挿入する
-
スピーチテキストを入力
Script Composer にアバターに発話させたいテキストを入力します。
-
モーションチップを挿入
Motion Library パネルで目的のモーションを見つけます。テキスト中の挿入したい位置にカーソルを置き、+ をクリックしてチップとして挿入します。
-
Play を押す
アバターがスクリプト全体を発話し、各マーク位置でモーションを実行します。チップは
[MOTION <id>:1]にシリアライズされ、presenter.present()に直接渡されます。
VRM Uploader
Perxona Connect Kit lets you add your own
VRM 1.0 characters to the avatar catalog with
upload assistance from a Perxona team member — no extra
infrastructure required. Whether you want a branded mascot for
your product, a custom digital presenter for your audience, or a
hand-crafted character for a personal project, this is the
fastest path from a .vrm file to a live, speaking
avatar.
To get your VRM file uploaded to your account, simply speak to a Perxona team member — they'll handle the upload and have your avatar ready to use right away.
Once the upload is complete, your new VRM character will appear
in the avatar list returned by
GET /assets/avatars, ready to use in your project.
VRM Uploader
Perxona Connect Kit 可透過 Perxona 工作人員協助,將你自己的
VRM 1.0 角色加入 Avatar
目錄供選用——無需額外架設任何基礎設施。無論你想為產品打造品牌吉祥物、為受眾建立專屬的數位主持人,或是為個人專案製作原創角色,這都是從
.vrm 檔案到上線說話 Avatar 的最快路徑。
如需將 VRM 檔案上傳至你的帳戶,請洽詢 Perxona 工作人員,他們將協助完成所有上傳步驟,讓你的 Avatar 立即可以使用。
上傳完畢後,你便可以在 GET /assets/avatars
的 Avatar 清單中找到剛上傳的 VRM 角色,並將其應用在你的作品中。
VRM アップローダー
Perxona Connect Kit では、Perxona スタッフのアップロード支援を
受けて、自分の VRM 1.0
キャラクターをアバターカタログに追加できます——追加のインフラ構築は一切不要です。ブランドマスコット、独自のデジタルプレゼンター、個人プロジェクト向けのオリジナルキャラクターなど、どんな用途でも
.vrm
ファイルからライブで話すアバターへの最速ルートです。
VRM ファイルをアカウントにアップロードするには、Perxona スタッフにお声がけください。スタッフがアップロードをお引き受けし、すぐにご利用いただける状態にします。
アップロードが完了すると、GET /assets/avatars
のアバターリストに新しい VRM
キャラクターが表示され、すぐに作品に活用できます。
Known Limitations
- Sample, not production. Demonstrates the happy path — not hardened, scaled, or feature-complete compared to the full API.
-
Shared credential model. All browser visitors
share one Connect identity (the
.envservice account). Fine for demos; not a multi-tenant production design. -
CONNECT_TOKEN_EXPIREDis not wired up. The presenter dispatches this event when its token is rejected. This sample doesn't handle it — reload the page to get a fresh token on long sessions. -
Chat is opt-in.
POST /api/chatreturns501untilLLM_API_KEYis set in.env. - Minimal UI. Intentionally framework-free vanilla JS — designed for readability, not production polish.
已知限制
- 範例,非生產環境。展示正常路徑——與完整 API 相比,未經強化、擴展或功能完整。
-
共享憑證模型。所有瀏覽器訪客共用同一個
Connect 身份(
.env的服務帳號)。適合 Demo;不適合生產環境的多租戶設計。 -
CONNECT_TOKEN_EXPIRED未連接。presenter 的 token 被拒絕時會觸發此事件。此範例未處理——長時間 session 時請重新載入頁面以獲取新 token。 -
聊天為可選功能。
POST /api/chat在.env中設定LLM_API_KEY之前回傳501。 - 極簡 UI。刻意使用無框架的原生 JS——設計為可讀性優先,非生產就緒。
既知の制限
- サンプル、本番環境ではありません。ハッピーパスを示すもの——完全な API と比べて堅牢化・スケール・機能完備はされていません。
-
共有認証情報モデル。すべてのブラウザ訪問者が
1 つの Connect ID(
.envのサービスアカウント)を共有します。デモには適していますが、本番のマルチテナント設計には不向きです。 -
CONNECT_TOKEN_EXPIREDは未接続。Presenter のトークンが拒否された時にこのイベントが発行されます。このサンプルは処理しません——長時間セッションではページをリロードして新しいトークンを取得してください。 -
チャットはオプション。
POST /api/chatは.envにLLM_API_KEYが設定されるまで501を返します。 - 最小限の UI。意図的にフレームワークなしのバニラ JS——可読性を優先した設計で、本番向けではありません。
Troubleshooting
疑難排解
トラブルシューティング
Server exits immediately: "PERXONA_API_BASE_URL is required" or "PERXONA_CONNECT_EMAIL and PERXONA_CONNECT_PASSWORD are required" 伺服器立即退出:"PERXONA_API_BASE_URL is required" 或 "PERXONA_CONNECT_EMAIL and PERXONA_CONNECT_PASSWORD are required" サーバーが即座に終了:"PERXONA_API_BASE_URL is required" または "PERXONA_CONNECT_EMAIL and PERXONA_CONNECT_PASSWORD are required"
You haven't created .env or left a required
value blank. Run cp .env.example .env and fill in
the API base URL and your Perxona service account
credentials.
你尚未建立 .env 或必填值為空白。執行
cp .env.example .env 並填入 API 基底 URL 和
Perxona 服務帳號憑證。
.env
を作成していないか、必須の値が空白です。cp .env.example .env
を実行し、API ベース URL と Perxona
サービスアカウントの認証情報を入力してください。
Catalog fails to load — status shows 401 or
403
目錄載入失敗——狀態顯示 401 或
403
カタログの読み込みが失敗——ステータスが
401 または 403 を表示
The server's PERXONA_CONNECT_EMAIL/PERXONA_CONNECT_PASSWORD
are wrong, or PERXONA_API_BASE_URL points at the
wrong region. Double-check the credentials you registered with
via the signup/confirm-signup API
and verify the API base URL. Check
GET /api/health — the upstream field
shows reachability.
伺服器的 PERXONA_CONNECT_EMAIL/PERXONA_CONNECT_PASSWORD
錯誤,或
PERXONA_API_BASE_URL
指向錯誤的區域。請重新確認透過 signup/confirm-signup
API 註冊時使用的憑證,並檢查 API base URL。檢查
GET /api/health——upstream
欄位顯示可連線性。
サーバーの PERXONA_CONNECT_EMAIL/PERXONA_CONNECT_PASSWORD
が誤っているか、PERXONA_API_BASE_URL
が誤ったリージョンを指しています。signup/confirm-signup
API で登録した認証情報と API base URL
を再確認してください。GET /api/health
を確認——upstream
フィールドで到達可能性を確認できます。
Avatar doesn't appear after clicking Launch 點擊 Launch 後 Avatar 未出現 Launch をクリックしてもアバターが表示されない
Check the browser console for errors. Common causes: the
presenter engine failed to load (CORS error — verify
PRESENTER_URL with your Perxona contact), or
initialize() rejected because the selected
avatar/scene IDs don't exist in your account.
檢查瀏覽器控制台的錯誤。常見原因:presenter
引擎載入失敗(CORS 錯誤——向 Perxona 聯絡人確認
PRESENTER_URL),或
initialize() 因所選 avatar/scene ID
在你的帳號中不存在而失敗。
ブラウザのコンソールでエラーを確認してください。よくある原因:presenter
エンジンの読み込み失敗(CORS エラー——PRESENTER_URL
を Perxona 担当者に確認)、または選択した avatar/scene ID
がアカウントに存在しないため
initialize() が失敗した。
Avatar appears but doesn't speak Avatar 出現但不說話 アバターは表示されるがしゃべらない
Ensure resumeAudioPlayback() is called inside
the Launch button's click handler — not in a timer or after an
await that yields control back to the browser.
Browsers block autoplay triggered outside a synchronous user
gesture.
確保 resumeAudioPlayback() 在 Launch
按鈕的點擊處理器內部呼叫——不在計時器或讓出控制的
await
之後。瀏覽器會阻止在同步使用者手勢之外觸發的自動播放。
resumeAudioPlayback() が Launch
ボタンのクリックハンドラー内で呼び出されていることを確認してください——タイマーやブラウザにコントロールを戻す
await
の後ではなく。ブラウザは同期的なユーザージェスチャー外でトリガーされた自動再生をブロックします。
npm install fails with a Node version
error
npm install 因 Node 版本錯誤而失敗
npm install が Node
バージョンエラーで失敗する
This kit requires Node >=22. Run node --version. If using nvm, run
nvm use (reads .nvmrc) or
nvm install 22.
此套件需要 Node >=22。執行 node --version 確認版本。若使用 nvm,執行
nvm use(讀取 .nvmrc)或
nvm install 22。
このキットには
Node >=22 が必要です。node --version
で確認してください。nvm を使っている場合は
nvm use(.nvmrc を読み込む)または
nvm install 22 を実行してください。
Chat panel doesn't appear 聊天面板未出現 チャットパネルが表示されない
Set LLM_API_KEY in .env and restart
the server. The panel is hidden until the key is present —
GET /api/config will return
chat: true once it's set.
在 .env 中設定
LLM_API_KEY
並重新啟動伺服器。面板在金鑰存在前是隱藏的——設定後
GET /api/config 將回傳
chat: true。
.env に
LLM_API_KEY
を設定してサーバーを再起動してください。キーが存在するまでパネルは非表示です——設定後は
GET /api/config が
chat: true を返します。
Next Steps
Once the basic demo is running, here are natural paths forward:
-
Bring your own UI. Replace the vanilla JS
frontend with React, Vue, or any framework — the server API
(
/api/*) stays unchanged. -
Handle token refresh. Listen for the
CONNECT_TOKEN_EXPIREDevent and callpresenter.refreshConnectToken(newToken)for long-running sessions. -
Enable chat. Set
LLM_API_KEY(and optionallyLLM_BASE_URL+LLM_MODEL) in.envto unlock the LLM-powered chat panel. -
Explore the full API contract. See the
OpenAPI spec for the direct Connect API at
samples/express/docs/openapi.yaml, and install@perxona/presenter-types@latestfor presenter type declarations. -
Try the Chatbot demo. Open
http://localhost:8083/demos/chatbot/to create and configure a chatbot with full CRUD, multi-turn conversation history, knowledge file upload, and optional function tools — all wired to the avatar presenter. - Follow updates and contribute. Star and watch the repository below to track new features and bugfixes.
後續步驟
基本 Demo 運行後,以下是自然的進一步方向:
-
使用你自己的 UI。用 React、Vue
或任何框架取代原生 JS 前端——伺服器
API(
/api/*)保持不變。 -
處理 token 刷新。監聽
CONNECT_TOKEN_EXPIRED事件並呼叫presenter.refreshConnectToken(newToken)以支援長時間 session。 -
啟用聊天。在
.env中設定LLM_API_KEY(及可選的LLM_BASE_URL+LLM_MODEL)以解鎖 LLM 聊天面板。 -
探索完整 API 合約。參考 direct Connect API 的
OpenAPI spec
samples/express/docs/openapi.yaml,並安裝@perxona/presenter-types@latest取得 presenter 型別宣告。 -
嘗試 Chatbot Demo。開啟
http://localhost:8083/demos/chatbot/建立並設定 chatbot,支援完整 CRUD、多輪對話記錄、knowledge file 上傳與可選的 function tools——全部整合至 avatar presenter。 - 追蹤更新並貢獻。Star 並 Watch 下方的 repository 以追蹤新功能和修復。
次のステップ
基本デモが動いたら、自然な次のステップを紹介します:
-
独自の UI を使用。バニラ JS フロントエンドを
React、Vue、または任意のフレームワークで置き換えてください——サーバー
API(
/api/*)は変わりません。 -
トークンリフレッシュの処理。長時間セッション向けに
CONNECT_TOKEN_EXPIREDイベントを監視してpresenter.refreshConnectToken(newToken)を呼び出してください。 -
チャットを有効化。
.envにLLM_API_KEY(オプションでLLM_BASE_URL+LLM_MODEL)を設定して LLM チャットパネルをアンロックしてください。 -
完全な API コントラクトを探索。direct Connect
API の OpenAPI spec
samples/express/docs/openapi.yamlを参照し、 presenter 型宣告には@perxona/presenter-types@latestをインストールしてください。 -
チャットボットデモを試す。
http://localhost:8083/demos/chatbot/を開いて、完全な CRUD・マルチターン会話履歴・ナレッジファイルアップロード・オプションのファンクションツールを備えたチャットボットを作成・設定してください——すべてアバター Presenter と連携しています。 - アップデートをフォロー・貢献。下のリポジトリをスターしてウォッチし、新機能とバグ修正を追跡してください。
XRSPACE-Inc / perxona-connect-kit
Clone the sample, open issues, and follow updates on GitHub. 在 GitHub 上 clone 範例、提交 issue 並追蹤更新。 GitHub でサンプルをクローン、Issue を開いてアップデートをフォローしてください。