@oxvo/ai-live-assist 7.3.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/LICENSE +21 -0
- package/README.md +17 -0
- package/cjs/AiLiveAssist.d.ts +108 -0
- package/cjs/AiLiveAssist.js +1774 -0
- package/cjs/client.d.ts +53 -0
- package/cjs/client.js +193 -0
- package/cjs/context.d.ts +58 -0
- package/cjs/context.js +979 -0
- package/cjs/control.d.ts +31 -0
- package/cjs/control.js +190 -0
- package/cjs/experienceState.d.ts +18 -0
- package/cjs/experienceState.js +82 -0
- package/cjs/index.d.ts +13 -0
- package/cjs/index.js +32 -0
- package/cjs/media.d.ts +34 -0
- package/cjs/media.js +207 -0
- package/cjs/messages.d.ts +2 -0
- package/cjs/messages.js +95 -0
- package/cjs/package.json +1 -0
- package/cjs/placement.d.ts +52 -0
- package/cjs/placement.js +293 -0
- package/cjs/presentation.d.ts +41 -0
- package/cjs/presentation.js +483 -0
- package/cjs/recordingPolicy.d.ts +2 -0
- package/cjs/recordingPolicy.js +12 -0
- package/cjs/safeSvg.d.ts +1 -0
- package/cjs/safeSvg.js +157 -0
- package/cjs/tabLock.d.ts +31 -0
- package/cjs/tabLock.js +260 -0
- package/cjs/types.d.ts +299 -0
- package/cjs/types.js +2 -0
- package/cjs/ui.d.ts +184 -0
- package/cjs/ui.js +2353 -0
- package/cjs/version.d.ts +1 -0
- package/cjs/version.js +4 -0
- package/cjs/visualContext.d.ts +21 -0
- package/cjs/visualContext.js +72 -0
- package/cjs/voicePresenceUi.d.ts +148 -0
- package/cjs/voicePresenceUi.js +2182 -0
- package/lib/AiLiveAssist.d.ts +108 -0
- package/lib/AiLiveAssist.js +1769 -0
- package/lib/client.d.ts +53 -0
- package/lib/client.js +187 -0
- package/lib/context.d.ts +58 -0
- package/lib/context.js +975 -0
- package/lib/control.d.ts +31 -0
- package/lib/control.js +186 -0
- package/lib/experienceState.d.ts +18 -0
- package/lib/experienceState.js +78 -0
- package/lib/index.d.ts +13 -0
- package/lib/index.js +26 -0
- package/lib/media.d.ts +34 -0
- package/lib/media.js +203 -0
- package/lib/messages.d.ts +2 -0
- package/lib/messages.js +92 -0
- package/lib/placement.d.ts +52 -0
- package/lib/placement.js +286 -0
- package/lib/presentation.d.ts +41 -0
- package/lib/presentation.js +478 -0
- package/lib/recordingPolicy.d.ts +2 -0
- package/lib/recordingPolicy.js +8 -0
- package/lib/safeSvg.d.ts +1 -0
- package/lib/safeSvg.js +153 -0
- package/lib/tabLock.d.ts +31 -0
- package/lib/tabLock.js +256 -0
- package/lib/types.d.ts +299 -0
- package/lib/types.js +1 -0
- package/lib/ui.d.ts +184 -0
- package/lib/ui.js +2349 -0
- package/lib/version.d.ts +1 -0
- package/lib/version.js +1 -0
- package/lib/visualContext.d.ts +21 -0
- package/lib/visualContext.js +68 -0
- package/lib/voicePresenceUi.d.ts +148 -0
- package/lib/voicePresenceUi.js +2178 -0
- package/package.json +58 -0
package/cjs/client.d.ts
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
import type { AssistMode, BootstrapConfig, ConsentScope, LaunchResult, ExperienceMode } from './types.js';
|
|
2
|
+
export declare class RuntimeClientError extends Error {
|
|
3
|
+
readonly code: string;
|
|
4
|
+
readonly retryable: boolean;
|
|
5
|
+
readonly retryAfterMs: number | null;
|
|
6
|
+
readonly status: number;
|
|
7
|
+
constructor(code: string, message: string, retryable: boolean, retryAfterMs: number | null, status: number);
|
|
8
|
+
}
|
|
9
|
+
type LaunchInput = {
|
|
10
|
+
siteKey: string;
|
|
11
|
+
configRevision: number;
|
|
12
|
+
path: string;
|
|
13
|
+
tabId: string;
|
|
14
|
+
mode: AssistMode;
|
|
15
|
+
anonymousId: string;
|
|
16
|
+
replay?: {
|
|
17
|
+
sessionId: string;
|
|
18
|
+
tabId: string;
|
|
19
|
+
};
|
|
20
|
+
disclosureChecksum: string;
|
|
21
|
+
scopes: ConsentScope[];
|
|
22
|
+
locale: string;
|
|
23
|
+
microphone: boolean;
|
|
24
|
+
reducedMotion: boolean;
|
|
25
|
+
protocolVersion: 1 | 2;
|
|
26
|
+
experienceMode: ExperienceMode;
|
|
27
|
+
fallbackIntent?: "standard_assist" | "human_handoff";
|
|
28
|
+
lowPower: boolean;
|
|
29
|
+
};
|
|
30
|
+
export declare const idempotencyKey: (prefix: string) => string;
|
|
31
|
+
export declare class RuntimeClient {
|
|
32
|
+
private readonly clientVersion;
|
|
33
|
+
readonly baseUrl: string;
|
|
34
|
+
constructor(runtimeUrl: string, clientVersion: string);
|
|
35
|
+
bootstrap(siteKey: string, path: string, anonymousId: string, signal: AbortSignal): Promise<BootstrapConfig>;
|
|
36
|
+
launch(input: LaunchInput, signal: AbortSignal): Promise<LaunchResult>;
|
|
37
|
+
resume(sessionId: string, credential: string, path: string, protocolVersion: 1 | 2, signal: AbortSignal): Promise<LaunchResult>;
|
|
38
|
+
offer(result: LaunchResult, offerSdp: string, signal: AbortSignal): Promise<{
|
|
39
|
+
answerSdp: string;
|
|
40
|
+
fencingToken: number;
|
|
41
|
+
}>;
|
|
42
|
+
end(result: LaunchResult, fencingToken: number, signal?: AbortSignal): Promise<void>;
|
|
43
|
+
pauseOrResume(result: LaunchResult, fencingToken: number, operation: 'pause' | 'resume', signal?: AbortSignal): Promise<void>;
|
|
44
|
+
feedback(result: LaunchResult, payload: {
|
|
45
|
+
rating: number | null;
|
|
46
|
+
outcome: 'resolved' | 'partially_resolved' | 'not_resolved' | 'handoff';
|
|
47
|
+
}, signal?: AbortSignal): Promise<void>;
|
|
48
|
+
private postEmpty;
|
|
49
|
+
private postJson;
|
|
50
|
+
private parseJson;
|
|
51
|
+
private throwResponse;
|
|
52
|
+
}
|
|
53
|
+
export {};
|
package/cjs/client.js
ADDED
|
@@ -0,0 +1,193 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
3
|
+
exports.RuntimeClient = exports.idempotencyKey = exports.RuntimeClientError = void 0;
|
|
4
|
+
class RuntimeClientError extends Error {
|
|
5
|
+
constructor(code, message, retryable, retryAfterMs, status) {
|
|
6
|
+
super(message);
|
|
7
|
+
this.code = code;
|
|
8
|
+
this.retryable = retryable;
|
|
9
|
+
this.retryAfterMs = retryAfterMs;
|
|
10
|
+
this.status = status;
|
|
11
|
+
this.name = 'RuntimeClientError';
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
exports.RuntimeClientError = RuntimeClientError;
|
|
15
|
+
const requestId = () => `req_${crypto.randomUUID()}`;
|
|
16
|
+
const idempotencyKey = (prefix) => `${prefix}_${crypto.randomUUID()}`;
|
|
17
|
+
exports.idempotencyKey = idempotencyKey;
|
|
18
|
+
class RuntimeClient {
|
|
19
|
+
constructor(runtimeUrl, clientVersion) {
|
|
20
|
+
this.clientVersion = clientVersion;
|
|
21
|
+
const url = new URL(runtimeUrl, window.location.href);
|
|
22
|
+
if (!['http:', 'https:'].includes(url.protocol)) {
|
|
23
|
+
throw new Error('AI Live Assist runtime URL must use HTTP or HTTPS.');
|
|
24
|
+
}
|
|
25
|
+
this.baseUrl = url.origin + url.pathname.replace(/\/$/, '');
|
|
26
|
+
}
|
|
27
|
+
async bootstrap(siteKey, path, anonymousId, signal) {
|
|
28
|
+
const url = new URL(`${this.baseUrl}/ai-live-assist/v1/public/bootstrap`);
|
|
29
|
+
url.searchParams.set('siteKey', siteKey);
|
|
30
|
+
url.searchParams.set('path', path);
|
|
31
|
+
const response = await fetch(url, {
|
|
32
|
+
method: 'GET',
|
|
33
|
+
mode: 'cors',
|
|
34
|
+
credentials: 'omit',
|
|
35
|
+
cache: 'no-store',
|
|
36
|
+
headers: {
|
|
37
|
+
Accept: 'application/json',
|
|
38
|
+
'X-Oxvo-Ai-Client-Version': this.clientVersion,
|
|
39
|
+
'X-Oxvo-Ai-Visitor-Id': anonymousId,
|
|
40
|
+
'X-Request-Id': requestId(),
|
|
41
|
+
},
|
|
42
|
+
signal,
|
|
43
|
+
});
|
|
44
|
+
return this.parseJson(response);
|
|
45
|
+
}
|
|
46
|
+
async launch(input, signal) {
|
|
47
|
+
const shared = {
|
|
48
|
+
clientVersion: this.clientVersion,
|
|
49
|
+
siteKey: input.siteKey,
|
|
50
|
+
configRevision: input.configRevision,
|
|
51
|
+
path: input.path,
|
|
52
|
+
tabId: input.tabId,
|
|
53
|
+
mode: input.mode,
|
|
54
|
+
visitor: { anonymousId: input.anonymousId },
|
|
55
|
+
...(input.replay ? { replay: input.replay } : {}),
|
|
56
|
+
consent: {
|
|
57
|
+
disclosureChecksum: input.disclosureChecksum,
|
|
58
|
+
scopes: input.scopes,
|
|
59
|
+
locale: input.locale,
|
|
60
|
+
},
|
|
61
|
+
};
|
|
62
|
+
const body = input.protocolVersion === 2
|
|
63
|
+
? {
|
|
64
|
+
schemaVersion: 2,
|
|
65
|
+
protocolVersion: 2,
|
|
66
|
+
experienceMode: input.experienceMode,
|
|
67
|
+
...(input.fallbackIntent
|
|
68
|
+
? { fallbackIntent: input.fallbackIntent }
|
|
69
|
+
: {}),
|
|
70
|
+
...shared,
|
|
71
|
+
capabilitySummary: {
|
|
72
|
+
microphone: input.microphone,
|
|
73
|
+
webrtc: typeof RTCPeerConnection !== 'undefined',
|
|
74
|
+
audioPlayback: typeof HTMLAudioElement !== 'undefined',
|
|
75
|
+
webAudio: typeof AudioContext !== 'undefined' ||
|
|
76
|
+
typeof window
|
|
77
|
+
.webkitAudioContext !== 'undefined',
|
|
78
|
+
svgOverlay: typeof SVGElement !== 'undefined',
|
|
79
|
+
visualViewport: typeof window.visualViewport !== 'undefined',
|
|
80
|
+
reducedMotion: input.reducedMotion,
|
|
81
|
+
lowPower: input.lowPower,
|
|
82
|
+
},
|
|
83
|
+
}
|
|
84
|
+
: {
|
|
85
|
+
schemaVersion: 1,
|
|
86
|
+
protocolVersion: 1,
|
|
87
|
+
...shared,
|
|
88
|
+
capabilitySummary: {
|
|
89
|
+
microphone: input.microphone,
|
|
90
|
+
webrtc: typeof RTCPeerConnection !== 'undefined',
|
|
91
|
+
reducedMotion: input.reducedMotion,
|
|
92
|
+
},
|
|
93
|
+
};
|
|
94
|
+
return this.postJson('/ai-live-assist/v1/public/launch', body, {
|
|
95
|
+
'Idempotency-Key': (0, exports.idempotencyKey)('launch'),
|
|
96
|
+
}, signal);
|
|
97
|
+
}
|
|
98
|
+
async resume(sessionId, credential, path, protocolVersion, signal) {
|
|
99
|
+
return this.postJson(`/ai-live-assist/v1/public/sessions/${encodeURIComponent(sessionId)}/resume`, {
|
|
100
|
+
schemaVersion: protocolVersion,
|
|
101
|
+
protocolVersion,
|
|
102
|
+
path,
|
|
103
|
+
reason: 'navigation',
|
|
104
|
+
}, { Authorization: `Bearer ${credential}` }, signal);
|
|
105
|
+
}
|
|
106
|
+
async offer(result, offerSdp, signal) {
|
|
107
|
+
const response = await fetch(result.realtimeOfferUrl, {
|
|
108
|
+
method: 'POST',
|
|
109
|
+
mode: 'cors',
|
|
110
|
+
credentials: 'omit',
|
|
111
|
+
cache: 'no-store',
|
|
112
|
+
headers: {
|
|
113
|
+
Accept: 'application/sdp',
|
|
114
|
+
Authorization: `Bearer ${result.launchCredential}`,
|
|
115
|
+
'Content-Type': 'application/sdp',
|
|
116
|
+
'Idempotency-Key': (0, exports.idempotencyKey)('offer'),
|
|
117
|
+
'X-Oxvo-Ai-Client-Version': this.clientVersion,
|
|
118
|
+
'X-Request-Id': requestId(),
|
|
119
|
+
},
|
|
120
|
+
body: offerSdp,
|
|
121
|
+
signal,
|
|
122
|
+
});
|
|
123
|
+
if (!response.ok)
|
|
124
|
+
await this.throwResponse(response);
|
|
125
|
+
const fencingToken = Number(response.headers.get('X-Oxvo-Fencing-Token'));
|
|
126
|
+
if (!Number.isSafeInteger(fencingToken) || fencingToken < 1) {
|
|
127
|
+
throw new RuntimeClientError('PROTOCOL_INVALID', 'The runtime returned an invalid control lease.', false, null, 502);
|
|
128
|
+
}
|
|
129
|
+
return { answerSdp: await response.text(), fencingToken };
|
|
130
|
+
}
|
|
131
|
+
async end(result, fencingToken, signal) {
|
|
132
|
+
await this.postEmpty(`/ai-live-assist/v1/public/sessions/${encodeURIComponent(result.sessionId)}/end`, result.controlCredential, fencingToken, result.protocolVersion, signal);
|
|
133
|
+
}
|
|
134
|
+
async pauseOrResume(result, fencingToken, operation, signal) {
|
|
135
|
+
await this.postEmpty(`/ai-live-assist/v1/public/sessions/${encodeURIComponent(result.sessionId)}/${operation}`, result.controlCredential, fencingToken, result.protocolVersion, signal);
|
|
136
|
+
}
|
|
137
|
+
async feedback(result, payload, signal) {
|
|
138
|
+
await this.postJson(`/ai-live-assist/v1/public/sessions/${encodeURIComponent(result.sessionId)}/feedback`, payload, {
|
|
139
|
+
Authorization: `Bearer ${result.feedbackCredential}`,
|
|
140
|
+
}, signal);
|
|
141
|
+
}
|
|
142
|
+
async postEmpty(path, credential, fencingToken, protocolVersion, signal) {
|
|
143
|
+
await this.postJson(path, {
|
|
144
|
+
schemaVersion: protocolVersion,
|
|
145
|
+
protocolVersion,
|
|
146
|
+
fencingToken,
|
|
147
|
+
}, { Authorization: `Bearer ${credential}` }, signal);
|
|
148
|
+
}
|
|
149
|
+
async postJson(path, body, extraHeaders, signal) {
|
|
150
|
+
const response = await fetch(`${this.baseUrl}${path}`, {
|
|
151
|
+
method: 'POST',
|
|
152
|
+
mode: 'cors',
|
|
153
|
+
credentials: 'omit',
|
|
154
|
+
cache: 'no-store',
|
|
155
|
+
headers: {
|
|
156
|
+
Accept: 'application/json',
|
|
157
|
+
'Content-Type': 'application/json',
|
|
158
|
+
'X-Oxvo-Ai-Client-Version': this.clientVersion,
|
|
159
|
+
'X-Request-Id': requestId(),
|
|
160
|
+
...extraHeaders,
|
|
161
|
+
},
|
|
162
|
+
body: JSON.stringify(body),
|
|
163
|
+
...(signal ? { signal } : {}),
|
|
164
|
+
});
|
|
165
|
+
if (response.status === 204)
|
|
166
|
+
return undefined;
|
|
167
|
+
return this.parseJson(response);
|
|
168
|
+
}
|
|
169
|
+
async parseJson(response) {
|
|
170
|
+
if (!response.ok)
|
|
171
|
+
await this.throwResponse(response);
|
|
172
|
+
try {
|
|
173
|
+
return (await response.json());
|
|
174
|
+
}
|
|
175
|
+
catch {
|
|
176
|
+
throw new RuntimeClientError('PROTOCOL_INVALID', 'The runtime returned an invalid response.', false, null, response.status);
|
|
177
|
+
}
|
|
178
|
+
}
|
|
179
|
+
async throwResponse(response) {
|
|
180
|
+
let error = {};
|
|
181
|
+
try {
|
|
182
|
+
const body = (await response.json());
|
|
183
|
+
error = body.error ?? {};
|
|
184
|
+
}
|
|
185
|
+
catch {
|
|
186
|
+
// Keep the public fallback generic; response bodies may come from a proxy.
|
|
187
|
+
}
|
|
188
|
+
throw new RuntimeClientError(typeof error.code === 'string' ? error.code : 'RUNTIME_UNAVAILABLE', typeof error.message === 'string'
|
|
189
|
+
? error.message
|
|
190
|
+
: 'AI Live Assist is temporarily unavailable.', error.retryable === true, typeof error.retryAfterMs === 'number' ? error.retryAfterMs : null, response.status);
|
|
191
|
+
}
|
|
192
|
+
}
|
|
193
|
+
exports.RuntimeClient = RuntimeClient;
|
package/cjs/context.d.ts
ADDED
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
import type { ActionExecutionResult, ActionGrant, PageContextSnapshot, PresentationTarget, VisualContextCapture } from './types.js';
|
|
2
|
+
type SelectorRegionRule = {
|
|
3
|
+
digest: string;
|
|
4
|
+
selector: string;
|
|
5
|
+
};
|
|
6
|
+
type ContextCallbacks = {
|
|
7
|
+
onSnapshot: (snapshot: PageContextSnapshot) => void | Promise<void>;
|
|
8
|
+
onNavigation: (pageId: string, revision: number, url: string) => void | Promise<void>;
|
|
9
|
+
onHighlight: (element: Element | null, status: 'focus' | 'success' | 'failure') => void;
|
|
10
|
+
};
|
|
11
|
+
export declare class PageContextCollector {
|
|
12
|
+
private readonly callbacks;
|
|
13
|
+
private readonly selectorRegionRules;
|
|
14
|
+
private readonly policyVersion;
|
|
15
|
+
private pageId;
|
|
16
|
+
private revision;
|
|
17
|
+
private running;
|
|
18
|
+
private mutationObserver;
|
|
19
|
+
private captureTimer;
|
|
20
|
+
private targetIds;
|
|
21
|
+
private textIds;
|
|
22
|
+
private optionIds;
|
|
23
|
+
private targets;
|
|
24
|
+
private originalPushState;
|
|
25
|
+
private originalReplaceState;
|
|
26
|
+
private executingActionId;
|
|
27
|
+
private pendingNavigation;
|
|
28
|
+
private pendingCapture;
|
|
29
|
+
private deferredNavigation;
|
|
30
|
+
private recentSelection;
|
|
31
|
+
constructor(callbacks: ContextCallbacks, selectorRegionRules?: SelectorRegionRule[], policyVersion?: number);
|
|
32
|
+
get currentRevision(): number;
|
|
33
|
+
get currentPageId(): string;
|
|
34
|
+
presentationTarget(targetId: string, revision: number): PresentationTarget | null;
|
|
35
|
+
start(): void;
|
|
36
|
+
stop(): void;
|
|
37
|
+
captureAndPublish(): Promise<PageContextSnapshot>;
|
|
38
|
+
capture(): PageContextSnapshot;
|
|
39
|
+
captureVisualContext(): VisualContextCapture | null;
|
|
40
|
+
execute(grant: ActionGrant): Promise<ActionExecutionResult>;
|
|
41
|
+
completeActionExecution(actionId: string): Promise<string | null>;
|
|
42
|
+
private click;
|
|
43
|
+
private type;
|
|
44
|
+
private select;
|
|
45
|
+
private submit;
|
|
46
|
+
private safeState;
|
|
47
|
+
private actionApplied;
|
|
48
|
+
private clippedGeometry;
|
|
49
|
+
private scheduleCapture;
|
|
50
|
+
private handleSelectionChange;
|
|
51
|
+
private handleControlStateChange;
|
|
52
|
+
private readSafeSelection;
|
|
53
|
+
private handleNavigation;
|
|
54
|
+
private installNavigationHooks;
|
|
55
|
+
private restoreNavigationHooks;
|
|
56
|
+
private reducedMotion;
|
|
57
|
+
}
|
|
58
|
+
export {};
|