@spatialwalk/avatarkit 1.0.0-beta.88 → 1.0.0-beta.89

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/CHANGELOG.md CHANGED
@@ -5,6 +5,31 @@ All notable changes to this project will be documented in this file.
5
5
  The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.0.0/),
6
6
  and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
+ ## [Unreleased]
9
+
10
+ ### ⚡ Breaking Changes
11
+
12
+ - **Enum Rename** — `ConversationState.pausing` renamed to `ConversationState.paused` for cross-SDK consistency
13
+ - **FrameRateInfo** — Unified as pre-computed fields; sub-stage data (decode/render/present) now available via `FrameRenderInfo`
14
+
15
+ ### ✨ Features
16
+
17
+ - **FrameRateMonitor** — Unified public API for frame rate monitoring with enable/disable switch
18
+ - **Device Benchmark** — `deviceScore` and `isDeviceSupported` APIs for runtime device capability assessment
19
+ - **Telemetry Enhancements** — `avatar_playback_fps` now reports `cpu_score`, `gpu_score`, and `renderer_backend` (webgl/webgpu)
20
+ - **Deprecation Reset** — Deprecation warnings reset on `initialize()` to avoid stale state across re-init cycles
21
+ - **Compressed Model (Beta)** — `load()` accepts optional `useCompressedModel` parameter (default `false`); when `true`, prefers compressed model resource (~30% of original size, minor quality degradation), falls back to standard resource if unavailable。此功能目前为 Beta,请务必验证渲染效果后再用于生产环境
22
+
23
+ ### ⚡ Performance
24
+
25
+ - **Audio-Clock-Driven Scheduling** — Speaking playback now uses audio clock for tick scheduling, replacing RAF-based timing for more accurate frame pacing
26
+ - **Idle Present Frame Resubmission** — Idle state uses `presentFrameOnly()` to resubmit the current frame, reducing GPU re-computation
27
+
28
+ ### 🐛 Bugfixes
29
+
30
+ - **Build Packaging** — WASM binary missing from dist in beta.87; added benchmark-demo and marble-test to dts exclude
31
+ - **Deprecation State** — Fixed stale deprecation warnings persisting across SDK re-initialization
32
+
8
33
  ## [1.0.0-beta.88] - 2026-03-10
9
34
 
10
35
  ### 🐛 Bugfixes
@@ -1,7 +1,7 @@
1
1
  var __defProp = Object.defineProperty;
2
2
  var __defNormalProp = (obj, key, value) => key in obj ? __defProp(obj, key, { enumerable: true, configurable: true, writable: true, value }) : obj[key] = value;
3
3
  var __publicField = (obj, key, value) => __defNormalProp(obj, typeof key !== "symbol" ? key + "" : key, value);
