00:00 / 00:00

Persona

SDK

@laplace.live/persona-sdk 是 Persona 外掛 API 的官方 TypeScript/JavaScript 用戶端,同時提供通訊傳輸 Schema 的型別定義。本頁面為完整的型別與 API 參考;有關伺服端設定、金鑰產生以及可用 RPC 方法的詳細說明,請參閱 外掛 API。

該 SDK 相容 Node.js 22+、Bun、現代 Web 瀏覽器以及 OBS 瀏覽器來源等執行環境。其唯一的執行階段相依套件為 zod,用於定義並驗證傳輸 Schema。

npm install @laplace.live/persona-sdk

你能用它做什麼

Persona Console 是基於該 SDK 建構的官方參考實作。它提供了一個全功能的 Web 主控台,可在單一瀏覽器分頁內集中管理場景、圖層、素材庫、表情、動作、參數對應、快速鍵、追蹤來源以及全域系統設定,其介面針對直播演播期間的行動裝置與觸控操作進行了專門最佳化。

該主控台完全基於外掛 API 建構,未引用任何桌面端專有程式碼,開發者可使用相同的 SDK 實作同等深度的控制能力。

開發用戶端時建議遵循以下設計原則:

  • 基於功能能力判斷,而非格式或版本號:各實例控制項應在讀取 InstanceRuntime.capabilities 後依需求啟用或停用,避免盲目呼叫導致 unsupported-for-format 錯誤;
  • 斷線重新連線視為狀態重設:WebSocket 連線中斷期間錯過的廣播事件不會重放,本機快取可能與伺服端最新狀態脫節,重新建立連線後應清除本機快取並重新拉取完整狀態快照;
  • 妥善處理終止性連線關閉碼:狀態碼 4001(金鑰失效/撤銷)與 4002(伺服端強制中斷)屬於終止性關閉,應停止自動重新連線重試;其他異常關閉則建議執行指數退避重新連線;
  • 事件訂閱由 SDK 託管:透過 persona.on(…) 註冊的事件接聽程式將在重新連線成功後自動重新訂閱,業務程式碼無需手動維護重新連線後的接聽生命週期。

LLM 提示詞

可將以下 Prompt 提供給 LLM 或加入專案的 CLAUDE.md / AGENTS.md 規則檔案中,作為外掛開發的完整上下文指引:

