realtime-avatar 0.11.3 → 0.11.5

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.
@@ -218,7 +218,7 @@ function isTransient(cause) {
218
218
 
219
219
  // ../http-client/src/client.ts
220
220
  var DEFAULT_BASE_URL = "https://realtimeavatar.ai/api/v1";
221
- var SDK_VERSION = "0.11.3";
221
+ var SDK_VERSION = "0.11.5";
222
222
  var RealtimeAvatar = class {
223
223
  #apiKey;
224
224
  #baseUrl;
@@ -1,4 +1,4 @@
1
- import { RealtimeAvatar, isQueued, RealtimeAvatarHttpError } from './chunk-K726WCDN.js';
1
+ import { RealtimeAvatar, isQueued, RealtimeAvatarHttpError } from './chunk-FAEFGA2G.js';
2
2
 
3
3
  // ../proxy/src/config.ts
4
4
  var json = (body, status = 200) => new Response(JSON.stringify(body), {
package/dist/express.js CHANGED
@@ -1,5 +1,5 @@
1
- import { createProxyHandler } from './chunk-OVAQBIZ2.js';
2
- import './chunk-K726WCDN.js';
1
+ import { createProxyHandler } from './chunk-SML2NB3Q.js';
2
+ import './chunk-FAEFGA2G.js';
3
3
 
4
4
  // ../proxy/src/express.ts
5
5
  function realtimeAvatarExpress(config) {
package/dist/hono.js CHANGED
@@ -1,5 +1,5 @@
1
- import { createProxyHandler } from './chunk-OVAQBIZ2.js';
2
- import './chunk-K726WCDN.js';
1
+ import { createProxyHandler } from './chunk-SML2NB3Q.js';
2
+ import './chunk-FAEFGA2G.js';
3
3
 
4
4
  // ../proxy/src/hono.ts
5
5
  function realtimeAvatarHono(config) {
package/dist/index.js CHANGED
@@ -1 +1 @@
1
- export { RealtimeAvatar, RealtimeAvatarError, RealtimeAvatarHttpError, clipLibraryDeclarationSchema, isQueued, verifyTranscript } from './chunk-K726WCDN.js';
1
+ export { RealtimeAvatar, RealtimeAvatarError, RealtimeAvatarHttpError, clipLibraryDeclarationSchema, isQueued, verifyTranscript } from './chunk-FAEFGA2G.js';
package/dist/nextjs.js CHANGED
@@ -1,5 +1,5 @@
1
- import { createProxyHandler } from './chunk-OVAQBIZ2.js';
2
- import './chunk-K726WCDN.js';
1
+ import { createProxyHandler } from './chunk-SML2NB3Q.js';
2
+ import './chunk-FAEFGA2G.js';
3
3
 
4
4
  // ../proxy/src/nextjs.ts
5
5
  function createRealtimeAvatarRoute(config) {
@@ -723,8 +723,28 @@ var DEFAULT_GOVERNOR_CONFIG = {
723
723
  downgradeFreezeMs: 150,
724
724
  probationFreezeMs: 100,
725
725
  openingDwellMs: 2e3,
726
- dwellBaseMs: 8e3,
727
- dwellMaxMs: 12e4,
726
+ // HOW LONG THE PICTURE STAYS SOFT AFTER A DEMOTE. Swept against this reducer, 300 s per
727
+ // run, five link profiles, scored as switches / percent of time on the top rung / worst
728
+ // single spell on the low cap:
729
+ //
730
+ // profile 8s x 2^n max 120s flat 3s 3s x 2^n max 12s
731
+ // a spurious blip, link fine 2 / 94% / 19s 2 / 98% / 6s 2 / 97% / 9s
732
+ // ordinary jitter, /30s 20 / 61% / 19s 20 / 80% / 6s 20 / 79% / 9s
733
+ // flaky, /10s 9 / 7% / 123s 59 / 40% / 6s 31 / 25% / 15s
734
+ // genuinely bad, 600ms /5s 9 / 4% / 123s 59 / 20% / 8s 31 / 11% / 18s
735
+ //
736
+ // Two things that table says. First, the old `dwellMaxMs` of 120 s was the real damage:
737
+ // a link that is merely flaky could sit soft for TWO MINUTES, which is far worse than
738
+ // the churn the backoff exists to prevent. Second, removing the backoff entirely (flat
739
+ // 3 s) buys the last few points of quality at 59 switches instead of 31, and a switch is
740
+ // a decoder reconfigure plus a keyframe wait, measured at about 1.3 s of dead air on a
741
+ // weak link. So the shape is kept and only the numbers move: start lower, cap far lower.
742
+ //
743
+ // This depends on not charging a layer switch to the link (see the size-change reset in
744
+ // avatar-video-surface). Probing more often is only safe once a failed probe cannot
745
+ // trigger the next demotion by itself.
746
+ dwellBaseMs: 3e3,
747
+ dwellMaxMs: 12e3,
728
748
  cleanMs: 3e3,
729
749
  probeMs: 1e4,
730
750
  healthyResetMs: 12e4
package/dist/react.js CHANGED
@@ -924,8 +924,28 @@ var DEFAULT_GOVERNOR_CONFIG = {
924
924
  downgradeFreezeMs: 150,
925
925
  probationFreezeMs: 100,
926
926
  openingDwellMs: 2e3,
927
- dwellBaseMs: 8e3,
928
- dwellMaxMs: 12e4,
927
+ // HOW LONG THE PICTURE STAYS SOFT AFTER A DEMOTE. Swept against this reducer, 300 s per
928
+ // run, five link profiles, scored as switches / percent of time on the top rung / worst
929
+ // single spell on the low cap:
930
+ //
931
+ // profile 8s x 2^n max 120s flat 3s 3s x 2^n max 12s
932
+ // a spurious blip, link fine 2 / 94% / 19s 2 / 98% / 6s 2 / 97% / 9s
933
+ // ordinary jitter, /30s 20 / 61% / 19s 20 / 80% / 6s 20 / 79% / 9s
934
+ // flaky, /10s 9 / 7% / 123s 59 / 40% / 6s 31 / 25% / 15s
935
+ // genuinely bad, 600ms /5s 9 / 4% / 123s 59 / 20% / 8s 31 / 11% / 18s
936
+ //
937
+ // Two things that table says. First, the old `dwellMaxMs` of 120 s was the real damage:
938
+ // a link that is merely flaky could sit soft for TWO MINUTES, which is far worse than
939
+ // the churn the backoff exists to prevent. Second, removing the backoff entirely (flat
940
+ // 3 s) buys the last few points of quality at 59 switches instead of 31, and a switch is
941
+ // a decoder reconfigure plus a keyframe wait, measured at about 1.3 s of dead air on a
942
+ // weak link. So the shape is kept and only the numbers move: start lower, cap far lower.
943
+ //
944
+ // This depends on not charging a layer switch to the link (see the size-change reset in
945
+ // avatar-video-surface). Probing more often is only safe once a failed probe cannot
946
+ // trigger the next demotion by itself.
947
+ dwellBaseMs: 3e3,
948
+ dwellMaxMs: 12e3,
929
949
  cleanMs: 3e3,
930
950
  probeMs: 1e4,
931
951
  healthyResetMs: 12e4
@@ -1502,7 +1522,8 @@ function useLiveFrameFlow(wrapRef, trackProducing, trackIdentity, stallAfterMs)
1502
1522
  lastFrameAtMs: null,
1503
1523
  maxGapMs: 0,
1504
1524
  resumePending: false,
1505
- producingSinceMs: null
1525
+ producingSinceMs: null,
1526
+ lastSizeKey: null
1506
1527
  });
1507
1528
  useEffect(() => {
1508
1529
  sampleRef.current = {
@@ -1510,7 +1531,8 @@ function useLiveFrameFlow(wrapRef, trackProducing, trackIdentity, stallAfterMs)
1510
1531
  lastFrameAtMs: null,
1511
1532
  maxGapMs: 0,
1512
1533
  resumePending: document.visibilityState !== "visible",
1513
- producingSinceMs: trackProducing ? Date.now() : null
1534
+ producingSinceMs: trackProducing ? Date.now() : null,
1535
+ lastSizeKey: null
1514
1536
  };
1515
1537
  flowingRef.current = false;
1516
1538
  setSeenFrame(false);
@@ -1527,17 +1549,20 @@ function useLiveFrameFlow(wrapRef, trackProducing, trackIdentity, stallAfterMs)
1527
1549
  const now = Date.now();
1528
1550
  lastCurrentTime = video?.currentTime ?? lastCurrentTime;
1529
1551
  const firstFrame = !previous.seenFrame;
1552
+ const sizeKey = `${video?.videoWidth ?? 0}x${video?.videoHeight ?? 0}`;
1553
+ const layerSwitched = previous.lastSizeKey !== null && sizeKey !== previous.lastSizeKey;
1530
1554
  sampleRef.current = {
1531
1555
  producingSinceMs: previous.producingSinceMs,
1532
1556
  seenFrame: true,
1533
1557
  lastFrameAtMs: now,
1534
1558
  // A hidden tab/bfcache resume is a local scheduling gap, not network
1535
1559
  // congestion. The first fresh frame becomes the new baseline.
1536
- maxGapMs: previous.resumePending ? 0 : Math.max(
1560
+ maxGapMs: previous.resumePending || layerSwitched ? 0 : Math.max(
1537
1561
  previous.maxGapMs,
1538
1562
  previous.lastFrameAtMs === null ? 0 : now - previous.lastFrameAtMs
1539
1563
  ),
1540
- resumePending: false
1564
+ resumePending: false,
1565
+ lastSizeKey: sizeKey
1541
1566
  };
1542
1567
  if (firstFrame) setSeenFrame(true);
1543
1568
  recovery.stallAfterMs = escalation.thresholdMs(now);
package/dist/server.js CHANGED
@@ -1 +1 @@
1
- export { RealtimeAvatar, RealtimeAvatarError, RealtimeAvatarHttpError, clipLibraryDeclarationSchema, isQueued, verifyTranscript } from './chunk-K726WCDN.js';
1
+ export { RealtimeAvatar, RealtimeAvatarError, RealtimeAvatarHttpError, clipLibraryDeclarationSchema, isQueued, verifyTranscript } from './chunk-FAEFGA2G.js';
@@ -1,5 +1,5 @@
1
- import { createProxyHandler } from './chunk-OVAQBIZ2.js';
2
- import './chunk-K726WCDN.js';
1
+ import { createProxyHandler } from './chunk-SML2NB3Q.js';
2
+ import './chunk-FAEFGA2G.js';
3
3
 
4
4
  // src/tanstack-start.ts
5
5
  function realtimeAvatarServerRoute(config) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "realtime-avatar",
3
- "version": "0.11.3",
3
+ "version": "0.11.5",
4
4
  "description": "Realtime Avatar SDK. `realtime-avatar` and the route adapters hold your API key and are server-only; `realtime-avatar/react`, `/browser` and `/tools` never can — importing a server entry into a browser build throws at bundle time.",
5
5
  "license": "MIT",
6
6
  "author": "The Influence Company",