4
- import { A as APP_CONFIG, l as logger, e as errorToMessage, a as logEvent } from "./index-Ow7xDTS3.js";
4
+ import { A as APP_CONFIG, l as logger, e as errorToMessage, a as logEvent } from "./index-Cq6e5BSB.js";
5
5
  class StreamingAudioPlayer {
6
6
  // Mark if AudioContext is being resumed, avoid concurrent resume requests
7
7
  constructor(options) {
@@ -0,0 +1,36 @@
1
+ (function() {
2
+ "use strict";
3
+ const MATRIX_SIZE = 128;
4
+ const A = new Float32Array(MATRIX_SIZE * MATRIX_SIZE);
5
+ const B = new Float32Array(MATRIX_SIZE * MATRIX_SIZE);
6
+ const C = new Float32Array(MATRIX_SIZE * MATRIX_SIZE);
7
+ for (let i = 0; i < A.length; i++) {
8
+ A[i] = i % 100 / 100;
9
+ B[i] = i * 7 % 100 / 100;
10
+ }
11
+ function benchmarkMatrixMultiply() {
12
+ const N = MATRIX_SIZE;
13
+ for (let i = 0; i < N; i++) {
14
+ for (let j = 0; j < N; j++) {
15
+ let sum = 0;
16
+ for (let k = 0; k < N; k++) {
17
+ sum += A[i * N + k] * B[k * N + j];
18
+ }
19
+ C[i * N + j] = sum;
20
+ }
21
+ }
22
+ }
23
+ self.onmessage = () => {
24
+ const warmupEnd = performance.now() + 1e3;
25
+ while (performance.now() < warmupEnd) {
26
+ benchmarkMatrixMultiply();
27
+ }
28
+ let iterations = 0;
29
+ const measureEnd = performance.now() + 1e3;
30
+ while (performance.now() < measureEnd) {
31
+ benchmarkMatrixMultiply();
32
+ iterations++;
33
+ }
34
+ self.postMessage({ cpuScore: iterations });
35
+ };
36
+ })();
File without changes
@@ -3,6 +3,8 @@ export declare class Avatar {
3
3
  readonly id: string;
4
4
  private characterMeta;
5
5
  private resources;
6
+ /** Local-only field: tracks whether cached model is "standard" or "compressed". */
7
+ _cachedModelType: string;
6
8
  /**
7
9
  * Get character metadata
8
10
  * @returns Character metadata, including all configuration information (version, resource URLs, camera config, etc.)
@@ -1,15 +1,23 @@
1
1
  import { Avatar } from './Avatar';
2
2
  import { ConnectionState, DrivingServiceMode, ConversationState, PostProcessingConfig, KeyframeData } from '../types';
3
+ import { FrameRateInfo } from '../performance/FrameRateMonitor';
3
4
  export declare class AvatarController {
4
5
  private networkLayer?;
5
6
  private readonly playbackMode;
6
7
  private isStartingPlayback;
7
8
  private currentConversationId;
8
9
  private reqEnd;
9
- onConnectionState: ((state: ConnectionState, error?: Error) => void) | null;
10
+ onConnectionState: ((state: ConnectionState) => void) | null;
10
11
  onConversationState: ((state: ConversationState) => void) | null;
11
12
  onError: ((error: Error) => void) | null;
12
13
  private eventListeners;
14
+ private readonly frameRateMonitor;
15
+ /** Frame rate monitoring callback. Fires with aggregated metrics from a 2-second sliding window. */
16
+ get onFrameRateInfo(): ((info: FrameRateInfo) => void) | null;
17
+ set onFrameRateInfo(value: ((info: FrameRateInfo) => void) | null);
18
+ /** Whether frame rate monitoring is enabled. Default is false (zero overhead when disabled). */
19
+ get frameRateMonitorEnabled(): boolean;
20
+ set frameRateMonitorEnabled(value: boolean);
13
21
  private renderCallback?;
14
22
  private characterHandle;
15
23
  private characterId;
@@ -32,6 +40,9 @@ export declare class AvatarController {
32
40
  constructor(avatar: Avatar, options?: {
33
41
  playbackMode?: DrivingServiceMode;
34
42
  });
43
+ private handleVisibilityChange;
44
+ private shouldReportPlaybackStats;
45
+ private _getDeviceScoreProps;
35
46
  /**
36
47
  * Get current conversation ID
37
48
  * Returns the current conversation ID for the active audio session
@@ -18,9 +18,10 @@ export declare class AvatarManager {
18
18
  * Load avatar
19
19
  * @param id Avatar ID
20
20
  * @param onProgress Progress callback
21
+ * @param useCompressedModel Use compressed model resource (~30% of original size, with minor quality degradation). Defaults to false.
21
22
  * @returns Promise<Avatar>
22
23
  */
23
- load(id: string, onProgress?: (progress: LoadProgressInfo) => void): Promise<Avatar>;
24
+ load(id: string, onProgress?: (progress: LoadProgressInfo) => void, useCompressedModel?: boolean): Promise<Avatar>;
24
25
  /**
25
26
  * Cancel a pending or running download task
26
27
  * @param id Avatar ID to cancel
@@ -6,6 +6,8 @@ export declare class AvatarSDK {
6
6
  private static readonly _version;
7
7
  private static _avatarCore;
8
8
  private static _dynamicSdkConfig;
9
+ private static _cachedDeviceScore;
10
+ private static _rendererBackend;
9
11
  /**
10
12
  * Initialize SDK
11
13
  * @param appId Application ID to be included in both HTTP Headers and WebSocket Headers
@@ -34,4 +36,23 @@ export declare class AvatarSDK {
34
36
  * Cleanup resources
35
37
  */
36
38
  static cleanup(): void;
39
+ /**
40
+ * Device performance score (CPU + GPU).
41
+ * CPU: matrix multiply throughput in Web Worker (warmup 1s + measure 1s).
42
+ * GPU: WebGPU compute shader throughput (warmup 1s + measure 1s).
43
+ * Returns 0 for GPU if WebGPU is not available.
44
+ */
45
+ static deviceScore(): Promise<{
46
+ cpuScore: number;
47
+ gpuScore: number;
48
+ }>;
49
+ private static readonly CPU_SCORE_THRESHOLD;
50
+ private static readonly GPU_SCORE_THRESHOLD;
51
+ /**
52
+ * Check if the current device can run the avatar.
53
+ * Runs a ~2s benchmark, reports device info and scores to PostHog.
54
+ * Currently always returns true — thresholds will be calibrated from production data.
55
+ */
56
+ static isDeviceSupported(): Promise<boolean>;
57
+ private static _getGPURenderer;
37
58
  }