You are helping me build a plugin for LAPLACE Persona, a desktop VTuber app
(https://laplace.live/persona). Persona exposes a local WebSocket server called the
Plugin API, and `@laplace.live/persona-sdk` is its typed client.

Before writing any code, fetch the reference documents listed at the end — they are
the single source of truth for method names, events, error codes and types. Do not
rely on memory and do not invent names.

## Setup

- Install `@laplace.live/persona-sdk`. Isomorphic: Node 22+, Bun, browsers and OBS
  browser sources. Its only runtime dependency is zod.
- The user enables the server in Persona under Settings → Plugin API and creates an
  API key there. Tokens look like `sk-lp-v1-…`. Default endpoint: `ws://127.0.0.1:25034`.
- Everything — values and types — is exported from the package root; there is no
  other entry point.

## Client

```ts
import { PersonaClient } from "@laplace.live/persona-sdk";

const persona = new PersonaClient({
  token: "sk-lp-v1-…", // required; everything else is optional
  clientInfo: { name: "My Plugin", version: "1.0.0" }, // display-only identity
});
await persona.connect();

const { scenes, activeSceneId } = await persona.call("scene.list");
await persona.call("scene.patch", {
  background: { mode: "color", color: "#00ff00", imageAssetId: null },
});
persona.on("motion.started", (m) => console.log("playing", m.group));

const mouth = persona.driveParameter("MouthOpen", 0.8); // parameter lease
mouth.set(0.3);
mouth.release();
```

`call(method, params?)` is fully typed — the method name determines the request and
response shapes.

Methods cover scenes, model instances, stage objects, expressions, motions, speech,
hotkeys, automations, model and asset registration, settings, tracking and pose
input, per-key storage and parameter injection. Events notify you of scene,
selection, expression, motion, speech, tracking and registry changes.

The exact method and event names, parameter shapes, error codes and limits live in
the reference below — look them up instead of guessing. Gate features on the
capabilities reported by `app.info` and `instance.list`, never on version strings.

## Reference

Fetch these before writing code. The documentation is served as raw Markdown —
append `.mdx` to any page URL (`.en.mdx` for English):

- https://laplace.live/persona/plugin-api.en.mdx — server setup, API keys, and every
  method, event, error code and limit
- https://laplace.live/persona/sdk.en.mdx — the SDK client: options, auth modes and
  every exported type

用戶端

import { PersonaClient } from "@laplace.live/persona-sdk";

const persona = new PersonaClient({ token: "sk-lp-v1-…" });
await persona.connect();

const { scenes, activeSceneId } = await persona.call("scene.list");
await persona.call("scene.patch", {
  background: { mode: "color", color: "#00ff00", imageAssetId: null },
});
persona.on("motion.started", (m) => console.log("playing", m.group));

PersonaClient 支援透過設定選項建立實例,其中僅 token 為必填項目:

Prop

Type

ClientInfo

clientInfo 用於向 Persona 宣告用戶端的身分識別碼,該識別碼將顯示在用戶端設定介面的已連線的用戶端清單中。此欄位為選用的宣告性中繼資料,僅用於介面呈現,不參與驗證邏輯。SDK 在每次重新連線時均會自動重新回報該資訊。

const persona = new PersonaClient({
  token,
  clientInfo: { name: "My Overlay", version: "1.2.0", developer: "You" },
});

Prop

Type

驗證設定

在瀏覽器環境中,API Token 統一透過 ?token= URL 查詢參數傳遞(受限於瀏覽器 WebSocket API 的實作)。在 Node.js 或 Bun 等伺服端環境中,可透過自訂 createWebSocket 鉤子插入 Authorization: Bearer 請求標頭(配合 ws 等用戶端程式庫):

import WebSocket from "ws";

const persona = new PersonaClient({
  token,
  auth: "header",
  createWebSocket: (url, headers) => new WebSocket(url, { headers }),
});

WebSocketLike 定義了 createWebSocket 必須回傳的 Socket 抽象介面。全域 WebSocket 實例與 ws 用戶端均在結構上完全滿足該型別條件約束,無需額外的型別斷言。

Prop

Type

在 Node.js 22+ 中,全域 WebSocket 可以透過 WebSocketInit 擴充傳送交握請求標頭。SDK 提供的 createNodeClient 輔助函式以此建立用戶端:

  • 設定 auth: 'header'
  • 使用 Node 的全域 WebSocket
  • 將連線逾時設為 5 秒
  • 將 SDK 警告與終止性關閉(如 API Key 遭撤銷或被伺服端強制中斷連線)輸出到傳入的 log 函式
import { createNodeClient } from "@laplace.live/persona-sdk";

const persona = createNodeClient({
  token: "sk-lp-v1-…",
  log: console.warn,
});
await persona.connect();

Prop

Type

參數租約驅動

driveParameter 用於持續向模型參數寫入目標值,並回傳一個 InjectionHandle 控制代碼。SDK 在背景自動維護租約心跳,參數租約在最後一次寫入約 1 秒後自動過期並平滑恢復預設值,從而避免用戶端處理程序異常結束時導致參數卡死。

const mouth = persona.driveParameter("MouthOpen", 0.8);
mouth.set(0.3);
mouth.release();

同一模型參數在同一時段內僅允許由單一工作階段獨佔租用;其他工作階段嘗試重複租用將觸發 conflict 錯誤。

該方法亦支援傳入選用的 weight(權重)以及 onError 異常回呼函式。當背景心跳續約失敗時將透過回呼通知,無需在每次更新參數時呼叫 await。

Prop

Type

連線關閉處理

onClose 在伺服端或網路導致連線關閉時觸發。回呼參數包含原始 Socket 關閉碼、關閉原因,以及表示是否已停止重新連線的 terminal 旗標。

  • 回呼在用戶端重設內部狀態並清理擱置請求之後才觸發,因此可以在回呼中安全地呼叫 close()。
  • 用戶端主動呼叫 close() 不會觸發 onClose。
  • 設定 onClose 後,終止性關閉改由它回報,不再經過 onWarning。

Prop

Type

PersonaClientState 與用戶端錯誤

type PersonaClientState = "closed" | "connecting" | "open" | "reconnecting";
type ClientErrorReason =
  | "connect-timeout"
  | "connection-closed"
  | "client-closed"
  | "not-connected"
  | "request-timeout";

當用戶端自身或底層傳輸層無法完成 connect() 或 call() 時,Promise 會以 PersonaClientError 拒絕(帶有 reason: ClientErrorReason,取值見 CLIENT_ERROR_REASONS);伺服端回傳的錯誤影格則以 PersonaApiError(帶有 code: ApiErrorCode)拒絕 call()。詳見 外掛 API:錯誤代碼。

Prop

Type

常數定義

匯出常數取值語意說明
PROTOCOL_VERSION4通訊傳輸格式發生重大變更時遞增;伺服端在 hello 交握中回報自身版本
DEFAULT_API_HOST127.0.0.1伺服端預設繫結的本機回送位址(除非使用者手動開啟區域網路存取)
DEFAULT_API_PORT25034伺服端預設接聽的 WebSocket 連接埠
SCENE_ACTIVATION_TIMEOUT_MS120000未指定 requestTimeoutMs 時,SDK 等待 scene.activate 的預設逾時時間
ASSET_IMPORT_PROMPT_MS45000asset.import 匯入外掛目錄外的檔案時,桌面端等待使用者確認的逾時時間(未指定 requestTimeoutMs 時,SDK 對 asset.import 預設等待 55000 毫秒)
CLOSE_KEY_REVOKED4001終止性關閉狀態碼:API Key 已被伺服端撤銷
CLOSE_FORCE_DISCONNECTED4002終止性關閉狀態碼:使用者在控制面板中中斷了目前用戶端工作階段
CLOSE_SERVER_STOPPING1001非終止性狀態碼:伺服端處理程序正在結束,用戶端可等待重啟後自動重新連線
INJECT_LEASE_TTL_MS1000注入參數在最後一次寫入後的租約存活時間(TTL)
INJECT_HEARTBEAT_MS100SDK 背景重發租約心跳封包的時間間隔
STORAGE_KEY_MAX_LENGTH128外掛儲存鍵名的最大允許字元長度
STORAGE_VALUE_MAX_LENGTH65536單一儲存值序列化後的最大位元組長度限制
STORAGE_KEYS_MAX256每個 API Key 最多可儲存的鍵數量
SPEECH_URL_MAX_LENGTH8000000speech.play 介面支援的 url 最大長度(可容納約 40 秒的 Base64 編碼 WAV 音訊)

SDK 還匯出了以下取值清單與輔助函式:

  • API_ERROR_CODES、CLIENT_ERROR_REASONS、EVENT_NAMES、INPUT_NAMES、TIME_INPUT_NAMES、RANDOM_PULSE_INPUT_NAMES、MODIFIER_TOKENS、APP_CAPABILITIES、FPS_LIMIT_PRESETS、EFFECTS_QUALITY_LEVELS:as const 陣列,便於在 UI 選擇器中列出全部合法取值
  • isApiErrorCode、isEventName、isAppCapability、isTimeInputName、isRandomPulseInputName:對應的 TypeScript 型別防護
  • injectTargetKey:產生標準化的注入目標識別碼
  • personaWsUrl:根據 { host, port, secure }(PersonaAddress,其中 host 須為純主機名稱或 IP 位址)或使用者輸入的位址字串(支援純主機名稱、host:port、IPv4/IPv6 位址以及完整的 ws:// / wss:// URL)產生 WebSocket URL;API Token 由 PersonaClient 在連線時自動附加
  • parseHost、parsePort、isValidPort:驗證純主機名稱/IP 位址(支援帶或不帶方括號的 IPv6,含協定、連接埠、路徑或區域 ID 時回傳 null)與連接埠號碼
  • requestTimeoutMs(method, fallbackMs):依方法名稱計算請求逾時時間(scene.activate 與 asset.import 自動採用各自的長逾時)

模型與素材

模型與通用素材共用統一的中繼資料定義。kind 用於標識項目的資源型別,origin 用於標識其來源:bundled 代表應用程式內建資源或桌面端從 Persona 目錄按需下載的資源,user 代表使用者本機註冊的檔案,同時包含清單中宣告的創作者署名資訊。

Prop

Type

type ModelFormat = "live2d" | "vrm";
type ContentOrigin = "bundled" | "user";
type AssetKind =
  | "image"
  | "video"
  | "audio"
  | "prop"
  | "ibl"
  | "lut"
  | "animation"
  | "cameraMotion"
  | "lyrics";
type InventoryKind = ModelFormat | AssetKind | "effect" | "addon";

effect 屬於特殊的虛擬資產型別,不對應實際磁碟檔案,素材庫透過它列舉系統支援的 內建特效;addon 則代表擴充應用程式本身的選用附加元件(如 攝影機追蹤附加元件),不會作為圖層進入場景。

model.list 回傳 ModelRef 陣列,asset.list 回傳 AssetRef 陣列。兩者都是 ContentRef,kind 分別收窄為 ModelFormat 與 AssetKind。

兩者也帶有布林欄位 exists:AssetRef 的檔案在磁碟上被移動或刪除後,該欄位為 false;ModelRef 在模型入口檔案遺失時同樣為 false。

Prop

Type

Prop

Type

Prop

Type

CatalogItem

CatalogItem 提供了脫離具體傳輸協定的內容中繼資料抽象模型,本機註冊表項目與遠端資源目錄均轉換為此統一結構。它在 ContentRef 基礎上移除了未安裝狀態下的 origin 欄位,並擴充了多語言簡介 description(LocalizedText)與目錄檢索屬性。download(CatalogDownload)描述未安裝項目的下載來源資訊;若該欄位為空,代表該資產已存在於本機環境。

Prop

Type

Prop

Type

Prop

Type

目錄與多語言輔助項:

  • CATALOG_FORMAT、MARKETPLACE_ITEMS_PATH、CATALOG_KINDS:目錄清單格式版本號、公開目錄 API 路徑(/api/items)與目錄支援的項目類型清單
  • isCatalogId、healCatalog、healCatalogItem、healCatalogRows、healSha256:驗證並正規化遠端或本機目錄清單資料
  • payloadEntryPath、payloadEntryKey、catalogMediaFile(參數為 CatalogMediaRole):計算解壓後的目錄資源入口路徑,以及來源目錄下預渲染縮圖與預覽影片的檔案名稱(.thumbnail.avif 與 .preview.webm)
  • pickLocalized(text, locale)、healLocalizedText:依目前介面語言從 LocalizedText 中選取相符的顯示文案並正規化多語言物件

空間排版與放置

2D 螢幕空間以像素為單位,以舞台視窗中心為座標原點(+y 軸向下);3D 世界空間以公尺為單位。傳輸協定中所有旋轉分量均嚴格採用弧度制表示(控制面板上為便於直觀理解以角度呈現)。

Prop

Type

Prop

Type

Place2D 與 Place3D 為物體道具對應的排版型別,欄位結構相同並額外包含 opacity 不透明度屬性。

場景項目

場景設定中的 items 陣列依據渲染深度(Z-order)混合管理模型與物體圖層:

type SceneItem = SceneModelItem | SceneObjectItem;

Prop

Type

Prop

Type

Prop

Type

ObjectContent

物體圖層承載的實際內容結構依據 kind 欄位區分。除 capture(畫面擷取)外,其餘型別均可在桌面端介面中直接建立,詳見 圖層管理。

type ObjectContent =
  | { kind: "image"; assetId: string }
  | {
      kind: "video";
      assetId: string;
      loop: boolean;
      muted: boolean;
      volume: number;
    }
  | { kind: "prop"; assetId: string }
  | {
      kind: "web";
      url: string;
      width: number;
      height: number;
      fps: number;
      transparent: boolean;
      css: string;
      layer: WebLayer;
      shutdownWhenHidden: boolean;
    }
  | { kind: "capture"; source: CaptureKind; sourceId: string; label: string };

type ObjectSpace = "2d" | "3d";
type WebLayer = "behind" | "front";
type CaptureKind = "display" | "window";

Prop

Type

釘附系統

Prop

Type

AttachAnchor

type AttachAnchor =
  | { kind: "root" }
  | { kind: "bone"; bone: string }
  | {
      kind: "artMesh";
      id: string;
      verts: [number, number, number];
      weights: [number, number, number];
    };

object.anchors 回傳父級物件可供繫結的掛載錨點清單(以 AnchorOption 結構呈現,包含錨點 ID 及對應的可讀名稱)。VRM 模型提供根節點及人形骨骼節點;Live2D 模型提供根節點及各 ArtMesh 部件,並帶有 order 繪製層級序號。

AttachDepth

type AttachDepth =
  { kind: "front" } | { kind: "behind" } | { kind: "artMesh"; id: string };

depth 用於控制 Live2D 道具 在父模型內部的渲染層深,可置於模型後方、前方,或指定 ArtMesh 的正上方。該屬性僅適用於附著到 Live2D 父模型的 Live2D 實例,透過 instance.attach 設定。

Prop

Type

釘附相關的輔助函式:

  • depthStops(meshes):由後到前列出可選的深度檔位(模型後方、按繪製順序排列的各 ArtMesh 上方、模型前方)
  • depthStopIndex(meshes, depth):計算某個深度位於哪個檔位;關聯的 ArtMesh 已不存在時按最頂層處理
  • pinRiders(items, instanceId):遞迴找出直接或間接附著在 instanceId 上的所有實例,用於防止循環附著
  • pinnableParents(models, items, instanceId):產生父級候選清單,並用 ridesThis 標記須停用的非法項
  • defaultAttach(parentInstanceId, screenSpace?):產生預設附著設定(繫結根節點、位於模型最前方、不切分部件、無動態物理參數);設定 screenSpace(Live2D 模型或 2D 物件)時,還會以預設回應跟隨父模型頭部轉動

Prop

Type

Prop

Type

場景設定

Prop

Type

Prop

Type

Prop

Type

背景設定

Prop

Type

type BackgroundMode = "color" | "image";

相機設定

Prop

Type

Prop

Type

Prop

Type

Prop

Type

Prop

Type

Prop

Type

cameraDistanceLimits(environment, radius) 計算軌道相機在滑鼠導覽時允許的距離範圍。預設最小、最大距離分別為 DISTANCE_MIN(0.35 公尺)與 DISTANCE_MAX(20 公尺);3D 環境的外框尺寸明顯大於或小於標準空間(約 10 公尺跨度)時,限制會按比例縮放。radius 是 3D 場景的外接球半徑,即 scene.inspect 回傳的 environment.radius;場景載入完成前為 null,此時回傳預設限制。

燈光系統

Prop

Type

type SceneLightType = "directional" | "point" | "ambient" | "area" | "spot";
type ShadowQuality = "off" | "low" | "medium" | "high" | "ultra";
type ShadowFilter = "pcf" | "pcss";

SCENE_LIGHT_TYPES、SHADOW_QUALITY_LEVELS 與 SHADOW_FILTERS 以 as const 陣列提供光源型別、陰影檔位與過濾方式,順序與面板中一致。

SceneLight 的以下三個欄位讓燈光跟隨相機:

  • followCamera:將光源的位置與旋轉繫結到相機座標系
  • followCameraOptions:選擇哪些運動自由度跟隨相機;DEFAULT_LIGHT_FOLLOW_CAMERA_OPTIONS 啟用全部
  • followCameraReference:不跟隨的維度所使用的固定參考變換

若要在不改變燈光實際照射角度的前提下切換跟隨狀態,請呼叫 scene.setLightFollowCamera,不要直接修改這些欄位,詳見 燈光系統。

Prop

Type

Prop

Type

iblAssetId 與 modelAssetId 分別指定環境貼圖(IBL)與 3D 場景模型;具備 environment-map-model 能力的應用程式版本可以同時使用兩者。

  • 更新環境時建議使用 environmentWithAsset():它設定新的資源、保留另一項現有資源,並清理與舊場景繫結的燈光覆蓋項。
  • 選取環境貼圖會自動關閉 bakeFromModel;只有此前兩項均為空時,載入新 3D 場景才會預設開啟烘焙。
  • environmentClearPatch(environment, slot) 產生清除 'model' 或 'map' 的修補程式;slot 為 null 時兩者都清除。
  • applyEnvironmentLighting() 與 applyEnvironmentLook() 對應面板中的快捷操作,分別用於啟用環境燈光與整體套用 EnvironmentLook 視覺風格。

Prop

Type

Prop

Type

Prop

Type

Prop

Type

體積光照依光源單獨開啟,透過 SceneLight.volumetric 設定。相關輔助項:

  • SCENE_VOLUMETRIC_LIGHTING_SPECS:體積霧各滑桿的取值範圍
  • defaultSceneVolumetricLighting():預設的體積霧設定
  • healSceneVolumetricLighting():將越界參數限制在合法範圍內
  • sceneLightCanHaze(type):判斷某種光源型別能否產生體積光
  • sceneLightHazes(light):判斷某個光源目前是否正在產生體積光

特效系統

SceneEffects 採用扁平化的資料結構設計:每個具備開關及參數的後製特效均直接掛載於頂層,便於開發工具進行通用的走訪與反射處理。具體特效在使用者介面中的呈現分組屬於檢視層設計,不影響底層協定結構。

Prop

Type

特效在 圖層清單 中的呈現順序由 environment.effectLayers 獨立維護(為 ToggleEffectKey 陣列)。該清單與特效自身的 enabled 狀態相互獨立:enabled 控制特效管線的運算開關,effectLayers 決定其在 UI 面板中是否作為圖層列出。當透過 Patch 啟用某個特效時,系統會自動補齊對應的圖層項目,因此外掛開發時通常只需修改 enabled 屬性。

type SceneToneMapping = "none" | "neutral" | "aces" | "agx";

Prop

Type

Prop

Type

Prop

Type

Prop

Type

Prop

Type

Prop

Type

Prop

Type

Prop

Type

漸層特效提供 24 種混合模式 EffectBlendMode,EFFECT_BLEND_MODES 依面板中的順序列出它們。

Prop

Type

Prop

Type

Prop

Type

Prop

Type

Prop

Type

Prop

Type

Prop

Type

Prop

Type

Prop

Type

Prop

Type

Prop

Type

Prop

Type

Prop

Type

Prop

Type

Prop

Type

Prop

Type

Prop

Type

rain(降雨)與 snow(降雪)在資料結構上與其他特效保持一致,但在管線行為上具有本質區別:它們在場景中以實際的 3D 粒子幾何體形式存在並參與渲染,而非傳統的畫面空間後製通道,詳見 雨景特效 與 雪景特效。

虛擬形象與物體圖層也有各自的特效管線。SceneModelItem 與 SceneObjectItem 上的 effects 與 effectLayers 先於全螢幕場景特效執行,透過 instance.setEffects 修改。

  • 圖層特效支援 LayerEffectKey 定義的子集:color、levels、colorWheels、colorShift、selectColors、gradient、blur、bloom、diffusion、sketch、rim、outline 與 dropShadow。
  • 輝光特效的顏色過濾僅在圖層層級生效,詳見 圖層特效。

轉場過渡

transition 用於設定場景啟動時的視覺過渡效果,詳見 場景轉場(未宣告 scene-transitions 能力的版本不提供該特性)。SCENE_TRANSITION_TYPES 列出所有合法轉場型別,defaultSceneTransition() 回傳預設的直接切換,healSceneTransition() 用於將參數校正至合法範圍。

Prop

Type

environment.itemTransition 控制場景內模型、道具及動態生成物體的出現與消失動效,詳見 顯示與隱藏。ITEM_TRANSITION_STYLES 列出全部支援的過渡風格,defaultItemTransition() 預設採用 300 ms 的 glitch 故障效果,ITEM_TRANSITION_MAX_MS 限制最長過渡時間為 5000 ms。

Prop

Type

場景預設

presets 依顯示順序列出場景已儲存的 場景預設;未宣告 scene-presets 能力的版本不提供該欄位。可透過 preset.create、preset.update、preset.rename、preset.setTransition、preset.delete 與 preset.apply 管理目前場景的預設,詳見 外掛 API:場景預設。

  • SCENE_PRESET_TRANSITIONS:全部轉場方式
  • scenePresetIsCurrent():判斷舞台目前配置是否與某個預設吻合,桌面端與 Web 主控台據此醒目提示對應預設
  • capturePresetItems():擷取圖層配置
  • presetStep():計算套用預設時各圖層的變化

Prop

Type

Prop

Type

執行階段狀態

instance.list 動態回傳目前舞台上每個活動實例支援的實際能力集,用戶端可據此在 UI 層面精確停用不支援的操作控制項,而無需依賴被動攔截 RPC 例外狀況:

Prop

Type

type InstanceCapability =
  | "motions"
  | "expressions"
  | "placement-2d"
  | "placement-3d"
  | "mtoon"
  | "idle-clips"
  | "idle-motions"
  | "pose"
  | "breath"
  | "expression-weights"
  | "live2d-params"
  | "speech"
  | "post-fx";

speech 語音合成能力僅對已載入的 Live2D 模型有效,因此僅在執行階段實例能力清單中動態回傳,無法單從靜態檔案格式推斷。應用程式自身的功能特性則透過 hello 交握及 app.info 統一回報。用戶端應始終透過能力列舉(Capability Flags)判斷功能是否可用,不要比對應用程式版本號字串:

type AppCapability =
  | "storage"
  | "speech"
  | "automations"
  | "controllers"
  | "model-editing"
  | "asset-inspection"
  | "layer-effects"
  | "scene-transitions"
  | "light-area"
  | "light-spot"
  | "light-camera-follow"
  | "light-shadow-filter"
  | "environment-map-model"
  | "stage-spawn"
  | "idle-tracking-lost"
  | "motion-stop"
  | "stage-capture"
  | "object-pin-depth"
  | "object-text"
  | "camera-follow"
  | "camera-aim"
  | "camera-focus"
  | "camera-handheld"
  | "object-video-sound"
  | "object-chroma-key"
  | "model-movement"
  | "model-movement-pivot"
  | "layer-effects-2d"
  | "scene-presets"
  | "background-alpha"
  | "binding-calibration"
  | "binding-random-pulses"
  | "expression-groups"
  | "expression-groups-hide-first"
  | "model-history"
  | "automation-editing"
  | "automation-transport"
  | "asset-import";

canonicalAppCapability 將舊版能力名稱對應到目前的標準名稱。舊版名稱包括 area-lights、spot-lights、camera-follow-lights、shadow-filters、spawn、tracking-lost、text-objects 與 video-sound 等。PersonaClient 收到伺服端回報的能力清單時已自動完成這項轉換。

stage.capture(依賴 stage-capture 能力)回傳 { dataUrl, width, height },包含舞台渲染視窗帶透明色版的 PNG 影像,最長邊不超過 maxEdge(有效範圍 64 – 2048,預設 1024)。無圖形介面的自動化用戶端或 AI 助理主要透過此介面驗證渲染結果,協定規範詳見 外掛 API:功能能力。

Prop

Type

files 保持了模型定義檔案中各動作的原始索引順序:檔案缺失的動作項目使用空字串佔位,以確保後續動作的絕對索引不發生偏移。motionSlots(files) 回傳實際可播放的動作項目及其對應索引;若嘗試向空位呼叫 motion.play 將回傳 not-found 錯誤。Live2D 模型還會自動掃描並列出同目錄下未在 model3.json 中宣告的所有 .motion3.json 動作檔案,並以檔案名稱分別建立獨立的分組。

motion.stop(依賴 motion-stop 能力)用於結束目前播放中的單次動作,並讓模型平滑回到待命狀態;若目前僅處於待命狀態,則回傳 { stopped: false }。motion.playing 及 motion.started 中的 oneShot 旗標表明該動作是否屬於可透過 stop 中斷的單次播放動作。

Prop

Type

Prop

Type

Prop

Type

表情群組

expression.getGroups 與 expression.setGroups(依賴 expression-groups 能力)讀寫模型的表情群組,回傳 ExpressionGroups;規則詳見 外掛 API:表情群組。

Prop

Type

Prop

Type

Prop

Type

EXPRESSION_GROUP_FADE_SECONDS_MAX(2)為成員淡入淡出時長的上限,EXPRESSION_GROUP_FADE_SECONDS_DEFAULT(0.2)為新成員的預設值;foldExpressionKey 依 VTS 的規則(不區分大小寫)折疊表情鍵,用於判斷兩個鍵是否指向同一表情,firstByExpressionKey(items, keyOf) 則依折疊後的鍵建立對應表並保留每個非空鍵下首次出現的項目(與 VTS 解析表情鍵的順序一致);newVtsId 產生 VTS 格式的 ID(32 位小寫十六進位),可用於新增的群組。

快速鍵系統

Prop

Type

Prop

Type

HotkeyConfig 是剝離了 registered 狀態後的設定結構,用於 hotkey.set 介面傳遞參數。registered 列出目前在 Persona 處於背景時仍會回應的快速鍵;桌面端直接讀取按鍵狀態而非向系統註冊全域快速鍵,因此任意組合鍵(包括單一按鍵)均可在背景觸發,hotkeyRunsInBackground 用於判斷某條快速鍵是否設定為背景生效。組合鍵依同時按住的按鍵集合觸發,comboKey(accelerator) 回傳與順序無關的組合識別碼,duplicateAccelerators 據此找出被多條快速鍵佔用的組合。acceleratorLabel(accelerator, platform, mouseLabels?) 依標準修飾鍵順序(MODIFIER_TOKENS:Control、Alt、Shift、Super)將組合鍵格式化為適合鍵帽顯示的標籤陣列,並根據 hello 回報的桌面端 app.platform 選取符號('darwin' 下為 ⌃、⌥、⇧、⌘,其他平台為 Ctrl、Alt、Shift、Win;滑鼠按鍵預設使用 MOUSE_TRIGGER_LABELS,亦可傳入多語言標籤)。

舞台上的每個虛擬形象都有一套獨立的快速鍵:

  • hotkey.list、hotkey.set 與 hotkey.trigger 均接受選用的 modelId 參數,省略時指向主模型。
  • hotkey.state 事件依模型分別推送更新。
  • hold、fadeSeconds、deactivateAfterSeconds 與 stopsOnLastFrame 為新版協定新增的欄位;呼叫 hotkey.set 時省略的欄位保持現有設定不變。

SDK 提供了快速列舉目前場景快速鍵的輔助函式:listSceneHotkeys(client) 查詢目前作用中場景中所有模型的快速鍵設定(主模型排在首位);listModelHotkeys(client, scene) 為舞台上的每個模型分別回傳一個 Promise<ModelHotkeys>,便於呼叫端並行獨立結算。

Prop

Type

自動化系統

自動化工作流程是應用程式層級的自動化系統,獨立於單一模型實例。每條自動化包含一組操作指令,可由快速鍵、系統事件或 API 呼叫觸發。automation.list 用於查詢清單,automation.run 依 ID 執行指定自動化,automation.state 在工作流程發生變更時廣播推送完整清單。該特性需要應用程式宣告 automations 能力,詳見 外掛 API:自動化。

Prop

Type

type AutomationActionKind =
  | "effect-toggle"
  | "effect-params"
  | "effect-clip"
  | "camera-pose"
  | "camera-reset"
  | "camera-motion-play"
  | "camera-motion-stop"
  | "camera-follow"
  | "camera-aim"
  | "camera-focus"
  | "camera-handheld"
  | "layer-visibility"
  | "preset-apply"
  | "text-set"
  | "lyrics-play"
  | "stream-mode"
  | "scene-switch"
  | "expression-toggle"
  | "motion-play"
  | "audio-play"
  | "audio-control"
  | "expression-clear"
  | "model-load"
  | "model-position";

actionKinds 與 triggerKinds 的型別是開放的 string[] 而非固定的聯集型別,以便相容更高版本伺服端新增的型別。操作型別統一以類別開頭命名,用戶端會自動規範化舊版主機傳來的歷史名稱。

  • automationActionLabel:操作型別的英文顯示標籤
  • automationLabel:整條自動化的摘要標籤,優先使用 title,未設定時以 · 連接各項操作的標籤
  • AUTOMATION_SETUP_KINDS、isAutomationSetup(以及 isAutomationSetupAction):識別在時間軸開始前先行執行的準備操作(scene-switch 與 model-load);AUTOMATION_BOUNDARY_KINDS 與 isAutomationBoundary 為已棄用的別名
  • isAutomationMediaAction、isAutomationSourcedAction、isAutomationSampledClip、isAutomationContentAction:依時間軸行為對動作分類(媒體片段、帶 sourceInMs 入點偏移的片段、支援拖曳定位預覽的片段、一般時間軸動作)

時間軸編輯與播放控制

具備 automation-editing 能力時,automation.get、automation.create、automation.update 與 automation.delete 可讀寫完整的 AppAutomation 時間軸定義;具備 automation-transport 能力時,automation.control 與 automation.status 可驅動時間軸播放並讀取 AutomationRunStatus,詳見 外掛 API:自動化。

Prop

Type

Prop

Type

Prop

Type

Prop

Type

  • AutomationDefinitionSchema、AppAutomationSchema、automationTimelineActionSchemas、automationTriggerSchemas:時間軸定義、各動作類型與各事件觸發條件類型的 Zod Schema
  • validateAutomationTimeline、automationTimelineLimit:驗證時間軸時長與各片段的時間範圍,並計算時間軸的結束時間
  • AUTOMATION_TRANSPORT_COMMANDS、AUTOMATION_RUN_PHASES、AUTOMATION_STEP_STATES:播放控制命令(play、pause、stop、seek、prepare)、執行階段與步驟狀態的 as const 陣列
  • MAX_AUTOMATION_DURATION_MS、MAX_AUTOMATION_EFFECT_FADE_MS、MAX_AUTOMATION_HOLD_MS、MAX_AUTOMATION_COOLDOWN_MS:時間軸時長、畫面效果片段淡入淡出、保持時長與觸發條件冷卻時間的上限常數
  • AUDIO_RETRIGGER_MODES、PLAYBACK_COMMANDS、MAX_AUDIO_FADE_MS、MAX_AUDIO_REPEAT_COUNT:audio-play 與 audio-control 動作使用的重觸發模式、播放控制指令與音訊參數上限

系統設定

Prop

Type

SettingsPatch 是設定中可寫入的部分,所有欄位均為選用:lipSync、controller(僅 enabled 開關)、window、ui 與 performance。動態捕捉與姿勢參數則透過 tracking.* 與 pose.* 介面單獨設定。

Settings 與 SettingsPatch 均由 SDK 匯出的執行階段 Zod Schema(SettingsSchema 與 SettingsPatchSchema)推導而來:

  • 驗證修補內容時會自動剔除未知欄位與唯讀欄位。
  • 解析伺服端回應時會放行擴充欄位。
  • PersonaClient 本身不在用戶端做前置驗證。
type TrackingSourceId = "persona-ios" | "ifacialmocap" | "vts-ios";
type PoseSourceId = "vmc" | "mocopi";
type TrackingSourceKind = TrackingSourceId | PoseSourceId | "mediapipe";
type TrackingStatus = "off" | "waiting" | "tracking" | "no-face";
type PoseStatus = "off" | "waiting" | "tracking";
type EffectsQuality = "low" | "medium" | "high";

捕捉來源設定

tracking.sources 列出了目前設定的所有輸入來源,包括網路臉部來源、動作姿勢來源以及本機攝影機。系統支援多來源同時運作,模型實例透過 SceneModelItem 上的 faceSourceId、poseSourceId 與 handSourceId 依 ID 繫結對應的捕捉來源。

Prop

Type

tracking.source、pose.source 及 pose.port 屬於多來源架構引入前的舊欄位,目前鏡像對應至對應通道的首個網路來源,僅供舊版用戶端相容使用。新開發的外掛應統一使用 sources 欄位。

mediapipe 網路攝影機臉部追蹤 來源包含獨立的設定屬性,預設參數定義於 DEFAULT_MEDIAPIPE_CONFIG。

Prop

Type

type HandTrackingMode = "arms" | "fingers";

單一輸入來源可以同時驅動多個資料通道,例如一台攝影機可同時輸出臉部、手部與身體姿勢。sourceSupportsChannel(source, channel) 用於判斷特定來源在目前演算法模式下是否支援 face、hands 或 pose 輸出通道;sourceChannelEnabled(source, channel, masters) 則在此基礎上綜合計算該來源自身的分通道開關以及全域總開關的啟用狀態。

口型同步設定

settings.lipSync 與 lipSync.configure 介面共用相同的 LipSyncConfig 結構,對應桌面端的麥克風音訊驅動。對於不支援音訊口型同步的環境建置,Settings 中將剔除該設定項目。

Prop

Type

lipSync.state 與 lipSync.calibrate 回傳 LipSyncState。校準互動流程詳見 麥克風口型同步。

Prop

Type

SceneModelItem 中的 lipSyncMode 用於依模型設定麥克風口型同步的驅動策略:

type LipSyncMode = "off" | "always" | "when-untracked";

模型整體移動設定

model.getMovement 與 model.setMovement 介面使用 ModelMovementConfig 設定結構,對應 Live2D 模型在面部捕捉驅動下的整體位移與縮放(即 VTube Studio 的 Movement Config)。水平、垂直與深度位移滑桿範圍為 −50 – 50;pivot(前後縮放中心,需 model-movement-pivot 能力)以 Live2D 畫布標準化座標記錄縮放中心。

Prop

Type

版本歷史

model.*Version* 方法與 model.restoreFiles(依賴 model-history 能力)讀取與管理模型已儲存的版本,對應桌面端的 版本歷史;各方法的參數與錯誤語意詳見 外掛 API:版本歷史。

Prop

Type

Prop

Type

Prop

Type

type ModelVersionKind = "first" | "saved" | "backup";
type ModelVersionUnsavedAction = "save" | "discard";
type ModelVersionChangeStatus = "added" | "modified" | "deleted" | "unchanged";
  • MODEL_VERSION_KINDS、MODEL_VERSION_UNSAVED_ACTIONS、MODEL_VERSION_CHANGE_STATUSES:上述類型對應的 as const 陣列
  • MODEL_VERSION_CURRENT('current'):可在任何接受版本 ID 的位置代表磁碟上的目前檔案,如 model.compareVersions 的 from 或 to
  • MODEL_VERSION_NAME_MAX_LENGTH(80)、MODEL_VERSION_NOTES_MAX_LENGTH(2000):版本名稱與備註的最大字元數
  • MODEL_VERSIONS_LIST_MAX(500)、MODEL_VERSIONS_LIST_DEFAULT(50):單次 model.listVersions 回傳版本數的上限與預設值

外掛儲存

storage.* 介面支援儲存任意合法的 JSON 值。具體鍵值限制詳見 常數定義,使用規範詳見 外掛儲存。

type JsonValue =
  string | number | boolean | null | JsonValue[] | { [key: string]: JsonValue };

參數注入

Prop

Type

type InjectTargetType = "input" | "live2d-param" | "vrm-expression";

InjectTarget 是去掉 value 與 weight 後的注入目標。

輸入名稱

input 目標的 id 取自下表中的輸入名稱。INPUT_NAMES 包含下表中的全部名稱,其中 VTube Studio 與 ARKit 名稱與模型 .vtube.json 中的命名一致。注入的 input 值僅對 Live2D 模型生效。

類別輸入
VTube StudioVTS 經典 21 項輸入命名:FaceAngleX FaceAngleY FaceAngleZ FacePositionX FacePositionY FacePositionZ EyeOpenLeft EyeOpenRight EyeLeftX EyeLeftY EyeRightX EyeRightY Brows BrowLeftY BrowRightY MouthSmile MouthOpen MouthX CheekPuff JawOpen TongueOut
ARKit其餘 52 個通道,以 ARKit 為字首,後接 ARKit Blendshape 的 PascalCase 名稱,如 ARKitJawOpen、ARKitMouthSmileLeft、ARKitEyeBlinkRight
控制器BASE_CONTROLLER_INPUT_NAMES,即首個控制器沿用 VTS 規範的輸入名稱:左右搖桿(ControllerStickLeftX/Y、ControllerStickRightX/Y)與搖桿下壓、十字鍵軸向與四個獨立方向鍵(ControllerDPadUp/Down/Left/Right)、動作鍵、肩鍵、扳機鍵、Options、Home、PlayStation 觸控板按下(ControllerTouchPadPress)、VTS 衍生的拇指與食指位置(ControllerThumbPosLeft/Right、ControllerFingerPosLeft/Right)、左右側按鈕狀態與計數(ControllerButtonsAnyLeft/Right、ControllerButtonCountLeft/Right)以及控制器傾斜(ControllerLean)
手部HAND_INPUT_NAMES:VTS 規範的 26 個手部通道,外加 HandLeftAngleY 與 HandRightAngleY,涵蓋雙手偵測旗標、三維座標、空間旋轉角、手掌開合度、各手指獨立開合(如 HandLeftFinger_1_Thumb),以及 BothHandsFound 與 HandDistance
語音VOICE_INPUT_NAMES:VTS 的 VoiceVolume、VoiceFrequency、VoiceVolumePlusMouthOpen、VoiceFrequencyPlusMouthSmile、VoiceA 至 VoiceO 以及 VoiceSilence,外加 VoiceMouthOpen 與帶符號的 VoiceMouthSpread
滑鼠MOUSE_INPUT_NAMES:MousePositionX 與 MousePositionY,即滑鼠指標在螢幕上的位置,正規化為 −1..1(向右為正、向上為正,與 FacePositionY 一致)
時間TIME_INPUT_NAMES:Time24h 與 Time12h,取值範圍為 0..1(TIME_INPUT_RANGES)
隨機RANDOM_PULSE_INPUT_NAMES:RandomPulse1 至 RandomPulse8,取值範圍為 0..1(RANDOM_PULSE_INPUT_RANGES)
  • 加上 ARKit 字首是為了與 VTS 已佔用的 JawOpen、CheekPuff、TongueOut 區分,因為 .vtube.json 的參數比對不區分大小寫。這三個同名通道即 ARKIT_TWINS:它們與對應的 ARKit 通道共用同一個浮點值,兩個名稱均可寫入,內部統一對應到 ARKit 通道。
  • INPUT_RANGES 定義了各輸入的標準取值範圍:頭部與手部旋轉以角度(Degrees)為單位,ARKit 通道為 0..1,其餘為無量綱的正規化數值。
  • CONTROLLER_THUMB_POSITIONS、CONTROLLER_FINGER_POSITIONS 與 isControllerPositionInput 對應拇指與食指位置。次級控制器在 Controller 後追加索引數字(如 Controller2StickLeftX、Controller12Cross),支援任意數量的控制器。controllerInputName 產生指定序號的輸入名稱,getInputRange 回傳對應量程(搖桿與十字鍵的 Y 軸向上為正)。
  • 滑鼠輸入獨立於臉部捕捉,不受臉部動態捕捉總開關影響。
  • 時間輸入每一影格取樣一次桌面主機的本機時鐘,獨立於臉部動態捕捉狀態,同時支援 Live2D 與 VRM 參數繫結,詳見 時間參數繫結。isTimeInputName 是對應的型別防護。
  • 隨機脈衝輸入各自依獨立的觸發設定自動在 0(靜止)與 1(完全觸發)之間起伏,獨立於臉部追蹤狀態(詳見 參數對應 與 外掛 API:參數對應)。RandomPulseSchedules 依輸入名稱記錄模型的自訂觸發設定,未單獨設定的脈衝使用 DEFAULT_RANDOM_PULSE_SCHEDULE(間隔 0.5–4.5 秒、持續 0.58 秒、淡入與淡出各 0.29 秒,與 VTube Studio 自動眨眼一致);RANDOM_PULSE_MIN_SECONDS(0.1)與 RANDOM_PULSE_MAX_SECONDS(3600)定義時間範圍上下限,sanitizeRandomPulse 與 sanitizeRandomPulses 負責驗證與正規化設定,isPulseBinding、pulseRest、pulseHoldsRest、firePulseBinding 與 bindingOutputRange 則用於計算脈衝對應的疊加輸出。

Prop

Type

有關 Live2D 模型中各輸入通道如何對應至具體內部參數,詳見 參數對應。

底層訊息信封

若直接使用 SDK 用戶端開發,無需手動處理此類底層訊息信封;本節規範供直接對接原始 WebSocket 協定的開發者參考:

Prop

Type

Prop

Type

Prop

Type

Prop

Type

Prop

Type

Prop

Type

ApiErrorCode 為 ErrorMessage 中 code 屬性的封閉列舉集合,各錯誤碼的具體語意詳見 錯誤碼參考。用戶端在執行 call 發生例外狀況時擲出的 PersonaApiError 實例將封裝該錯誤碼。

最後更新於 2026年11月7日

Tech otakus destroy the world