realtime-avatar 0.17.0 → 0.18.0
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/dist/{chunk-OESXLLQB.js → chunk-27XNZHSF.js} +20 -2
- package/dist/{chunk-27BB4DQ2.js → chunk-RKIEGOGJ.js} +1 -1
- package/dist/express.d.ts +2 -2
- package/dist/express.js +2 -2
- package/dist/hono.d.ts +2 -2
- package/dist/hono.js +2 -2
- package/dist/index.d.ts +3 -2
- package/dist/index.js +1 -1
- package/dist/nextjs.d.ts +2 -2
- package/dist/nextjs.js +2 -2
- package/dist/react-native.d.ts +2 -2
- package/dist/react-native.js +142 -87
- package/dist/react.d.ts +2 -2
- package/dist/react.js +142 -87
- package/dist/recording.d.ts +2 -2
- package/dist/server.d.ts +1 -1
- package/dist/server.js +1 -1
- package/dist/tanstack-start.d.ts +2 -2
- package/dist/tanstack-start.js +2 -2
- package/dist/{types-CFkiNV3f.d.ts → types-Bzn5PJ0g.d.ts} +1 -1
- package/dist/{types-BnlnrYgN.d.ts → types-CxkszIDK.d.ts} +38 -0
- package/package.json +1 -1
- package/dist/{proxy-client-DmJVj18Z.d.ts → proxy-client-w6prrzGW.d.ts} +1 -1
|
@@ -71,9 +71,27 @@ var clipListSchema = z.array(motionIdSchema).min(1).max(32).superRefine((clips,
|
|
|
71
71
|
seen.add(clip);
|
|
72
72
|
});
|
|
73
73
|
});
|
|
74
|
+
var idleWeightSchema = z.number().min(0).max(100);
|
|
74
75
|
var idleSchema = z.strictObject({
|
|
75
76
|
clips: clipListSchema,
|
|
76
|
-
weight
|
|
77
|
+
/** Legacy aggregate weight. Mutually exclusive with member weights. */
|
|
78
|
+
weight: idleWeightSchema.optional(),
|
|
79
|
+
/** Per-member weights, including `primary`; omitted members default to 1. */
|
|
80
|
+
weights: motionRecord(idleWeightSchema).optional()
|
|
81
|
+
}).superRefine((idle, ctx) => {
|
|
82
|
+
if (idle.weights === void 0) return;
|
|
83
|
+
if (idle.weight !== void 0) {
|
|
84
|
+
ctx.addIssue({ code: "custom", path: ["weight"], message: "Use weight or weights, not both" });
|
|
85
|
+
}
|
|
86
|
+
const members = /* @__PURE__ */ new Set(["primary", ...idle.clips]);
|
|
87
|
+
for (const clip of Object.keys(idle.weights)) {
|
|
88
|
+
if (!members.has(clip)) {
|
|
89
|
+
ctx.addIssue({ code: "custom", path: ["weights", clip], message: "Unknown idle member" });
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
if (![...members].some((clip) => (idle.weights?.[clip] ?? 1) > 0)) {
|
|
93
|
+
ctx.addIssue({ code: "custom", path: ["weights"], message: "Idle pool needs a positive member" });
|
|
94
|
+
}
|
|
77
95
|
});
|
|
78
96
|
var clipActionSchema = z.strictObject({
|
|
79
97
|
description: z.string().trim().min(1).max(512),
|
|
@@ -600,7 +618,7 @@ z.enum([
|
|
|
600
618
|
|
|
601
619
|
// ../http-client/src/client.ts
|
|
602
620
|
var DEFAULT_BASE_URL = "https://realtimeavatar.ai/api/v1";
|
|
603
|
-
var SDK_VERSION = "0.
|
|
621
|
+
var SDK_VERSION = "0.18.0";
|
|
604
622
|
var RealtimeAvatar = class {
|
|
605
623
|
#apiKey;
|
|
606
624
|
#baseUrl;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { RealtimeAvatar, isQueued, RealtimeAvatarHttpError } from './chunk-
|
|
1
|
+
import { RealtimeAvatar, isQueued, RealtimeAvatarHttpError } from './chunk-27XNZHSF.js';
|
|
2
2
|
|
|
3
3
|
// ../proxy/src/config.ts
|
|
4
4
|
var json = (body, status = 200) => new Response(JSON.stringify(body), {
|
package/dist/express.d.ts
CHANGED
package/dist/express.js
CHANGED
package/dist/hono.d.ts
CHANGED
package/dist/hono.js
CHANGED
package/dist/index.d.ts
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
|
-
import { a as CallPolicy, C as CallMode, S as StartCallResult, E as EndCallOptions, A as Avatar, b as AvatarUpdate, c as AvatarSourceSwap, d as ClipLibraryDeclaration, e as ClipLibraryUpdate, L as LoopRedirect, f as ClipLibrary, g as AssetKind, h as Asset, i as ListSessionsOptions, U as UsageSessionPage, j as UsageSession, k as ListRecordingsQuery, l as ListRecordingsResponse, R as RecordingArtifact, m as RecordingAccessResponse, n as CreditBalance, T as TranscriptPayload } from './types-
|
|
2
|
-
export { o as AvatarClip, p as CallConnection, q as CallQueued, r as ClipDeclaration, s as ClipLibraryPlan, t as ClipSource, u as ContextMessage, v as EndCallReason, w as RecordingArtifactStatus, x as RecordingMode, V as VideoPolicy, y as isQueued, z as listRecordingsResponseSchema, B as recordingAccessResponseSchema, D as recordingArtifactSchema, F as recordingModeSchema } from './types-
|
|
1
|
+
import { a as CallPolicy, C as CallMode, S as StartCallResult, E as EndCallOptions, A as Avatar, b as AvatarUpdate, c as AvatarSourceSwap, d as ClipLibraryDeclaration, e as ClipLibraryUpdate, L as LoopRedirect, f as ClipLibrary, g as AssetKind, h as Asset, i as ListSessionsOptions, U as UsageSessionPage, j as UsageSession, k as ListRecordingsQuery, l as ListRecordingsResponse, R as RecordingArtifact, m as RecordingAccessResponse, n as CreditBalance, T as TranscriptPayload } from './types-CxkszIDK.js';
|
|
2
|
+
export { o as AvatarClip, p as CallConnection, q as CallQueued, r as ClipDeclaration, s as ClipLibraryPlan, t as ClipSource, u as ContextMessage, v as EndCallReason, w as RecordingArtifactStatus, x as RecordingMode, V as VideoPolicy, y as isQueued, z as listRecordingsResponseSchema, B as recordingAccessResponseSchema, D as recordingArtifactSchema, F as recordingModeSchema } from './types-CxkszIDK.js';
|
|
3
3
|
import { ConnectionHistoryResponse } from './connection-history.js';
|
|
4
4
|
import { z } from 'zod';
|
|
5
5
|
|
|
@@ -344,6 +344,7 @@ declare const clipLibraryDeclarationSchema: z.ZodObject<{
|
|
|
344
344
|
idle: z.ZodOptional<z.ZodObject<{
|
|
345
345
|
clips: z.ZodArray<z.ZodString>;
|
|
346
346
|
weight: z.ZodOptional<z.ZodNumber>;
|
|
347
|
+
weights: z.ZodOptional<z.ZodPreprocess<z.ZodRecord<z.ZodString, z.ZodNumber>>>;
|
|
347
348
|
}, z.core.$strict>>;
|
|
348
349
|
on: z.ZodOptional<z.ZodObject<{
|
|
349
350
|
userSpeechStarted: z.ZodOptional<z.ZodObject<{
|
package/dist/index.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { RealtimeAvatar, RealtimeAvatarError, RealtimeAvatarHttpError, clipLibraryDeclarationSchema, isQueued, listRecordingsResponseSchema, recordingAccessResponseSchema, recordingArtifactSchema, recordingModeSchema, verifyTranscript } from './chunk-
|
|
1
|
+
export { RealtimeAvatar, RealtimeAvatarError, RealtimeAvatarHttpError, clipLibraryDeclarationSchema, isQueued, listRecordingsResponseSchema, recordingAccessResponseSchema, recordingArtifactSchema, recordingModeSchema, verifyTranscript } from './chunk-27XNZHSF.js';
|
|
2
2
|
import './chunk-MCIXU6XP.js';
|
package/dist/nextjs.d.ts
CHANGED
package/dist/nextjs.js
CHANGED
package/dist/react-native.d.ts
CHANGED
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
import { LiveKitRoomProps } from '@livekit/react-native';
|
|
2
2
|
export { AudioSession, VideoTrack, VideoTrackProps, registerGlobals } from '@livekit/react-native';
|
|
3
3
|
import { ReactNode, ReactElement } from 'react';
|
|
4
|
-
import { L as LiveKitSessionGrant, A as AvatarVideoFit } from './proxy-client-
|
|
5
|
-
export { a as AdaptivePlayoutController, b as AdaptivePlayoutDecision, c as AdaptivePlayoutOptions, d as AdaptivePlayoutSample, e as ApproachingEndEvent, f as ApproachingEndReason, g as AvatarConnectionDetails, h as AvatarSessionClient, B as BehaviorSnapshot, C as CallTranscript, i as CallTranscriptSegment, j as CartesiaTtsModel, k as ClipResult, l as ClosingTurnResult, m as CreditsLowEvent, D as DEFAULT_APPROACHING_END_LEAD_SECONDS, n as DEFAULT_CREDITS_LOW_LEAD_SECONDS, o as DEFAULT_GOVERNOR_CONFIG, p as DEFAULT_GRACE_CEILING_SECONDS, q as DEFAULT_GRACE_WINDOW_LEAD_SECONDS, r as DEFAULT_IDLE_SECONDS, s as DEFAULT_IDLE_WARN_LEAD_SECONDS, t as DEFAULT_TURN_TIMEOUT_SECONDS, E as EndReason, u as EndedEvent, v as ExtendResult, F as FishTtsModel, w as FreezeReadingFn, G as Governor, x as GovernorAction, y as GovernorConfig, z as GovernorSignal, H as GovernorState, I as GraceWindowClosedEvent, J as GraceWindowOpenEvent, K as GraceWindowState, M as IdleWarningEvent, N as InboundRtpCursor, O as InboundRtpReading, P as KnownBehaviorState, Q as LLMProvider, R as LLMSelection, S as LiveKitAvatarGrantState, T as LiveKitAvatarGrantStatus, U as LiveKitCapacityState, V as LiveKitConnectionStatus, W as LiveKitSessionRequest, X as LiveKitSessionStartResult, Y as MAX_RECONNECT_ATTEMPTS, Z as MAX_SESSION_INSTRUCTIONS_CHARS, _ as ProxyClientOptions, $ as QualityCap, a0 as RECONNECT_BACKOFF_MS, a1 as RealtimeAvatarRequestOptions, a2 as RealtimeSessionApi, a3 as RealtimeSessionMedia, a4 as RealtimeSessionRoomSinks, a5 as ReconnectPolicy, a6 as ReconnectingEvent, a7 as RecoveryState, a8 as RetryStep, a9 as SessionBehavior, aa as SessionClip, ab as SessionClocks, ac as SessionEndReason, ad as SessionLifecycleApi, ae as SessionLifecyclePhase, af as SessionLifecyclePhaseKind, ag as SessionLifecycleRoomBridge, ah as SessionLifecycleRoomBridgeProps, ai as SurfaceLayers, aj as TurnState, ak as TurnTimeoutEvent, al as UseAvatarQualityGovernorInput, am as UseLiveKitAvatarGrantInput, an as UseRealtimeSessionInput, ao as UseSessionLifecycleInput, ap as VoiceSpec, aq as VoiceSpecInput, ar as capacityErrorFromBusy, as as capacityStateFromGrant, at as createProxyClient, au as isNativeLiveTrackSubscribed, av as knownBehaviorStates, aw as mapTurnState, ax as readInboundRtp, ay as sessionBehaviorSchema, az as sessionClipSchema, aA as splitCallTranscript, aB as useAvatarAdaptivePlayoutDelay, aC as useAvatarPlayoutDelay, aD as useAvatarQualityGovernor, aE as useCallTranscript, aF as useLiveKitAvatarGrant, aG as useLiveTrackProducing, aH as useMicLease, aI as useRealtimeSession, aJ as useReleaseMicLeaseOnTrackEnded, aK as useSessionLifecycle } from './proxy-client-
|
|
4
|
+
import { L as LiveKitSessionGrant, A as AvatarVideoFit } from './proxy-client-w6prrzGW.js';
|
|
5
|
+
export { a as AdaptivePlayoutController, b as AdaptivePlayoutDecision, c as AdaptivePlayoutOptions, d as AdaptivePlayoutSample, e as ApproachingEndEvent, f as ApproachingEndReason, g as AvatarConnectionDetails, h as AvatarSessionClient, B as BehaviorSnapshot, C as CallTranscript, i as CallTranscriptSegment, j as CartesiaTtsModel, k as ClipResult, l as ClosingTurnResult, m as CreditsLowEvent, D as DEFAULT_APPROACHING_END_LEAD_SECONDS, n as DEFAULT_CREDITS_LOW_LEAD_SECONDS, o as DEFAULT_GOVERNOR_CONFIG, p as DEFAULT_GRACE_CEILING_SECONDS, q as DEFAULT_GRACE_WINDOW_LEAD_SECONDS, r as DEFAULT_IDLE_SECONDS, s as DEFAULT_IDLE_WARN_LEAD_SECONDS, t as DEFAULT_TURN_TIMEOUT_SECONDS, E as EndReason, u as EndedEvent, v as ExtendResult, F as FishTtsModel, w as FreezeReadingFn, G as Governor, x as GovernorAction, y as GovernorConfig, z as GovernorSignal, H as GovernorState, I as GraceWindowClosedEvent, J as GraceWindowOpenEvent, K as GraceWindowState, M as IdleWarningEvent, N as InboundRtpCursor, O as InboundRtpReading, P as KnownBehaviorState, Q as LLMProvider, R as LLMSelection, S as LiveKitAvatarGrantState, T as LiveKitAvatarGrantStatus, U as LiveKitCapacityState, V as LiveKitConnectionStatus, W as LiveKitSessionRequest, X as LiveKitSessionStartResult, Y as MAX_RECONNECT_ATTEMPTS, Z as MAX_SESSION_INSTRUCTIONS_CHARS, _ as ProxyClientOptions, $ as QualityCap, a0 as RECONNECT_BACKOFF_MS, a1 as RealtimeAvatarRequestOptions, a2 as RealtimeSessionApi, a3 as RealtimeSessionMedia, a4 as RealtimeSessionRoomSinks, a5 as ReconnectPolicy, a6 as ReconnectingEvent, a7 as RecoveryState, a8 as RetryStep, a9 as SessionBehavior, aa as SessionClip, ab as SessionClocks, ac as SessionEndReason, ad as SessionLifecycleApi, ae as SessionLifecyclePhase, af as SessionLifecyclePhaseKind, ag as SessionLifecycleRoomBridge, ah as SessionLifecycleRoomBridgeProps, ai as SurfaceLayers, aj as TurnState, ak as TurnTimeoutEvent, al as UseAvatarQualityGovernorInput, am as UseLiveKitAvatarGrantInput, an as UseRealtimeSessionInput, ao as UseSessionLifecycleInput, ap as VoiceSpec, aq as VoiceSpecInput, ar as capacityErrorFromBusy, as as capacityStateFromGrant, at as createProxyClient, au as isNativeLiveTrackSubscribed, av as knownBehaviorStates, aw as mapTurnState, ax as readInboundRtp, ay as sessionBehaviorSchema, az as sessionClipSchema, aA as splitCallTranscript, aB as useAvatarAdaptivePlayoutDelay, aC as useAvatarPlayoutDelay, aD as useAvatarQualityGovernor, aE as useCallTranscript, aF as useLiveKitAvatarGrant, aG as useLiveTrackProducing, aH as useMicLease, aI as useRealtimeSession, aJ as useReleaseMicLeaseOnTrackEnded, aK as useSessionLifecycle } from './proxy-client-w6prrzGW.js';
|
|
6
6
|
import { StyleProp, ViewStyle } from 'react-native';
|
|
7
7
|
export { useChat, useConnectionState, useLocalParticipant, useRoomContext, useTrackToggle, useTranscriptions, useVoiceAssistant } from '@livekit/components-react';
|
|
8
8
|
export { D as DEFAULT_AVATAR_PLAYOUT_DELAY_SECONDS } from './playout-delay-DWOc8iCl.js';
|
package/dist/react-native.js
CHANGED
|
@@ -148,6 +148,131 @@ function playoutDelayTarget(track) {
|
|
|
148
148
|
return typeof candidate?.setPlayoutDelay === "function" ? candidate : void 0;
|
|
149
149
|
}
|
|
150
150
|
|
|
151
|
+
// ../http-client/src/generated/error-semantics.ts
|
|
152
|
+
var ERROR_SEMANTICS = {
|
|
153
|
+
"bad_request": { statuses: [400], message: "Check the request and try again.", retryable: false },
|
|
154
|
+
"unauthorized": { statuses: [401], message: "Authentication is required to use Realtime Avatar.", retryable: false },
|
|
155
|
+
"payment_required": { statuses: [402], message: "Add credits to continue using realtime avatars.", retryable: false },
|
|
156
|
+
"forbidden": { statuses: [403], message: "This API key does not have access to that action.", retryable: false },
|
|
157
|
+
"not_found": { statuses: [404], message: "We could not find that avatar or resource.", retryable: false },
|
|
158
|
+
"method_not_allowed": { statuses: [405], message: "This request method is not supported.", retryable: false },
|
|
159
|
+
"not_acceptable": { statuses: [406], message: "The requested response format is not supported.", retryable: false },
|
|
160
|
+
"request_aborted": { statuses: [408], message: "The session request was cancelled.", retryable: false },
|
|
161
|
+
"conflict": { statuses: [409], message: "That request is already in progress. Try again in a moment.", retryable: true },
|
|
162
|
+
"length_required": { statuses: [411], message: "A request content length is required.", retryable: false },
|
|
163
|
+
"payload_too_large": { statuses: [413], message: "The request is too large.", retryable: false },
|
|
164
|
+
"unprocessable_entity": { statuses: [422], message: "Check the request and try again.", retryable: false },
|
|
165
|
+
"rate_limited": { statuses: [429], message: "Too many realtime requests. Please slow down and retry.", retryable: true },
|
|
166
|
+
"internal_error": { statuses: [500], message: "The session service encountered an error. Try again.", retryable: true },
|
|
167
|
+
"unavailable": { statuses: [503], message: "Realtime Avatar is temporarily unavailable. Try again in a moment.", retryable: true },
|
|
168
|
+
"insufficient_scope": { statuses: [403], message: "This API key is missing a required permission.", retryable: false },
|
|
169
|
+
"loop_pending": { statuses: [409], message: "An avatar loop update is still in progress. Try again shortly.", retryable: true },
|
|
170
|
+
"rate_limit_exceeded": { statuses: [429], message: "Too many realtime requests. Please slow down and retry.", retryable: true },
|
|
171
|
+
"upstream_failed": { statuses: [500, 502, 503], message: "The session service could not complete the request. Try again.", retryable: true },
|
|
172
|
+
"upstream_unreachable": { statuses: [502, 503], message: "The session service could not be reached. Try again.", retryable: true },
|
|
173
|
+
"invalid_upstream_response": { statuses: [502], message: "The session service returned an invalid response. Try again.", retryable: true },
|
|
174
|
+
"upstream_timeout": { statuses: [504], message: "The session service took too long to respond. Try again.", retryable: true },
|
|
175
|
+
"capacity_unavailable": { statuses: [503], message: "Session availability could not be checked. Try again.", retryable: true },
|
|
176
|
+
"session_dispatch_failed": { statuses: [503], message: "The avatar session could not be started. Try again.", retryable: true },
|
|
177
|
+
"admission_unavailable": { statuses: [503], message: "Session admission is temporarily unavailable. Try again.", retryable: true },
|
|
178
|
+
"service_warming": { statuses: [503], message: "Realtime Avatar is warming up. Try again in a moment.", retryable: true },
|
|
179
|
+
"avatar_not_ready": { statuses: [409], message: "This avatar is still being built \u2014 it is usually ready within a minute. Try again then.", retryable: true },
|
|
180
|
+
"clip_library_not_ready": { statuses: [409], message: "This avatar's motion clips are still rendering. Try again in a minute.", retryable: true },
|
|
181
|
+
"recording_unsupported": { statuses: [501], message: "Session recording is not enabled for this deployment.", retryable: false },
|
|
182
|
+
"recording_requires_new_room": { statuses: [422], message: "Recording requires a new session room. Start a fresh session to record it.", retryable: false },
|
|
183
|
+
"recording_unavailable": { statuses: [503], message: "Session recording is temporarily unavailable. Try again in a moment.", retryable: true }
|
|
184
|
+
};
|
|
185
|
+
var UNCOPIED_ERROR_CODES = [
|
|
186
|
+
"capacity_busy",
|
|
187
|
+
"concurrency_limit_reached",
|
|
188
|
+
"insufficient_credits",
|
|
189
|
+
"spend_limit_exceeded",
|
|
190
|
+
"billing_required",
|
|
191
|
+
"network_error"
|
|
192
|
+
];
|
|
193
|
+
var MESSAGE_SHAPE_PATTERNS = { "machine": { "source": "[_=<>{}\\[\\]|\\\\$`]|\\w+\\.\\w+\\.\\w|\\S:\\d|\\w\\(\\)|^\\s*(?:at|File)\\b|\\bTraceback \\(most recent call last\\)", "flags": "mu" }, "locator": { "source": "https?://|/[\\w.-]+/|[\\w.+-]+@[\\w.-]+\\.[a-z]{2,}|\\bbearer\\s|[\\r\\n]", "flags": "i" } };
|
|
194
|
+
var MESSAGE_MAX_LENGTH = 180;
|
|
195
|
+
var SHAPE_TESTS = Object.values(MESSAGE_SHAPE_PATTERNS).map(
|
|
196
|
+
(pattern) => new RegExp(pattern.source, pattern.flags)
|
|
197
|
+
);
|
|
198
|
+
function hasInternalDetail(message) {
|
|
199
|
+
return SHAPE_TESTS.some((pattern) => pattern.test(message));
|
|
200
|
+
}
|
|
201
|
+
function userSafeMessage(message) {
|
|
202
|
+
const trimmed = message.trim();
|
|
203
|
+
if (!trimmed || hasInternalDetail(trimmed)) return null;
|
|
204
|
+
return trimmed.length > MESSAGE_MAX_LENGTH ? `${trimmed.slice(0, MESSAGE_MAX_LENGTH - 3)}...` : trimmed;
|
|
205
|
+
}
|
|
206
|
+
function isCopiedErrorCode(code) {
|
|
207
|
+
return Object.hasOwn(ERROR_SEMANTICS, code);
|
|
208
|
+
}
|
|
209
|
+
function isKnownErrorCode(code) {
|
|
210
|
+
return isCopiedErrorCode(code) || UNCOPIED_ERROR_CODES.some((known) => known === code);
|
|
211
|
+
}
|
|
212
|
+
function semanticsFor(code) {
|
|
213
|
+
return isCopiedErrorCode(code) ? ERROR_SEMANTICS[code] : void 0;
|
|
214
|
+
}
|
|
215
|
+
function semanticsForStatus(status) {
|
|
216
|
+
return Object.values(ERROR_SEMANTICS).find(
|
|
217
|
+
(entry) => entry.statuses.some((allowed) => allowed === status)
|
|
218
|
+
);
|
|
219
|
+
}
|
|
220
|
+
function defaultCodeForStatus(status) {
|
|
221
|
+
const match = Object.entries(ERROR_SEMANTICS).find(
|
|
222
|
+
([, entry]) => entry.statuses.some((allowed) => allowed === status)
|
|
223
|
+
);
|
|
224
|
+
return match ? match[0] : "request_failed";
|
|
225
|
+
}
|
|
226
|
+
function normalizeError(input, overrides) {
|
|
227
|
+
const status = input.status ?? 0;
|
|
228
|
+
const rawCode = input.code?.trim() || null;
|
|
229
|
+
const rawMessage = input.message?.trim() || "";
|
|
230
|
+
if (rawCode) {
|
|
231
|
+
const semantics = semanticsFor(rawCode);
|
|
232
|
+
if (semantics?.statuses.some((allowed) => allowed === status)) {
|
|
233
|
+
return { code: rawCode, message: semantics.message, retryable: semantics.retryable };
|
|
234
|
+
}
|
|
235
|
+
}
|
|
236
|
+
if (status === 402) {
|
|
237
|
+
return {
|
|
238
|
+
code: rawCode === "insufficient_credits" || rawCode === "spend_limit_exceeded" ? rawCode : "billing_required",
|
|
239
|
+
message: userSafeMessage(rawMessage) ?? ERROR_SEMANTICS.payment_required.message,
|
|
240
|
+
retryable: false
|
|
241
|
+
};
|
|
242
|
+
}
|
|
243
|
+
if (status === 429 && rawCode === "concurrency_limit_reached") {
|
|
244
|
+
return {
|
|
245
|
+
code: "concurrency_limit_reached",
|
|
246
|
+
message: userSafeMessage(rawMessage) ?? overrides.concurrencyLimitFallback,
|
|
247
|
+
retryable: true
|
|
248
|
+
};
|
|
249
|
+
}
|
|
250
|
+
if (status === 400 || status === 422) {
|
|
251
|
+
return {
|
|
252
|
+
code: "invalid_request",
|
|
253
|
+
message: userSafeMessage(rawMessage) ?? ERROR_SEMANTICS.bad_request.message,
|
|
254
|
+
retryable: false
|
|
255
|
+
};
|
|
256
|
+
}
|
|
257
|
+
const recognised = !rawCode || isKnownErrorCode(rawCode);
|
|
258
|
+
const byStatus = recognised && status < 500 ? semanticsForStatus(status) : void 0;
|
|
259
|
+
if (byStatus) {
|
|
260
|
+
return {
|
|
261
|
+
code: status === 503 ? "service_unavailable" : defaultCodeForStatus(status),
|
|
262
|
+
message: byStatus.message,
|
|
263
|
+
retryable: byStatus.retryable
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
if (status >= 500) {
|
|
267
|
+
return { code: "service_unavailable", message: ERROR_SEMANTICS.unavailable.message, retryable: true };
|
|
268
|
+
}
|
|
269
|
+
return {
|
|
270
|
+
code: status === 0 && rawCode === "network_error" ? "network_error" : "request_failed",
|
|
271
|
+
message: userSafeMessage(rawMessage) ?? overrides.requestFailedFallback,
|
|
272
|
+
retryable: status === 0 || status >= 500
|
|
273
|
+
};
|
|
274
|
+
}
|
|
275
|
+
|
|
151
276
|
// ../client/src/errors.ts
|
|
152
277
|
var RealtimeAvatarApiError = class _RealtimeAvatarApiError extends Error {
|
|
153
278
|
constructor(message, status, body, response, metadata = {}) {
|
|
@@ -206,72 +331,27 @@ var RealtimeAvatarCapacityError = class extends Error {
|
|
|
206
331
|
return this.busy.recommended_retry_ms;
|
|
207
332
|
}
|
|
208
333
|
};
|
|
334
|
+
function readRecord(value) {
|
|
335
|
+
return typeof value === "object" && value !== null ? { ...value } : null;
|
|
336
|
+
}
|
|
209
337
|
function extractErrorMessage(body) {
|
|
210
|
-
if (
|
|
211
|
-
const record = body;
|
|
212
|
-
|
|
213
|
-
|
|
214
|
-
const error = readMessageValue(record.error);
|
|
215
|
-
if (error) return error;
|
|
216
|
-
const message = readMessageValue(record.message);
|
|
217
|
-
if (message) return message;
|
|
218
|
-
return null;
|
|
338
|
+
if (typeof body === "string") return body || null;
|
|
339
|
+
const record = readRecord(body);
|
|
340
|
+
if (!record) return null;
|
|
341
|
+
return readMessageValue(record.detail) ?? readMessageValue(record.error) ?? readMessageValue(record.message);
|
|
219
342
|
}
|
|
220
343
|
function normalizeRealtimeAvatarError(input) {
|
|
221
|
-
|
|
222
|
-
|
|
223
|
-
|
|
224
|
-
|
|
225
|
-
if (rawCode === "insufficient_credits" || rawCode === "spend_limit_exceeded" || status === 402) {
|
|
226
|
-
return {
|
|
227
|
-
code: rawCode ?? "billing_required",
|
|
228
|
-
message: rawMessage && !hasInternalDetail(rawMessage) ? rawMessage : "Add credits to continue using realtime avatars.",
|
|
229
|
-
retryable: false
|
|
230
|
-
};
|
|
231
|
-
}
|
|
232
|
-
if (status === 401) {
|
|
233
|
-
return { code: "unauthorized", message: "Authentication is required to use Realtime Avatar.", retryable: false };
|
|
234
|
-
}
|
|
235
|
-
if (status === 403) {
|
|
236
|
-
return { code: "forbidden", message: "This API key does not have access to that action.", retryable: false };
|
|
237
|
-
}
|
|
238
|
-
if (status === 404 || blob.includes("unknown avatar_id") || blob.includes("avatar not found")) {
|
|
239
|
-
return { code: "not_found", message: "We could not find that avatar or resource.", retryable: false };
|
|
240
|
-
}
|
|
241
|
-
if (status === 409) {
|
|
242
|
-
return { code: "conflict", message: "That request is already in progress. Try again in a moment.", retryable: true };
|
|
243
|
-
}
|
|
244
|
-
if (status === 429 && rawCode === "concurrency_limit_reached") {
|
|
245
|
-
return {
|
|
246
|
-
code: rawCode,
|
|
247
|
-
message: userSafeMessage(rawMessage) ?? "The concurrent session limit is reached. Active and starting sessions count. End a session or wait for pending starts to clear, then retry.",
|
|
248
|
-
retryable: true
|
|
249
|
-
};
|
|
250
|
-
}
|
|
251
|
-
if (status === 429) {
|
|
252
|
-
return { code: "rate_limited", message: "Too many realtime requests. Please slow down and retry.", retryable: true };
|
|
253
|
-
}
|
|
254
|
-
if (isWarmingMessage(blob)) {
|
|
255
|
-
return { code: "service_unavailable", message: "Realtime Avatar is warming up. Try again in a moment.", retryable: true };
|
|
256
|
-
}
|
|
257
|
-
if (status === 400 || status === 422) {
|
|
258
|
-
return { code: "invalid_request", message: userSafeMessage(rawMessage) ?? "Check the request and try again.", retryable: false };
|
|
259
|
-
}
|
|
260
|
-
if (status >= 500) {
|
|
261
|
-
return { code: "service_unavailable", message: "Realtime Avatar is temporarily unavailable. Try again in a moment.", retryable: true };
|
|
262
|
-
}
|
|
263
|
-
return {
|
|
264
|
-
code: isPublicErrorCode(rawCode) ? rawCode : "request_failed",
|
|
265
|
-
message: userSafeMessage(rawMessage) ?? "Realtime Avatar request failed. Try again.",
|
|
266
|
-
retryable: status === 0 || status >= 500
|
|
267
|
-
};
|
|
344
|
+
return normalizeError(input, {
|
|
345
|
+
concurrencyLimitFallback: CONCURRENCY_LIMIT_FALLBACK_MESSAGE,
|
|
346
|
+
requestFailedFallback: "Realtime Avatar request failed. Try again."
|
|
347
|
+
});
|
|
268
348
|
}
|
|
269
349
|
function extractErrorMetadata(body, status, rawMessage) {
|
|
270
|
-
|
|
350
|
+
const record = readRecord(body);
|
|
351
|
+
if (!record) {
|
|
271
352
|
const normalized2 = normalizeRealtimeAvatarError({ status, message: rawMessage });
|
|
272
353
|
return { ...normalized2, rawMessage };
|
|
273
354
|
}
|
|
274
|
-
const record = body;
|
|
275
355
|
const code = typeof record.code === "string" ? record.code : null;
|
|
276
356
|
const normalized = normalizeRealtimeAvatarError({ status, code, message: rawMessage });
|
|
277
357
|
return {
|
|
@@ -282,38 +362,13 @@ function extractErrorMetadata(body, status, rawMessage) {
|
|
|
282
362
|
message: normalized.message
|
|
283
363
|
};
|
|
284
364
|
}
|
|
285
|
-
var
|
|
286
|
-
"billing_required",
|
|
287
|
-
"invalid_request",
|
|
288
|
-
"unauthorized",
|
|
289
|
-
"forbidden",
|
|
290
|
-
"not_found",
|
|
291
|
-
"conflict",
|
|
292
|
-
"rate_limited",
|
|
293
|
-
"service_unavailable",
|
|
294
|
-
"request_failed",
|
|
295
|
-
"network_error"
|
|
296
|
-
]);
|
|
297
|
-
function isPublicErrorCode(code) {
|
|
298
|
-
return Boolean(code && PUBLIC_ERROR_CODES.has(code));
|
|
299
|
-
}
|
|
365
|
+
var CONCURRENCY_LIMIT_FALLBACK_MESSAGE = "The concurrent session limit is reached. Active and starting sessions count. End a session or wait for pending starts to clear, then retry.";
|
|
300
366
|
function readMessageValue(value) {
|
|
301
367
|
if (typeof value === "string") return value.trim() || null;
|
|
302
|
-
|
|
303
|
-
|
|
368
|
+
const record = readRecord(value);
|
|
369
|
+
if (!record) return null;
|
|
304
370
|
return readMessageValue(record.message) ?? readMessageValue(record.error) ?? readMessageValue(record.detail);
|
|
305
371
|
}
|
|
306
|
-
function userSafeMessage(message) {
|
|
307
|
-
if (!message || hasInternalDetail(message)) return null;
|
|
308
|
-
return message.length > 180 ? `${message.slice(0, 177)}...` : message;
|
|
309
|
-
}
|
|
310
|
-
function isWarmingMessage(blob) {
|
|
311
|
-
return blob.includes("warming") || blob.includes("not ready") || blob.includes("starting up");
|
|
312
|
-
}
|
|
313
|
-
var MACHINE_SHAPED = /[_=<>{}\[\]|\\$`]|\w+\.\w+\.\w|\S:\d|\w\(\)|^\s*(?:at|File)\b/mu;
|
|
314
|
-
function hasInternalDetail(message) {
|
|
315
|
-
return MACHINE_SHAPED.test(message);
|
|
316
|
-
}
|
|
317
372
|
function splitCallTranscript(all, localIdentity) {
|
|
318
373
|
if (!localIdentity) return { user: [], agent: all };
|
|
319
374
|
const user = [];
|
|
@@ -2383,7 +2438,7 @@ function SessionLifecycleRoomBridge({
|
|
|
2383
2438
|
}, [connectionHistoryGrant, detailsSessionId]);
|
|
2384
2439
|
useEffect(() => {
|
|
2385
2440
|
const collector = connectionHistoryRef.current;
|
|
2386
|
-
if (!collector || typeof window === "undefined") return;
|
|
2441
|
+
if (!collector || typeof window === "undefined" || typeof window.addEventListener !== "function" || typeof window.removeEventListener !== "function") return;
|
|
2387
2442
|
const flush = () => {
|
|
2388
2443
|
void collector.flush();
|
|
2389
2444
|
};
|
package/dist/react.d.ts
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { RegisteredTool, ToolRegistration } from './tools.js';
|
|
2
2
|
import { ReactNode } from 'react';
|
|
3
|
-
import { ah as SessionLifecycleRoomBridgeProps, h as AvatarSessionClient, A as AvatarVideoFit } from './proxy-client-
|
|
4
|
-
export { a as AdaptivePlayoutController, b as AdaptivePlayoutDecision, c as AdaptivePlayoutOptions, d as AdaptivePlayoutSample, e as ApproachingEndEvent, f as ApproachingEndReason, g as AvatarConnectionDetails, aL as AvatarVideoSurface, aM as AvatarVideoSurfaceProps, B as BehaviorSnapshot, C as CallTranscript, i as CallTranscriptSegment, j as CartesiaTtsModel, k as ClipResult, l as ClosingTurnResult, m as CreditsLowEvent, D as DEFAULT_APPROACHING_END_LEAD_SECONDS, n as DEFAULT_CREDITS_LOW_LEAD_SECONDS, o as DEFAULT_GOVERNOR_CONFIG, p as DEFAULT_GRACE_CEILING_SECONDS, q as DEFAULT_GRACE_WINDOW_LEAD_SECONDS, r as DEFAULT_IDLE_SECONDS, s as DEFAULT_IDLE_WARN_LEAD_SECONDS, t as DEFAULT_TURN_TIMEOUT_SECONDS, E as EndReason, u as EndedEvent, v as ExtendResult, F as FishTtsModel, w as FreezeReadingFn, G as Governor, x as GovernorAction, y as GovernorConfig, z as GovernorSignal, H as GovernorState, I as GraceWindowClosedEvent, J as GraceWindowOpenEvent, K as GraceWindowState, M as IdleWarningEvent, N as InboundRtpCursor, O as InboundRtpReading, P as KnownBehaviorState, Q as LLMProvider, R as LLMSelection, S as LiveKitAvatarGrantState, T as LiveKitAvatarGrantStatus, U as LiveKitCapacityState, V as LiveKitConnectionStatus, W as LiveKitSessionRequest, X as LiveKitSessionStartResult, aN as LivePlaybackKeeper, Y as MAX_RECONNECT_ATTEMPTS, Z as MAX_SESSION_INSTRUCTIONS_CHARS, aO as MIC_LEASE_ENDED_TIMEOUT_MS, aP as MicLease, aQ as NETWORK_QUALITY_POLICY, aR as NetworkQualityStatus, aS as PlayableVideoElement, _ as ProxyClientOptions, $ as QualityCap, a0 as RECONNECT_BACKOFF_MS, aT as RealtimeAvatarCapacityError, aU as RealtimeAvatarLiveKitRoom, aV as RealtimeAvatarLiveKitRoomProps, a1 as RealtimeAvatarRequestOptions, a2 as RealtimeSessionApi, a3 as RealtimeSessionMedia, a4 as RealtimeSessionRoomSinks, a5 as ReconnectPolicy, a6 as ReconnectingEvent, a7 as RecoveryState, a8 as RetryStep, a9 as SessionBehavior, aa as SessionClip, ab as SessionClocks, ac as SessionEndReason, ad as SessionLifecycleApi, ae as SessionLifecyclePhase, af as SessionLifecyclePhaseKind, ag as SessionLifecycleRoomBridge, ai as SurfaceLayers, aj as TurnState, ak as TurnTimeoutEvent, al as UseAvatarQualityGovernorInput, am as UseLiveKitAvatarGrantInput, an as UseRealtimeSessionInput, ao as UseSessionLifecycleInput, ap as VoiceSpec, aq as VoiceSpecInput, ar as capacityErrorFromBusy, as as capacityStateFromGrant, at as createProxyClient, av as knownBehaviorStates, aw as mapTurnState, ax as readInboundRtp, ay as sessionBehaviorSchema, az as sessionClipSchema, aW as shouldReplayPendingTurn, aA as splitCallTranscript, aB as useAvatarAdaptivePlayoutDelay, aC as useAvatarPlayoutDelay, aD as useAvatarQualityGovernor, aE as useCallTranscript, aF as useLiveKitAvatarGrant, aH as useMicLease, aI as useRealtimeSession, aJ as useReleaseMicLeaseOnTrackEnded, aK as useSessionLifecycle } from './proxy-client-
|
|
3
|
+
import { ah as SessionLifecycleRoomBridgeProps, h as AvatarSessionClient, A as AvatarVideoFit } from './proxy-client-w6prrzGW.js';
|
|
4
|
+
export { a as AdaptivePlayoutController, b as AdaptivePlayoutDecision, c as AdaptivePlayoutOptions, d as AdaptivePlayoutSample, e as ApproachingEndEvent, f as ApproachingEndReason, g as AvatarConnectionDetails, aL as AvatarVideoSurface, aM as AvatarVideoSurfaceProps, B as BehaviorSnapshot, C as CallTranscript, i as CallTranscriptSegment, j as CartesiaTtsModel, k as ClipResult, l as ClosingTurnResult, m as CreditsLowEvent, D as DEFAULT_APPROACHING_END_LEAD_SECONDS, n as DEFAULT_CREDITS_LOW_LEAD_SECONDS, o as DEFAULT_GOVERNOR_CONFIG, p as DEFAULT_GRACE_CEILING_SECONDS, q as DEFAULT_GRACE_WINDOW_LEAD_SECONDS, r as DEFAULT_IDLE_SECONDS, s as DEFAULT_IDLE_WARN_LEAD_SECONDS, t as DEFAULT_TURN_TIMEOUT_SECONDS, E as EndReason, u as EndedEvent, v as ExtendResult, F as FishTtsModel, w as FreezeReadingFn, G as Governor, x as GovernorAction, y as GovernorConfig, z as GovernorSignal, H as GovernorState, I as GraceWindowClosedEvent, J as GraceWindowOpenEvent, K as GraceWindowState, M as IdleWarningEvent, N as InboundRtpCursor, O as InboundRtpReading, P as KnownBehaviorState, Q as LLMProvider, R as LLMSelection, S as LiveKitAvatarGrantState, T as LiveKitAvatarGrantStatus, U as LiveKitCapacityState, V as LiveKitConnectionStatus, W as LiveKitSessionRequest, X as LiveKitSessionStartResult, aN as LivePlaybackKeeper, Y as MAX_RECONNECT_ATTEMPTS, Z as MAX_SESSION_INSTRUCTIONS_CHARS, aO as MIC_LEASE_ENDED_TIMEOUT_MS, aP as MicLease, aQ as NETWORK_QUALITY_POLICY, aR as NetworkQualityStatus, aS as PlayableVideoElement, _ as ProxyClientOptions, $ as QualityCap, a0 as RECONNECT_BACKOFF_MS, aT as RealtimeAvatarCapacityError, aU as RealtimeAvatarLiveKitRoom, aV as RealtimeAvatarLiveKitRoomProps, a1 as RealtimeAvatarRequestOptions, a2 as RealtimeSessionApi, a3 as RealtimeSessionMedia, a4 as RealtimeSessionRoomSinks, a5 as ReconnectPolicy, a6 as ReconnectingEvent, a7 as RecoveryState, a8 as RetryStep, a9 as SessionBehavior, aa as SessionClip, ab as SessionClocks, ac as SessionEndReason, ad as SessionLifecycleApi, ae as SessionLifecyclePhase, af as SessionLifecyclePhaseKind, ag as SessionLifecycleRoomBridge, ai as SurfaceLayers, aj as TurnState, ak as TurnTimeoutEvent, al as UseAvatarQualityGovernorInput, am as UseLiveKitAvatarGrantInput, an as UseRealtimeSessionInput, ao as UseSessionLifecycleInput, ap as VoiceSpec, aq as VoiceSpecInput, ar as capacityErrorFromBusy, as as capacityStateFromGrant, at as createProxyClient, av as knownBehaviorStates, aw as mapTurnState, ax as readInboundRtp, ay as sessionBehaviorSchema, az as sessionClipSchema, aW as shouldReplayPendingTurn, aA as splitCallTranscript, aB as useAvatarAdaptivePlayoutDelay, aC as useAvatarPlayoutDelay, aD as useAvatarQualityGovernor, aE as useCallTranscript, aF as useLiveKitAvatarGrant, aH as useMicLease, aI as useRealtimeSession, aJ as useReleaseMicLeaseOnTrackEnded, aK as useSessionLifecycle } from './proxy-client-w6prrzGW.js';
|
|
5
5
|
export { D as DEFAULT_AVATAR_PLAYOUT_DELAY_SECONDS } from './playout-delay-DWOc8iCl.js';
|
|
6
6
|
import 'zod';
|
|
7
7
|
import '@livekit/components-react';
|
package/dist/react.js
CHANGED
|
@@ -301,6 +301,131 @@ function playoutDelayTarget(track) {
|
|
|
301
301
|
return typeof candidate?.setPlayoutDelay === "function" ? candidate : void 0;
|
|
302
302
|
}
|
|
303
303
|
|
|
304
|
+
// ../http-client/src/generated/error-semantics.ts
|
|
305
|
+
var ERROR_SEMANTICS = {
|
|
306
|
+
"bad_request": { statuses: [400], message: "Check the request and try again.", retryable: false },
|
|
307
|
+
"unauthorized": { statuses: [401], message: "Authentication is required to use Realtime Avatar.", retryable: false },
|
|
308
|
+
"payment_required": { statuses: [402], message: "Add credits to continue using realtime avatars.", retryable: false },
|
|
309
|
+
"forbidden": { statuses: [403], message: "This API key does not have access to that action.", retryable: false },
|
|
310
|
+
"not_found": { statuses: [404], message: "We could not find that avatar or resource.", retryable: false },
|
|
311
|
+
"method_not_allowed": { statuses: [405], message: "This request method is not supported.", retryable: false },
|
|
312
|
+
"not_acceptable": { statuses: [406], message: "The requested response format is not supported.", retryable: false },
|
|
313
|
+
"request_aborted": { statuses: [408], message: "The session request was cancelled.", retryable: false },
|
|
314
|
+
"conflict": { statuses: [409], message: "That request is already in progress. Try again in a moment.", retryable: true },
|
|
315
|
+
"length_required": { statuses: [411], message: "A request content length is required.", retryable: false },
|
|
316
|
+
"payload_too_large": { statuses: [413], message: "The request is too large.", retryable: false },
|
|
317
|
+
"unprocessable_entity": { statuses: [422], message: "Check the request and try again.", retryable: false },
|
|
318
|
+
"rate_limited": { statuses: [429], message: "Too many realtime requests. Please slow down and retry.", retryable: true },
|
|
319
|
+
"internal_error": { statuses: [500], message: "The session service encountered an error. Try again.", retryable: true },
|
|
320
|
+
"unavailable": { statuses: [503], message: "Realtime Avatar is temporarily unavailable. Try again in a moment.", retryable: true },
|
|
321
|
+
"insufficient_scope": { statuses: [403], message: "This API key is missing a required permission.", retryable: false },
|
|
322
|
+
"loop_pending": { statuses: [409], message: "An avatar loop update is still in progress. Try again shortly.", retryable: true },
|
|
323
|
+
"rate_limit_exceeded": { statuses: [429], message: "Too many realtime requests. Please slow down and retry.", retryable: true },
|
|
324
|
+
"upstream_failed": { statuses: [500, 502, 503], message: "The session service could not complete the request. Try again.", retryable: true },
|
|
325
|
+
"upstream_unreachable": { statuses: [502, 503], message: "The session service could not be reached. Try again.", retryable: true },
|
|
326
|
+
"invalid_upstream_response": { statuses: [502], message: "The session service returned an invalid response. Try again.", retryable: true },
|
|
327
|
+
"upstream_timeout": { statuses: [504], message: "The session service took too long to respond. Try again.", retryable: true },
|
|
328
|
+
"capacity_unavailable": { statuses: [503], message: "Session availability could not be checked. Try again.", retryable: true },
|
|
329
|
+
"session_dispatch_failed": { statuses: [503], message: "The avatar session could not be started. Try again.", retryable: true },
|
|
330
|
+
"admission_unavailable": { statuses: [503], message: "Session admission is temporarily unavailable. Try again.", retryable: true },
|
|
331
|
+
"service_warming": { statuses: [503], message: "Realtime Avatar is warming up. Try again in a moment.", retryable: true },
|
|
332
|
+
"avatar_not_ready": { statuses: [409], message: "This avatar is still being built \u2014 it is usually ready within a minute. Try again then.", retryable: true },
|
|
333
|
+
"clip_library_not_ready": { statuses: [409], message: "This avatar's motion clips are still rendering. Try again in a minute.", retryable: true },
|
|
334
|
+
"recording_unsupported": { statuses: [501], message: "Session recording is not enabled for this deployment.", retryable: false },
|
|
335
|
+
"recording_requires_new_room": { statuses: [422], message: "Recording requires a new session room. Start a fresh session to record it.", retryable: false },
|
|
336
|
+
"recording_unavailable": { statuses: [503], message: "Session recording is temporarily unavailable. Try again in a moment.", retryable: true }
|
|
337
|
+
};
|
|
338
|
+
var UNCOPIED_ERROR_CODES = [
|
|
339
|
+
"capacity_busy",
|
|
340
|
+
"concurrency_limit_reached",
|
|
341
|
+
"insufficient_credits",
|
|
342
|
+
"spend_limit_exceeded",
|
|
343
|
+
"billing_required",
|
|
344
|
+
"network_error"
|
|
345
|
+
];
|
|
346
|
+
var MESSAGE_SHAPE_PATTERNS = { "machine": { "source": "[_=<>{}\\[\\]|\\\\$`]|\\w+\\.\\w+\\.\\w|\\S:\\d|\\w\\(\\)|^\\s*(?:at|File)\\b|\\bTraceback \\(most recent call last\\)", "flags": "mu" }, "locator": { "source": "https?://|/[\\w.-]+/|[\\w.+-]+@[\\w.-]+\\.[a-z]{2,}|\\bbearer\\s|[\\r\\n]", "flags": "i" } };
|
|
347
|
+
var MESSAGE_MAX_LENGTH = 180;
|
|
348
|
+
var SHAPE_TESTS = Object.values(MESSAGE_SHAPE_PATTERNS).map(
|
|
349
|
+
(pattern) => new RegExp(pattern.source, pattern.flags)
|
|
350
|
+
);
|
|
351
|
+
function hasInternalDetail(message) {
|
|
352
|
+
return SHAPE_TESTS.some((pattern) => pattern.test(message));
|
|
353
|
+
}
|
|
354
|
+
function userSafeMessage(message) {
|
|
355
|
+
const trimmed = message.trim();
|
|
356
|
+
if (!trimmed || hasInternalDetail(trimmed)) return null;
|
|
357
|
+
return trimmed.length > MESSAGE_MAX_LENGTH ? `${trimmed.slice(0, MESSAGE_MAX_LENGTH - 3)}...` : trimmed;
|
|
358
|
+
}
|
|
359
|
+
function isCopiedErrorCode(code) {
|
|
360
|
+
return Object.hasOwn(ERROR_SEMANTICS, code);
|
|
361
|
+
}
|
|
362
|
+
function isKnownErrorCode(code) {
|
|
363
|
+
return isCopiedErrorCode(code) || UNCOPIED_ERROR_CODES.some((known) => known === code);
|
|
364
|
+
}
|
|
365
|
+
function semanticsFor(code) {
|
|
366
|
+
return isCopiedErrorCode(code) ? ERROR_SEMANTICS[code] : void 0;
|
|
367
|
+
}
|
|
368
|
+
function semanticsForStatus(status) {
|
|
369
|
+
return Object.values(ERROR_SEMANTICS).find(
|
|
370
|
+
(entry) => entry.statuses.some((allowed) => allowed === status)
|
|
371
|
+
);
|
|
372
|
+
}
|
|
373
|
+
function defaultCodeForStatus(status) {
|
|
374
|
+
const match = Object.entries(ERROR_SEMANTICS).find(
|
|
375
|
+
([, entry]) => entry.statuses.some((allowed) => allowed === status)
|
|
376
|
+
);
|
|
377
|
+
return match ? match[0] : "request_failed";
|
|
378
|
+
}
|
|
379
|
+
function normalizeError(input, overrides) {
|
|
380
|
+
const status = input.status ?? 0;
|
|
381
|
+
const rawCode = input.code?.trim() || null;
|
|
382
|
+
const rawMessage = input.message?.trim() || "";
|
|
383
|
+
if (rawCode) {
|
|
384
|
+
const semantics = semanticsFor(rawCode);
|
|
385
|
+
if (semantics?.statuses.some((allowed) => allowed === status)) {
|
|
386
|
+
return { code: rawCode, message: semantics.message, retryable: semantics.retryable };
|
|
387
|
+
}
|
|
388
|
+
}
|
|
389
|
+
if (status === 402) {
|
|
390
|
+
return {
|
|
391
|
+
code: rawCode === "insufficient_credits" || rawCode === "spend_limit_exceeded" ? rawCode : "billing_required",
|
|
392
|
+
message: userSafeMessage(rawMessage) ?? ERROR_SEMANTICS.payment_required.message,
|
|
393
|
+
retryable: false
|
|
394
|
+
};
|
|
395
|
+
}
|
|
396
|
+
if (status === 429 && rawCode === "concurrency_limit_reached") {
|
|
397
|
+
return {
|
|
398
|
+
code: "concurrency_limit_reached",
|
|
399
|
+
message: userSafeMessage(rawMessage) ?? overrides.concurrencyLimitFallback,
|
|
400
|
+
retryable: true
|
|
401
|
+
};
|
|
402
|
+
}
|
|
403
|
+
if (status === 400 || status === 422) {
|
|
404
|
+
return {
|
|
405
|
+
code: "invalid_request",
|
|
406
|
+
message: userSafeMessage(rawMessage) ?? ERROR_SEMANTICS.bad_request.message,
|
|
407
|
+
retryable: false
|
|
408
|
+
};
|
|
409
|
+
}
|
|
410
|
+
const recognised = !rawCode || isKnownErrorCode(rawCode);
|
|
411
|
+
const byStatus = recognised && status < 500 ? semanticsForStatus(status) : void 0;
|
|
412
|
+
if (byStatus) {
|
|
413
|
+
return {
|
|
414
|
+
code: status === 503 ? "service_unavailable" : defaultCodeForStatus(status),
|
|
415
|
+
message: byStatus.message,
|
|
416
|
+
retryable: byStatus.retryable
|
|
417
|
+
};
|
|
418
|
+
}
|
|
419
|
+
if (status >= 500) {
|
|
420
|
+
return { code: "service_unavailable", message: ERROR_SEMANTICS.unavailable.message, retryable: true };
|
|
421
|
+
}
|
|
422
|
+
return {
|
|
423
|
+
code: status === 0 && rawCode === "network_error" ? "network_error" : "request_failed",
|
|
424
|
+
message: userSafeMessage(rawMessage) ?? overrides.requestFailedFallback,
|
|
425
|
+
retryable: status === 0 || status >= 500
|
|
426
|
+
};
|
|
427
|
+
}
|
|
428
|
+
|
|
304
429
|
// ../client/src/errors.ts
|
|
305
430
|
var RealtimeAvatarApiError = class _RealtimeAvatarApiError extends Error {
|
|
306
431
|
constructor(message, status, body, response, metadata = {}) {
|
|
@@ -359,72 +484,27 @@ var RealtimeAvatarCapacityError = class extends Error {
|
|
|
359
484
|
return this.busy.recommended_retry_ms;
|
|
360
485
|
}
|
|
361
486
|
};
|
|
487
|
+
function readRecord(value) {
|
|
488
|
+
return typeof value === "object" && value !== null ? { ...value } : null;
|
|
489
|
+
}
|
|
362
490
|
function extractErrorMessage(body) {
|
|
363
|
-
if (
|
|
364
|
-
const record = body;
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
const error = readMessageValue(record.error);
|
|
368
|
-
if (error) return error;
|
|
369
|
-
const message = readMessageValue(record.message);
|
|
370
|
-
if (message) return message;
|
|
371
|
-
return null;
|
|
491
|
+
if (typeof body === "string") return body || null;
|
|
492
|
+
const record = readRecord(body);
|
|
493
|
+
if (!record) return null;
|
|
494
|
+
return readMessageValue(record.detail) ?? readMessageValue(record.error) ?? readMessageValue(record.message);
|
|
372
495
|
}
|
|
373
496
|
function normalizeRealtimeAvatarError(input) {
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
if (rawCode === "insufficient_credits" || rawCode === "spend_limit_exceeded" || status === 402) {
|
|
379
|
-
return {
|
|
380
|
-
code: rawCode ?? "billing_required",
|
|
381
|
-
message: rawMessage && !hasInternalDetail(rawMessage) ? rawMessage : "Add credits to continue using realtime avatars.",
|
|
382
|
-
retryable: false
|
|
383
|
-
};
|
|
384
|
-
}
|
|
385
|
-
if (status === 401) {
|
|
386
|
-
return { code: "unauthorized", message: "Authentication is required to use Realtime Avatar.", retryable: false };
|
|
387
|
-
}
|
|
388
|
-
if (status === 403) {
|
|
389
|
-
return { code: "forbidden", message: "This API key does not have access to that action.", retryable: false };
|
|
390
|
-
}
|
|
391
|
-
if (status === 404 || blob.includes("unknown avatar_id") || blob.includes("avatar not found")) {
|
|
392
|
-
return { code: "not_found", message: "We could not find that avatar or resource.", retryable: false };
|
|
393
|
-
}
|
|
394
|
-
if (status === 409) {
|
|
395
|
-
return { code: "conflict", message: "That request is already in progress. Try again in a moment.", retryable: true };
|
|
396
|
-
}
|
|
397
|
-
if (status === 429 && rawCode === "concurrency_limit_reached") {
|
|
398
|
-
return {
|
|
399
|
-
code: rawCode,
|
|
400
|
-
message: userSafeMessage(rawMessage) ?? "The concurrent session limit is reached. Active and starting sessions count. End a session or wait for pending starts to clear, then retry.",
|
|
401
|
-
retryable: true
|
|
402
|
-
};
|
|
403
|
-
}
|
|
404
|
-
if (status === 429) {
|
|
405
|
-
return { code: "rate_limited", message: "Too many realtime requests. Please slow down and retry.", retryable: true };
|
|
406
|
-
}
|
|
407
|
-
if (isWarmingMessage(blob)) {
|
|
408
|
-
return { code: "service_unavailable", message: "Realtime Avatar is warming up. Try again in a moment.", retryable: true };
|
|
409
|
-
}
|
|
410
|
-
if (status === 400 || status === 422) {
|
|
411
|
-
return { code: "invalid_request", message: userSafeMessage(rawMessage) ?? "Check the request and try again.", retryable: false };
|
|
412
|
-
}
|
|
413
|
-
if (status >= 500) {
|
|
414
|
-
return { code: "service_unavailable", message: "Realtime Avatar is temporarily unavailable. Try again in a moment.", retryable: true };
|
|
415
|
-
}
|
|
416
|
-
return {
|
|
417
|
-
code: isPublicErrorCode(rawCode) ? rawCode : "request_failed",
|
|
418
|
-
message: userSafeMessage(rawMessage) ?? "Realtime Avatar request failed. Try again.",
|
|
419
|
-
retryable: status === 0 || status >= 500
|
|
420
|
-
};
|
|
497
|
+
return normalizeError(input, {
|
|
498
|
+
concurrencyLimitFallback: CONCURRENCY_LIMIT_FALLBACK_MESSAGE,
|
|
499
|
+
requestFailedFallback: "Realtime Avatar request failed. Try again."
|
|
500
|
+
});
|
|
421
501
|
}
|
|
422
502
|
function extractErrorMetadata(body, status, rawMessage) {
|
|
423
|
-
|
|
503
|
+
const record = readRecord(body);
|
|
504
|
+
if (!record) {
|
|
424
505
|
const normalized2 = normalizeRealtimeAvatarError({ status, message: rawMessage });
|
|
425
506
|
return { ...normalized2, rawMessage };
|
|
426
507
|
}
|
|
427
|
-
const record = body;
|
|
428
508
|
const code = typeof record.code === "string" ? record.code : null;
|
|
429
509
|
const normalized = normalizeRealtimeAvatarError({ status, code, message: rawMessage });
|
|
430
510
|
return {
|
|
@@ -435,38 +515,13 @@ function extractErrorMetadata(body, status, rawMessage) {
|
|
|
435
515
|
message: normalized.message
|
|
436
516
|
};
|
|
437
517
|
}
|
|
438
|
-
var
|
|
439
|
-
"billing_required",
|
|
440
|
-
"invalid_request",
|
|
441
|
-
"unauthorized",
|
|
442
|
-
"forbidden",
|
|
443
|
-
"not_found",
|
|
444
|
-
"conflict",
|
|
445
|
-
"rate_limited",
|
|
446
|
-
"service_unavailable",
|
|
447
|
-
"request_failed",
|
|
448
|
-
"network_error"
|
|
449
|
-
]);
|
|
450
|
-
function isPublicErrorCode(code) {
|
|
451
|
-
return Boolean(code && PUBLIC_ERROR_CODES.has(code));
|
|
452
|
-
}
|
|
518
|
+
var CONCURRENCY_LIMIT_FALLBACK_MESSAGE = "The concurrent session limit is reached. Active and starting sessions count. End a session or wait for pending starts to clear, then retry.";
|
|
453
519
|
function readMessageValue(value) {
|
|
454
520
|
if (typeof value === "string") return value.trim() || null;
|
|
455
|
-
|
|
456
|
-
|
|
521
|
+
const record = readRecord(value);
|
|
522
|
+
if (!record) return null;
|
|
457
523
|
return readMessageValue(record.message) ?? readMessageValue(record.error) ?? readMessageValue(record.detail);
|
|
458
524
|
}
|
|
459
|
-
function userSafeMessage(message) {
|
|
460
|
-
if (!message || hasInternalDetail(message)) return null;
|
|
461
|
-
return message.length > 180 ? `${message.slice(0, 177)}...` : message;
|
|
462
|
-
}
|
|
463
|
-
function isWarmingMessage(blob) {
|
|
464
|
-
return blob.includes("warming") || blob.includes("not ready") || blob.includes("starting up");
|
|
465
|
-
}
|
|
466
|
-
var MACHINE_SHAPED = /[_=<>{}\[\]|\\$`]|\w+\.\w+\.\w|\S:\d|\w\(\)|^\s*(?:at|File)\b/mu;
|
|
467
|
-
function hasInternalDetail(message) {
|
|
468
|
-
return MACHINE_SHAPED.test(message);
|
|
469
|
-
}
|
|
470
525
|
function splitCallTranscript(all, localIdentity) {
|
|
471
526
|
if (!localIdentity) return { user: [], agent: all };
|
|
472
527
|
const user = [];
|
|
@@ -2922,7 +2977,7 @@ function SessionLifecycleRoomBridge({
|
|
|
2922
2977
|
}, [connectionHistoryGrant, detailsSessionId]);
|
|
2923
2978
|
useEffect(() => {
|
|
2924
2979
|
const collector = connectionHistoryRef.current;
|
|
2925
|
-
if (!collector || typeof window === "undefined") return;
|
|
2980
|
+
if (!collector || typeof window === "undefined" || typeof window.addEventListener !== "function" || typeof window.removeEventListener !== "function") return;
|
|
2926
2981
|
const flush = () => {
|
|
2927
2982
|
void collector.flush();
|
|
2928
2983
|
};
|
package/dist/recording.d.ts
CHANGED
|
@@ -61,8 +61,8 @@ declare const recordingArtifactSchema: z.ZodDiscriminatedUnion<[z.ZodObject<{
|
|
|
61
61
|
retainedUntil: z.ZodString;
|
|
62
62
|
status: z.ZodLiteral<"failed">;
|
|
63
63
|
errorCode: z.ZodEnum<{
|
|
64
|
-
recording_failed: "recording_failed";
|
|
65
64
|
recording_unavailable: "recording_unavailable";
|
|
65
|
+
recording_failed: "recording_failed";
|
|
66
66
|
}>;
|
|
67
67
|
}, z.core.$strict>], "status">;
|
|
68
68
|
type RecordingArtifact = z.infer<typeof recordingArtifactSchema>;
|
|
@@ -118,8 +118,8 @@ declare const listRecordingsResponseSchema: z.ZodObject<{
|
|
|
118
118
|
retainedUntil: z.ZodString;
|
|
119
119
|
status: z.ZodLiteral<"failed">;
|
|
120
120
|
errorCode: z.ZodEnum<{
|
|
121
|
-
recording_failed: "recording_failed";
|
|
122
121
|
recording_unavailable: "recording_unavailable";
|
|
122
|
+
recording_failed: "recording_failed";
|
|
123
123
|
}>;
|
|
124
124
|
}, z.core.$strict>], "status">>;
|
|
125
125
|
nextCursor: z.ZodNullable<z.ZodString>;
|
package/dist/server.d.ts
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
1
|
export { RealtimeAvatar, RealtimeAvatarError, RealtimeAvatarHttpError, RealtimeAvatarOptions, StartCallOptions, clipLibraryDeclarationSchema, verifyTranscript } from './index.js';
|
|
2
|
-
export { h as Asset, g as AssetKind, A as Avatar, o as AvatarClip, c as AvatarSourceSwap, b as AvatarUpdate, p as CallConnection, C as CallMode, a as CallPolicy, q as CallQueued, r as ClipDeclaration, f as ClipLibrary, d as ClipLibraryDeclaration, s as ClipLibraryPlan, e as ClipLibraryUpdate, t as ClipSource, u as ContextMessage, n as CreditBalance, E as EndCallOptions, v as EndCallReason, k as ListRecordingsQuery, l as ListRecordingsResponse, i as ListSessionsOptions, L as LoopRedirect, m as RecordingAccessResponse, R as RecordingArtifact, w as RecordingArtifactStatus, x as RecordingMode, S as StartCallResult, T as TranscriptPayload, j as UsageSession, U as UsageSessionPage, V as VideoPolicy, y as isQueued, z as listRecordingsResponseSchema, B as recordingAccessResponseSchema, D as recordingArtifactSchema, F as recordingModeSchema } from './types-
|
|
2
|
+
export { h as Asset, g as AssetKind, A as Avatar, o as AvatarClip, c as AvatarSourceSwap, b as AvatarUpdate, p as CallConnection, C as CallMode, a as CallPolicy, q as CallQueued, r as ClipDeclaration, f as ClipLibrary, d as ClipLibraryDeclaration, s as ClipLibraryPlan, e as ClipLibraryUpdate, t as ClipSource, u as ContextMessage, n as CreditBalance, E as EndCallOptions, v as EndCallReason, k as ListRecordingsQuery, l as ListRecordingsResponse, i as ListSessionsOptions, L as LoopRedirect, m as RecordingAccessResponse, R as RecordingArtifact, w as RecordingArtifactStatus, x as RecordingMode, S as StartCallResult, T as TranscriptPayload, j as UsageSession, U as UsageSessionPage, V as VideoPolicy, y as isQueued, z as listRecordingsResponseSchema, B as recordingAccessResponseSchema, D as recordingArtifactSchema, F as recordingModeSchema } from './types-CxkszIDK.js';
|
|
3
3
|
import './connection-history.js';
|
|
4
4
|
import 'zod';
|
package/dist/server.js
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
|
-
export { RealtimeAvatar, RealtimeAvatarError, RealtimeAvatarHttpError, clipLibraryDeclarationSchema, isQueued, listRecordingsResponseSchema, recordingAccessResponseSchema, recordingArtifactSchema, recordingModeSchema, verifyTranscript } from './chunk-
|
|
1
|
+
export { RealtimeAvatar, RealtimeAvatarError, RealtimeAvatarHttpError, clipLibraryDeclarationSchema, isQueued, listRecordingsResponseSchema, recordingAccessResponseSchema, recordingArtifactSchema, recordingModeSchema, verifyTranscript } from './chunk-27XNZHSF.js';
|
|
2
2
|
import './chunk-MCIXU6XP.js';
|
package/dist/tanstack-start.d.ts
CHANGED
package/dist/tanstack-start.js
CHANGED
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { C as CallMode, a as CallPolicy } from './types-
|
|
1
|
+
import { C as CallMode, a as CallPolicy } from './types-CxkszIDK.js';
|
|
2
2
|
|
|
3
3
|
/** The three things a caller can ask the proxy to do. Gate on these, not on URLs. */
|
|
4
4
|
type ProxyOperation = "connect" | "end" | "avatars" | "credits";
|
|
@@ -110,6 +110,9 @@ interface components {
|
|
|
110
110
|
idle?: {
|
|
111
111
|
clips: string[];
|
|
112
112
|
weight?: number;
|
|
113
|
+
weights?: {
|
|
114
|
+
[key: string]: number;
|
|
115
|
+
};
|
|
113
116
|
};
|
|
114
117
|
on?: {
|
|
115
118
|
userSpeechStarted?: {
|
|
@@ -172,6 +175,19 @@ interface components {
|
|
|
172
175
|
require_ready_clip_library?: boolean;
|
|
173
176
|
};
|
|
174
177
|
LiveKitSessionGrant: {
|
|
178
|
+
/** @description Returned only for X-RTA-Release-Evidence: 1. Omitted by default for strict SDK compatibility. Missing deployment or worker evidence remains null. */
|
|
179
|
+
readonly releaseIdentity?: {
|
|
180
|
+
deploymentId: string | null;
|
|
181
|
+
workerRevision: string | null;
|
|
182
|
+
provenance: {
|
|
183
|
+
/** @constant */
|
|
184
|
+
deploymentSource: "cloudflare-worker-version";
|
|
185
|
+
workerSource: "authenticated-worker-heartbeat" | null;
|
|
186
|
+
workerId: string | null;
|
|
187
|
+
podStartedAtMs: number | null;
|
|
188
|
+
workerObservedAt: string | null;
|
|
189
|
+
};
|
|
190
|
+
};
|
|
175
191
|
/**
|
|
176
192
|
* @default ready
|
|
177
193
|
* @constant
|
|
@@ -471,6 +487,19 @@ interface components {
|
|
|
471
487
|
ListUsageSessionsResponse: {
|
|
472
488
|
data: {
|
|
473
489
|
sessionId: string;
|
|
490
|
+
/** @description Returned only for X-RTA-Release-Evidence: 1. Omitted by default for strict client compatibility. Evidence is stored against this session; missing evidence remains null. */
|
|
491
|
+
readonly releaseIdentity?: {
|
|
492
|
+
deploymentId: string | null;
|
|
493
|
+
workerRevision: string | null;
|
|
494
|
+
provenance: {
|
|
495
|
+
/** @constant */
|
|
496
|
+
deploymentSource: "cloudflare-worker-version";
|
|
497
|
+
workerSource: "authenticated-worker-heartbeat" | null;
|
|
498
|
+
workerId: string | null;
|
|
499
|
+
podStartedAtMs: number | null;
|
|
500
|
+
workerObservedAt: string | null;
|
|
501
|
+
};
|
|
502
|
+
};
|
|
474
503
|
avatarId: string | null;
|
|
475
504
|
avatarName: string | null;
|
|
476
505
|
/** @enum {string} */
|
|
@@ -667,6 +696,9 @@ interface components {
|
|
|
667
696
|
idle?: {
|
|
668
697
|
clips: string[];
|
|
669
698
|
weight?: number;
|
|
699
|
+
weights?: {
|
|
700
|
+
[key: string]: number;
|
|
701
|
+
};
|
|
670
702
|
};
|
|
671
703
|
on?: {
|
|
672
704
|
userSpeechStarted?: {
|
|
@@ -703,6 +735,9 @@ interface components {
|
|
|
703
735
|
idle?: {
|
|
704
736
|
clips: string[];
|
|
705
737
|
weight?: number;
|
|
738
|
+
weights?: {
|
|
739
|
+
[key: string]: number;
|
|
740
|
+
};
|
|
706
741
|
};
|
|
707
742
|
on?: {
|
|
708
743
|
userSpeechStarted?: {
|
|
@@ -763,6 +798,9 @@ interface components {
|
|
|
763
798
|
idle?: {
|
|
764
799
|
clips: string[];
|
|
765
800
|
weight?: number;
|
|
801
|
+
weights?: {
|
|
802
|
+
[key: string]: number;
|
|
803
|
+
};
|
|
766
804
|
};
|
|
767
805
|
on?: {
|
|
768
806
|
userSpeechStarted?: {
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "realtime-avatar",
|
|
3
|
-
"version": "0.
|
|
3
|
+
"version": "0.18.0",
|
|
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",
|
|
@@ -268,8 +268,8 @@ declare const liveKitSessionGrantSchema: z.ZodObject<{
|
|
|
268
268
|
retainedUntil: z.ZodString;
|
|
269
269
|
status: z.ZodLiteral<"failed">;
|
|
270
270
|
errorCode: z.ZodEnum<{
|
|
271
|
-
recording_failed: "recording_failed";
|
|
272
271
|
recording_unavailable: "recording_unavailable";
|
|
272
|
+
recording_failed: "recording_failed";
|
|
273
273
|
}>;
|
|
274
274
|
}, z.core.$strict>], "status">>;
|
|
275
275
|
connection_history: z.ZodOptional<z.ZodObject<{
|