@burdenoff/fe-libs 2026.1014.3 → 2026.1014.4
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/shared/assistant/avatar/live/avatarSessionClient.d.ts +25 -7
- package/dist/shared/assistant/avatar/live/avatarSessionClient.js +122 -61
- package/dist/shared/assistant/avatar/live/createLiveAvatarSeam.d.ts +7 -2
- package/dist/shared/assistant/avatar/live/createLiveAvatarSeam.js +11 -6
- package/dist/shared/assistant/avatar/live/liveAvatarController.js +201 -192
- package/dist/shared/assistant/avatar/useAvatarCopy.d.ts +1 -1
- package/dist/shared/assistant/avatar/useAvatarCopy.js +1 -0
- package/dist/shared/assistant/i18nManifest.d.ts +1 -0
- package/dist/shared/assistant/i18nManifest.js +1 -0
- package/dist/shared-assistant.js +7 -7
- package/package.json +1 -1
|
@@ -6,10 +6,15 @@ export declare const AVATAR_API_PATH = "/api/avatar/v1";
|
|
|
6
6
|
* credentials in it, or plain `http:` off a loopback host). A relative endpoint is resolved against `locationHref`.
|
|
7
7
|
*/
|
|
8
8
|
export declare function avatarApiBaseFromTtsEndpoint(ttsEndpoint: string | null | undefined, locationHref?: string): string | null;
|
|
9
|
+
/**
|
|
10
|
+
* Why nothing is offered, coarse on purpose (§3.3). The server's: no verified workspace reached it, or the avatar is not enabled for this
|
|
11
|
+
* caller. The gateway's edge check (`assistant:use` in the workspace): not permitted, or it could not be checked (`unavailable`).
|
|
12
|
+
*/
|
|
13
|
+
declare const AVAILABILITY_REASONS: readonly ["workspace_context_required", "not_enabled", "not_permitted", "unavailable"];
|
|
14
|
+
export type AvatarAvailabilityReason = (typeof AVAILABILITY_REASONS)[number];
|
|
9
15
|
export interface AvatarAvailability {
|
|
10
16
|
readonly available: boolean;
|
|
11
|
-
|
|
12
|
-
readonly reason: 'workspace_context_required' | 'not_enabled' | null;
|
|
17
|
+
readonly reason: AvatarAvailabilityReason | null;
|
|
13
18
|
/** Approved and provider-ready ids; names and pictures are the client's. */
|
|
14
19
|
readonly avatars: readonly string[];
|
|
15
20
|
/** The disclosure version the client must show and echo back on create. */
|
|
@@ -55,15 +60,18 @@ export interface AvatarSessionClientOptions {
|
|
|
55
60
|
readonly getAuthorization: () => string | null;
|
|
56
61
|
/**
|
|
57
62
|
* The workspace token as an `X-Workspace-Authorization` value (`Bearer …`), or null when none can be had. `fresh`: the gateway refused
|
|
58
|
-
* the last
|
|
63
|
+
* the last request (401), so not the token it carried: `refused`, as it was sent (absent when it carried none).
|
|
59
64
|
*/
|
|
60
65
|
readonly getWorkspaceAuthorization: (options: {
|
|
61
66
|
readonly fresh: boolean;
|
|
67
|
+
readonly refused?: string;
|
|
62
68
|
}) => Promise<string | null>;
|
|
63
69
|
readonly fetchImpl?: typeof fetch;
|
|
64
70
|
/** Waits between the contract's retries; injectable for tests. */
|
|
65
71
|
readonly sleep?: (ms: number) => Promise<void>;
|
|
66
|
-
/**
|
|
72
|
+
/** Wall-clock milliseconds, for the start budget; injectable for tests, with `sleep`. */
|
|
73
|
+
readonly now?: () => number;
|
|
74
|
+
/** How long 409 `start_in_progress` may be retried with the same key, its waits included, before giving up. */
|
|
67
75
|
readonly startInProgressBudgetMs?: number;
|
|
68
76
|
}
|
|
69
77
|
export interface AvatarSessionClient {
|
|
@@ -85,12 +93,22 @@ export declare function avatarIdempotencyKey(random?: Crypto | undefined): strin
|
|
|
85
93
|
export declare function createAvatarSessionClient(options: AvatarSessionClientOptions): AvatarSessionClient;
|
|
86
94
|
/** What the avatar UI does with a refusal: what to tell the person, and whether to stop offering the toggle for this page. */
|
|
87
95
|
export interface AvatarRefusal {
|
|
88
|
-
|
|
89
|
-
|
|
96
|
+
/** Null only with `showDisclosure`: the disclosure itself is what the person is shown. */
|
|
97
|
+
readonly problem: AvatarProblem | null;
|
|
98
|
+
/** Not offered here at all (404, 403 not allowed or not permitted, no workspace): hide the toggle until the next page load. */
|
|
90
99
|
readonly hide: boolean;
|
|
100
|
+
/** The server's disclosure version changed (`consent_required`): ask availability again, show the disclosure to confirm again. */
|
|
101
|
+
readonly showDisclosure?: true;
|
|
91
102
|
}
|
|
92
103
|
/**
|
|
93
104
|
* The person's side of every failure (§3.4): the normal voice always continues; this says what to show. 404 means "not here" (the module
|
|
94
|
-
* or the route is off), 403 "not for you", 429/503 "not now".
|
|
105
|
+
* or the route is off), 403 "not for you", 429/503 "not now". Every code the avatar module (`errors.ts`) and the gateway's proxy
|
|
106
|
+
* (`avatar-proxy.ts`) answer is named below; anything else is a problem of ours, not the person's.
|
|
95
107
|
*/
|
|
96
108
|
export declare function avatarRefusalFor(error: unknown): AvatarRefusal;
|
|
109
|
+
/**
|
|
110
|
+
* The person's side of an availability answer that offers nothing: not offered here, so the toggle goes (no verified workspace, not
|
|
111
|
+
* enabled, not permitted), or only not now when the gateway could not check the permission (`unavailable`): the toggle stays.
|
|
112
|
+
*/
|
|
113
|
+
export declare function avatarAvailabilityRefusal(reason: AvatarAvailabilityReason | null): AvatarRefusal;
|
|
114
|
+
export {};
|
|
@@ -14,7 +14,12 @@ function a(n, r) {
|
|
|
14
14
|
}
|
|
15
15
|
return i.username !== "" || i.password !== "" || i.protocol === "http:" && !t.has(i.hostname.toLowerCase()) || i.protocol !== "https:" && i.protocol !== "http:" ? null : `${i.protocol}//${i.host}${e}`;
|
|
16
16
|
}
|
|
17
|
-
var o =
|
|
17
|
+
var o = [
|
|
18
|
+
"workspace_context_required",
|
|
19
|
+
"not_enabled",
|
|
20
|
+
"not_permitted",
|
|
21
|
+
"unavailable"
|
|
22
|
+
], s = class extends Error {
|
|
18
23
|
status;
|
|
19
24
|
code;
|
|
20
25
|
retryAfterSeconds;
|
|
@@ -22,7 +27,7 @@ var o = class extends Error {
|
|
|
22
27
|
super(`avatar api ${e} ${t}`), this.status = e, this.code = t, this.retryAfterSeconds = n, this.name = "AvatarApiError";
|
|
23
28
|
}
|
|
24
29
|
};
|
|
25
|
-
function
|
|
30
|
+
function c(e = globalThis.crypto) {
|
|
26
31
|
if (e && typeof e.randomUUID == "function") return e.randomUUID();
|
|
27
32
|
let t = new Uint8Array(16);
|
|
28
33
|
if (e && typeof e.getRandomValues == "function") e.getRandomValues(t);
|
|
@@ -31,38 +36,38 @@ function s(e = globalThis.crypto) {
|
|
|
31
36
|
let n = [...t].map((e) => e.toString(16).padStart(2, "0")).join("");
|
|
32
37
|
return `${n.slice(0, 8)}-${n.slice(8, 12)}-${n.slice(12, 16)}-${n.slice(16, 20)}-${n.slice(20)}`;
|
|
33
38
|
}
|
|
34
|
-
function
|
|
39
|
+
function l(e) {
|
|
35
40
|
return typeof e == "object" && !!e && !Array.isArray(e);
|
|
36
41
|
}
|
|
37
|
-
function
|
|
42
|
+
function u(e, t) {
|
|
38
43
|
let n = e.headers.get("retry-after"), r = n === null || n.trim() === "" ? NaN : Number(n);
|
|
39
44
|
if (Number.isFinite(r) && r >= 0) return r;
|
|
40
|
-
let i =
|
|
45
|
+
let i = l(t) && l(t.error) ? Number(t.error.retryAfterSeconds) : NaN;
|
|
41
46
|
return Number.isFinite(i) && i >= 0 ? i : null;
|
|
42
47
|
}
|
|
43
|
-
async function
|
|
48
|
+
async function d(e) {
|
|
44
49
|
try {
|
|
45
50
|
return await e.json();
|
|
46
51
|
} catch {
|
|
47
52
|
return null;
|
|
48
53
|
}
|
|
49
54
|
}
|
|
50
|
-
async function
|
|
51
|
-
let t = await
|
|
52
|
-
return new
|
|
55
|
+
async function f(e) {
|
|
56
|
+
let t = await d(e), n = l(t) && l(t.error) && typeof t.error.code == "string" ? t.error.code : "http_error";
|
|
57
|
+
return new s(e.status, n, u(e, t));
|
|
53
58
|
}
|
|
54
|
-
function
|
|
55
|
-
if (!
|
|
56
|
-
let t = Array.isArray(e.avatars) ? e.avatars.flatMap((e) =>
|
|
59
|
+
function p(e) {
|
|
60
|
+
if (!l(e) || typeof e.available != "boolean") throw new s(200, "invalid_response", null);
|
|
61
|
+
let t = Array.isArray(e.avatars) ? e.avatars.flatMap((e) => l(e) && typeof e.id == "string" && r.test(e.id) ? [e.id] : []) : [], n = o.find((t) => t === e.reason) ?? null, i = typeof e.consentVersion == "string" ? e.consentVersion : "", a = typeof e.maxSessionSeconds == "number" && Number.isFinite(e.maxSessionSeconds) ? e.maxSessionSeconds : 0, c = e.available && t.length > 0 && i !== "" && a > 0;
|
|
57
62
|
return {
|
|
58
|
-
available:
|
|
59
|
-
reason:
|
|
63
|
+
available: c,
|
|
64
|
+
reason: c ? null : n ?? "not_enabled",
|
|
60
65
|
avatars: t,
|
|
61
66
|
consentVersion: i,
|
|
62
67
|
maxSessionSeconds: a
|
|
63
68
|
};
|
|
64
69
|
}
|
|
65
|
-
function
|
|
70
|
+
function m(e) {
|
|
66
71
|
try {
|
|
67
72
|
let n = new URL(e);
|
|
68
73
|
return n.protocol === "wss:" ? !0 : n.protocol === "ws:" && t.has(n.hostname.toLowerCase());
|
|
@@ -70,10 +75,10 @@ function p(e) {
|
|
|
70
75
|
return !1;
|
|
71
76
|
}
|
|
72
77
|
}
|
|
73
|
-
function
|
|
74
|
-
if (!
|
|
75
|
-
let { sessionId: t, livekitUrl: r, participantToken: i, avatarIdentity: a, connectBy:
|
|
76
|
-
if (typeof t != "string" || !n.test(t) || typeof r != "string" || !
|
|
78
|
+
function h(e) {
|
|
79
|
+
if (!l(e)) throw new s(201, "invalid_response", null);
|
|
80
|
+
let { sessionId: t, livekitUrl: r, participantToken: i, avatarIdentity: a, connectBy: o, endsAt: c } = e, u = typeof o == "string" ? Date.parse(o) : NaN, d = typeof c == "string" ? Date.parse(c) : NaN;
|
|
81
|
+
if (typeof t != "string" || !n.test(t) || typeof r != "string" || !m(r) || typeof i != "string" || i === "" || typeof a != "string" || a === "" || !Number.isFinite(u) || !Number.isFinite(d)) throw new s(201, "invalid_response", null);
|
|
77
82
|
return {
|
|
78
83
|
sessionId: t,
|
|
79
84
|
livekitUrl: r,
|
|
@@ -83,7 +88,7 @@ function m(e) {
|
|
|
83
88
|
endsAt: d
|
|
84
89
|
};
|
|
85
90
|
}
|
|
86
|
-
var
|
|
91
|
+
var g = [
|
|
87
92
|
"starting",
|
|
88
93
|
"ready",
|
|
89
94
|
"ending",
|
|
@@ -91,62 +96,77 @@ var h = [
|
|
|
91
96
|
"failed",
|
|
92
97
|
"canceled"
|
|
93
98
|
];
|
|
94
|
-
function
|
|
95
|
-
if (!
|
|
99
|
+
function _(e, t) {
|
|
100
|
+
if (!l(e) || !g.includes(e.state)) throw new s(200, "invalid_response", null);
|
|
96
101
|
return {
|
|
97
102
|
sessionId: t,
|
|
98
103
|
state: e.state,
|
|
99
104
|
endedReason: typeof e.endedReason == "string" ? e.endedReason : null
|
|
100
105
|
};
|
|
101
106
|
}
|
|
102
|
-
var
|
|
107
|
+
var v = (e) => new Promise((t) => {
|
|
103
108
|
setTimeout(t, e);
|
|
104
109
|
});
|
|
105
|
-
function
|
|
106
|
-
let t = e.fetchImpl ?? ((e, t) => fetch(e, t)), a = e.sleep ??
|
|
107
|
-
async function
|
|
110
|
+
function y(e) {
|
|
111
|
+
let t = e.fetchImpl ?? ((e, t) => fetch(e, t)), a = e.sleep ?? v, o = e.now ?? (() => Date.now()), c = e.startInProgressBudgetMs ?? 15e3, l = e.baseUrl.replace(/\/+$/, "");
|
|
112
|
+
async function u(t, n = null) {
|
|
108
113
|
let r = e.getAuthorization();
|
|
109
|
-
if (!r) throw new
|
|
114
|
+
if (!r) throw new s(401, "unauthenticated", null);
|
|
110
115
|
let i = { authorization: r };
|
|
111
116
|
if (t) {
|
|
112
|
-
let t = await e.getWorkspaceAuthorization({ fresh:
|
|
117
|
+
let t = await e.getWorkspaceAuthorization(n === null ? { fresh: !1 } : {
|
|
118
|
+
fresh: !0,
|
|
119
|
+
...n.workspace ? { refused: n.workspace } : {}
|
|
120
|
+
});
|
|
121
|
+
if (n !== null && (!t || t === n.workspace)) throw n.error;
|
|
113
122
|
t && (i["x-workspace-authorization"] = t);
|
|
114
123
|
}
|
|
115
124
|
return i;
|
|
116
125
|
}
|
|
117
|
-
async function
|
|
126
|
+
async function m(e, n) {
|
|
118
127
|
try {
|
|
119
128
|
return await t(e, {
|
|
120
129
|
...n,
|
|
121
|
-
credentials: "
|
|
122
|
-
cache: "no-store"
|
|
130
|
+
credentials: "same-origin",
|
|
131
|
+
cache: "no-store",
|
|
132
|
+
redirect: "error"
|
|
123
133
|
});
|
|
124
134
|
} catch (e) {
|
|
125
|
-
throw n.signal?.aborted ? e : new
|
|
135
|
+
throw n.signal?.aborted ? e : new s(0, "network", null);
|
|
126
136
|
}
|
|
127
137
|
}
|
|
128
138
|
return {
|
|
129
139
|
async availability(e) {
|
|
130
|
-
|
|
131
|
-
|
|
140
|
+
let t = null;
|
|
141
|
+
for (;;) {
|
|
142
|
+
let n = await u(!0, t), r = await m(`${l}/availability`, {
|
|
132
143
|
method: "GET",
|
|
133
144
|
headers: n,
|
|
134
145
|
signal: e
|
|
135
146
|
});
|
|
136
|
-
if (r.ok) return
|
|
137
|
-
|
|
147
|
+
if (r.ok) return p(await d(r));
|
|
148
|
+
let i = await f(r);
|
|
149
|
+
if (r.status === 401 && t === null) {
|
|
150
|
+
t = {
|
|
151
|
+
error: i,
|
|
152
|
+
workspace: n["x-workspace-authorization"]
|
|
153
|
+
};
|
|
154
|
+
continue;
|
|
155
|
+
}
|
|
156
|
+
throw i;
|
|
138
157
|
}
|
|
139
158
|
},
|
|
140
159
|
async create(e, t) {
|
|
141
|
-
if (!r.test(e.avatarId) || !i.test(e.idempotencyKey)) throw new
|
|
160
|
+
if (!r.test(e.avatarId) || !i.test(e.idempotencyKey)) throw new s(400, "invalid_request", null);
|
|
142
161
|
let n = JSON.stringify({
|
|
143
162
|
avatarId: e.avatarId,
|
|
144
163
|
consentVersion: e.consentVersion
|
|
145
|
-
}),
|
|
164
|
+
}), p = o(), g = null, _ = !1, v = !1, y = null;
|
|
146
165
|
for (;;) {
|
|
147
|
-
let r = await
|
|
148
|
-
if (
|
|
149
|
-
|
|
166
|
+
let r = await u(!0, g);
|
|
167
|
+
if (g = null, y !== null && o() - p > c) throw y;
|
|
168
|
+
if (r["x-workspace-authorization"] === void 0) throw new s(403, "workspace_context_required", null);
|
|
169
|
+
let i = await m(`${l}/sessions`, {
|
|
150
170
|
method: "POST",
|
|
151
171
|
headers: {
|
|
152
172
|
...r,
|
|
@@ -156,36 +176,41 @@ function v(e) {
|
|
|
156
176
|
body: n,
|
|
157
177
|
signal: t
|
|
158
178
|
});
|
|
159
|
-
if (i.status === 201) return
|
|
160
|
-
let
|
|
161
|
-
if (i.status === 401 && !
|
|
162
|
-
|
|
179
|
+
if (i.status === 201) return h(await d(i));
|
|
180
|
+
let b = await f(i);
|
|
181
|
+
if (i.status === 401 && !_) {
|
|
182
|
+
_ = !0, g = {
|
|
183
|
+
error: b,
|
|
184
|
+
workspace: r["x-workspace-authorization"]
|
|
185
|
+
};
|
|
163
186
|
continue;
|
|
164
187
|
}
|
|
165
|
-
if (i.status === 409 &&
|
|
166
|
-
|
|
188
|
+
if (i.status === 409 && b.code === "start_in_progress") {
|
|
189
|
+
let e = Math.max(250, (b.retryAfterSeconds ?? 1) * 1e3);
|
|
190
|
+
if (o() - p + e > c || (await a(e), t?.aborted)) throw b;
|
|
191
|
+
y = b;
|
|
167
192
|
continue;
|
|
168
193
|
}
|
|
169
|
-
if (i.status === 502 && !
|
|
170
|
-
|
|
194
|
+
if (i.status === 502 && !v) {
|
|
195
|
+
v = !0;
|
|
171
196
|
continue;
|
|
172
197
|
}
|
|
173
|
-
throw
|
|
198
|
+
throw b;
|
|
174
199
|
}
|
|
175
200
|
},
|
|
176
201
|
async status(e, t) {
|
|
177
|
-
if (!n.test(e)) throw new
|
|
178
|
-
let r = await
|
|
202
|
+
if (!n.test(e)) throw new s(400, "invalid_request", null);
|
|
203
|
+
let r = await u(!1), i = await m(`${l}/sessions/${e}`, {
|
|
179
204
|
method: "GET",
|
|
180
205
|
headers: r,
|
|
181
206
|
signal: t
|
|
182
207
|
});
|
|
183
|
-
if (!i.ok) throw await
|
|
184
|
-
return
|
|
208
|
+
if (!i.ok) throw await f(i);
|
|
209
|
+
return _(await d(i), e);
|
|
185
210
|
},
|
|
186
211
|
async end(e, { reason: t, keepalive: r = !1 }) {
|
|
187
|
-
if (!n.test(e)) throw new
|
|
188
|
-
let i = await
|
|
212
|
+
if (!n.test(e)) throw new s(400, "invalid_request", null);
|
|
213
|
+
let i = await u(!1), a = await m(`${l}/sessions/${e}/end`, {
|
|
189
214
|
method: "POST",
|
|
190
215
|
headers: {
|
|
191
216
|
...i,
|
|
@@ -194,13 +219,13 @@ function v(e) {
|
|
|
194
219
|
body: JSON.stringify({ reason: t }),
|
|
195
220
|
keepalive: r
|
|
196
221
|
});
|
|
197
|
-
if (!a.ok) throw await
|
|
198
|
-
return
|
|
222
|
+
if (!a.ok) throw await f(a);
|
|
223
|
+
return _(await d(a), e);
|
|
199
224
|
}
|
|
200
225
|
};
|
|
201
226
|
}
|
|
202
|
-
function
|
|
203
|
-
if (!(e instanceof
|
|
227
|
+
function b(e) {
|
|
228
|
+
if (!(e instanceof s) || e.status === 0) return {
|
|
204
229
|
problem: "connection",
|
|
205
230
|
hide: !1
|
|
206
231
|
};
|
|
@@ -210,10 +235,16 @@ function y(e) {
|
|
|
210
235
|
};
|
|
211
236
|
switch (e.code) {
|
|
212
237
|
case "avatar_not_allowed":
|
|
238
|
+
case "avatar_not_permitted":
|
|
213
239
|
case "workspace_context_required": return {
|
|
214
240
|
problem: "unavailable",
|
|
215
241
|
hide: !0
|
|
216
242
|
};
|
|
243
|
+
case "consent_required": return {
|
|
244
|
+
problem: null,
|
|
245
|
+
hide: !1,
|
|
246
|
+
showDisclosure: !0
|
|
247
|
+
};
|
|
217
248
|
case "avatar_not_approved":
|
|
218
249
|
case "avatar_not_ready": return {
|
|
219
250
|
problem: "not-ready",
|
|
@@ -228,6 +259,7 @@ function y(e) {
|
|
|
228
259
|
case "provider_concurrency_limited":
|
|
229
260
|
case "provider_no_capacity":
|
|
230
261
|
case "counters_unavailable":
|
|
262
|
+
case "permission_check_unavailable":
|
|
231
263
|
case "avatar_busy": return {
|
|
232
264
|
problem: "capacity",
|
|
233
265
|
hide: !1
|
|
@@ -237,6 +269,11 @@ function y(e) {
|
|
|
237
269
|
problem: "rate-limited",
|
|
238
270
|
hide: !1
|
|
239
271
|
};
|
|
272
|
+
case "start_budget_exceeded":
|
|
273
|
+
case "start_in_progress": return {
|
|
274
|
+
problem: "start-timeout",
|
|
275
|
+
hide: !1
|
|
276
|
+
};
|
|
240
277
|
case "avatar_paused":
|
|
241
278
|
case "budget_exhausted": return {
|
|
242
279
|
problem: "paused",
|
|
@@ -251,11 +288,35 @@ function y(e) {
|
|
|
251
288
|
problem: "provider",
|
|
252
289
|
hide: !1
|
|
253
290
|
};
|
|
291
|
+
case "authentication_required":
|
|
292
|
+
case "unauthenticated":
|
|
293
|
+
case "untrusted_caller": return {
|
|
294
|
+
problem: "unavailable",
|
|
295
|
+
hide: !1
|
|
296
|
+
};
|
|
297
|
+
case "invalid_request":
|
|
298
|
+
case "method_not_allowed":
|
|
299
|
+
case "request_too_large":
|
|
300
|
+
case "idempotency_key_spent":
|
|
301
|
+
case "idempotency_key_mismatch":
|
|
302
|
+
case "upstream_unavailable": return {
|
|
303
|
+
problem: "provider",
|
|
304
|
+
hide: !1
|
|
305
|
+
};
|
|
254
306
|
default: return {
|
|
255
307
|
problem: e.status === 401 ? "unavailable" : "provider",
|
|
256
308
|
hide: !1
|
|
257
309
|
};
|
|
258
310
|
}
|
|
259
311
|
}
|
|
312
|
+
function x(e) {
|
|
313
|
+
return e === "unavailable" ? {
|
|
314
|
+
problem: "capacity",
|
|
315
|
+
hide: !1
|
|
316
|
+
} : {
|
|
317
|
+
problem: "unavailable",
|
|
318
|
+
hide: !0
|
|
319
|
+
};
|
|
320
|
+
}
|
|
260
321
|
//#endregion
|
|
261
|
-
export { e as AVATAR_API_PATH,
|
|
322
|
+
export { e as AVATAR_API_PATH, s as AvatarApiError, a as avatarApiBaseFromTtsEndpoint, x as avatarAvailabilityRefusal, c as avatarIdempotencyKey, b as avatarRefusalFor, y as createAvatarSessionClient };
|
|
@@ -36,9 +36,14 @@ export declare function liveAvatarAuthorization(): string | null;
|
|
|
36
36
|
/**
|
|
37
37
|
* The workspace token, as the assistant's own calls mint it (`ensureWorkspaceToken`, the workspace gateway): the stored one while it is
|
|
38
38
|
* valid for the active context (workspace, organisation, project), else a new one. Null when there is no active workspace or no sign-in.
|
|
39
|
-
*
|
|
39
|
+
*
|
|
40
|
+
* ★ `fresh` (the gateway refused a request with a 401): never the token it carried (`refused`) again. A client sees a token's expiry and
|
|
41
|
+
* context, not its revocation, so it still looks valid here. The mint's issuance guard (the one `prepareWorkspaceRequest` uses) passes
|
|
42
|
+
* it over, keeps the new token to this workspace and this sign-in, and stores it for every other caller. A token another caller stored
|
|
43
|
+
* since the refusal is not the refused one, and is used as it is. Null when none can be had: no retry then.
|
|
40
44
|
*/
|
|
41
|
-
export declare function liveAvatarWorkspaceAuthorization(
|
|
45
|
+
export declare function liveAvatarWorkspaceAuthorization(options: {
|
|
42
46
|
readonly fresh: boolean;
|
|
47
|
+
readonly refused?: string;
|
|
43
48
|
}): Promise<string | null>;
|
|
44
49
|
export declare function createLiveAvatarSeam(options?: LiveAvatarSeamOptions): LiveAvatarSeamHandle;
|
|
@@ -28,15 +28,20 @@ function _() {
|
|
|
28
28
|
return n ? `Bearer ${n}` : null;
|
|
29
29
|
}
|
|
30
30
|
async function v(t) {
|
|
31
|
-
let i = n(), a = _()?.replace(/^Bearer\s+/i, "") ?? null;
|
|
32
|
-
if (!i || !
|
|
33
|
-
let
|
|
31
|
+
let i = n(), a = _(), o = a?.replace(/^Bearer\s+/i, "") ?? null;
|
|
32
|
+
if (!i || !o) return null;
|
|
33
|
+
let s = t.refused?.replace(/^Bearer\s+/i, ""), c = await e({
|
|
34
34
|
url: r("workspace"),
|
|
35
|
-
authToken:
|
|
35
|
+
authToken: o,
|
|
36
36
|
workspaceId: i,
|
|
37
|
-
currentQuery: "liveAvatarSession"
|
|
37
|
+
currentQuery: "liveAvatarSession",
|
|
38
|
+
...t.fresh ? { issuanceGuard: {
|
|
39
|
+
identityKey: "liveAvatarSession",
|
|
40
|
+
isCurrent: () => n() === i && _() === a,
|
|
41
|
+
accepts: (e, t) => e !== s && t === i
|
|
42
|
+
} } : {}
|
|
38
43
|
});
|
|
39
|
-
return
|
|
44
|
+
return c ? `Bearer ${c}` : null;
|
|
40
45
|
}
|
|
41
46
|
function y() {
|
|
42
47
|
let e = null;
|