@rtrvr-ai/rover 3.0.1 → 4.0.1
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/README.md +130 -22
- package/dist/agentDiscovery.d.ts +304 -0
- package/dist/agentDiscovery.js +1040 -0
- package/dist/embed.js +3733 -1564
- package/dist/index.d.ts +16 -2
- package/dist/ownerInstall.d.ts +152 -0
- package/dist/ownerInstall.js +357 -0
- package/dist/previewBootstrap.d.ts +9 -0
- package/dist/previewBootstrap.js +72 -2
- package/dist/rover.js +3733 -1564
- package/dist/worker/rover-worker.js +11 -11
- package/package.json +13 -1
package/dist/index.d.ts
CHANGED
|
@@ -1,9 +1,12 @@
|
|
|
1
1
|
import type { RoverPageCaptureConfig } from '@rover/shared/lib/types/index.js';
|
|
2
2
|
import { type RoverAskUserQuestion, type RoverShortcut, type RoverVoiceConfig } from '@rover/ui';
|
|
3
|
+
import { normalizePendingRunResumeReason } from './resumeReasons.js';
|
|
3
4
|
import { createRoverBookmarklet, createRoverConsoleSnippet, createRoverScriptTagSnippet, readRoverScriptDataAttributes, type RoverPreviewAttachLaunch } from './previewBootstrap.js';
|
|
5
|
+
import { createRoverOwnerInstallBundle, type RoverOwnerInstallBootConfig, type RoverOwnerInstallBundle, type RoverOwnerInstallBundleInput, type RoverOwnerInstallRoverBookConfig } from './ownerInstall.js';
|
|
6
|
+
import { createRoverAgentCard, createRoverAgentCardJson, createRoverAgentDiscoveryTags, createRoverSiteProfile, createRoverSiteProfileJson, createRoverServiceDescLinkHeader, createRoverWellKnownAgentCard, createRoverWellKnownSiteProfile, type RoverAgentCard, type RoverAgentDiscoveryRuntimeConfig } from './agentDiscovery.js';
|
|
4
7
|
import { type RoverCloudCheckpointState } from './cloudCheckpoint.js';
|
|
5
8
|
import type { PersistedRuntimeState, PersistedWorkerState } from './runtimeTypes.js';
|
|
6
|
-
import { type RoverLaunchAttachResponse } from './serverRuntime.js';
|
|
9
|
+
import { type RoverLaunchAttachResponse, type RoverServerExperienceConfig } from './serverRuntime.js';
|
|
7
10
|
import { type FollowupChatEntry } from './followupChatHeuristics.js';
|
|
8
11
|
export type RoverWebToolsConfig = {
|
|
9
12
|
enableExternalWebContext?: boolean;
|
|
@@ -75,6 +78,7 @@ export type RoverInit = {
|
|
|
75
78
|
activation?: 'on_demand';
|
|
76
79
|
idleCloseMs?: number;
|
|
77
80
|
};
|
|
81
|
+
agentDiscovery?: RoverAgentDiscoveryRuntimeConfig;
|
|
78
82
|
stability?: {
|
|
79
83
|
maxPersistBytes?: number;
|
|
80
84
|
maxSnapshotBytes?: number;
|
|
@@ -161,8 +165,10 @@ export type RoverInit = {
|
|
|
161
165
|
};
|
|
162
166
|
mascot?: {
|
|
163
167
|
disabled?: boolean;
|
|
168
|
+
imageUrl?: string;
|
|
164
169
|
mp4Url?: string;
|
|
165
170
|
webmUrl?: string;
|
|
171
|
+
soundEnabled?: boolean;
|
|
166
172
|
};
|
|
167
173
|
shortcuts?: RoverShortcut[];
|
|
168
174
|
muted?: boolean;
|
|
@@ -171,6 +177,7 @@ export type RoverInit = {
|
|
|
171
177
|
resizable?: boolean;
|
|
172
178
|
};
|
|
173
179
|
showTaskControls?: boolean;
|
|
180
|
+
experience?: RoverServerExperienceConfig;
|
|
174
181
|
greeting?: {
|
|
175
182
|
text?: string;
|
|
176
183
|
delay?: number;
|
|
@@ -195,10 +202,13 @@ export type RoverInit = {
|
|
|
195
202
|
};
|
|
196
203
|
export type ClientToolDefinition = {
|
|
197
204
|
name: string;
|
|
205
|
+
title?: string;
|
|
198
206
|
description?: string;
|
|
199
207
|
parameters?: Record<string, any>;
|
|
200
208
|
required?: string[];
|
|
201
209
|
schema?: any;
|
|
210
|
+
outputSchema?: any;
|
|
211
|
+
annotations?: Record<string, any>;
|
|
202
212
|
llmCallable?: boolean;
|
|
203
213
|
};
|
|
204
214
|
export type RoverEventName = 'ready' | 'updated' | 'status' | 'run_started' | 'run_state_transition' | 'run_completed' | 'tool_start' | 'tool_result' | 'error' | 'auth_required' | 'navigation_guardrail' | 'mode_change' | 'task_started' | 'task_ended' | 'task_suggested_reset' | 'context_restored' | 'checkpoint_state' | 'checkpoint_error' | 'tab_event_conflict_retry' | 'tab_event_conflict_exhausted' | 'checkpoint_token_missing' | 'open' | 'close';
|
|
@@ -240,6 +250,7 @@ export type RoverInstance = {
|
|
|
240
250
|
reason?: string;
|
|
241
251
|
}) => void;
|
|
242
252
|
getState: () => any;
|
|
253
|
+
getAgentCard: () => RoverAgentCard | null;
|
|
243
254
|
requestSigned: (input: string | URL, init?: RequestInit) => Promise<Response>;
|
|
244
255
|
attachLaunch: (params: RoverPreviewAttachLaunch) => Promise<RoverLaunchAttachResponse | null>;
|
|
245
256
|
registerPromptContextProvider: (provider: RoverPromptContextProvider) => () => void;
|
|
@@ -254,6 +265,7 @@ type TelemetryEventName = RoverEventName | RoverVoiceTelemetryEventName;
|
|
|
254
265
|
declare function normalizePromptContextEntry(input: string | RoverPromptContextEntry): FollowupChatEntry | null;
|
|
255
266
|
declare function buildPublicRunStartedPayload(msg: any): Record<string, unknown>;
|
|
256
267
|
declare function buildPublicRunLifecyclePayload(msg: any, completionState: ReturnType<typeof normalizeRunCompletionState>): Record<string, unknown>;
|
|
268
|
+
export declare function getAgentCard(): RoverAgentCard | null;
|
|
257
269
|
declare function normalizeRunCompletionState(msg: any): {
|
|
258
270
|
taskComplete: boolean;
|
|
259
271
|
needsUserInput: boolean;
|
|
@@ -290,6 +302,7 @@ export declare function endTask(options?: {
|
|
|
290
302
|
export declare function getState(): any;
|
|
291
303
|
export declare function registerTool(nameOrDef: string | ClientToolDefinition, handler: (args: any) => any | Promise<any>): void;
|
|
292
304
|
export declare const __roverInternalsForTests: {
|
|
305
|
+
normalizePendingRunResumeReason: typeof normalizePendingRunResumeReason;
|
|
293
306
|
sanitizeWorkerState: typeof sanitizeWorkerState;
|
|
294
307
|
cloneRuntimeStateForCheckpoint: typeof cloneRuntimeStateForCheckpoint;
|
|
295
308
|
getPersistGovernorConfig: () => {
|
|
@@ -301,5 +314,6 @@ export declare const __roverInternalsForTests: {
|
|
|
301
314
|
buildPublicRunStartedPayload: typeof buildPublicRunStartedPayload;
|
|
302
315
|
buildPublicRunLifecyclePayload: typeof buildPublicRunLifecyclePayload;
|
|
303
316
|
};
|
|
304
|
-
export { createRoverBookmarklet, createRoverConsoleSnippet, createRoverScriptTagSnippet, readRoverScriptDataAttributes, };
|
|
317
|
+
export { createRoverAgentCard, createRoverAgentCardJson, createRoverAgentDiscoveryTags, createRoverBookmarklet, createRoverConsoleSnippet, createRoverOwnerInstallBundle, createRoverSiteProfile, createRoverSiteProfileJson, createRoverServiceDescLinkHeader, createRoverScriptTagSnippet, createRoverWellKnownAgentCard, createRoverWellKnownSiteProfile, readRoverScriptDataAttributes, };
|
|
318
|
+
export type { RoverOwnerInstallBootConfig, RoverOwnerInstallBundle, RoverOwnerInstallBundleInput, RoverOwnerInstallRoverBookConfig, };
|
|
305
319
|
export declare function installGlobal(): void;
|
|
@@ -0,0 +1,152 @@
|
|
|
1
|
+
import type { RoverPageCaptureConfig } from '@rover/shared/lib/types/index.js';
|
|
2
|
+
import type { RoverShortcut, RoverVoiceConfig } from '@rover/ui';
|
|
3
|
+
import { type RoverAgentCard, type RoverAgentDiscoveryConfig, type RoverAgentDiscoveryRuntimeConfig, type RoverSiteProfile } from './agentDiscovery.js';
|
|
4
|
+
type JsonRecord = Record<string, unknown>;
|
|
5
|
+
export type RoverOwnerInstallBootConfig = {
|
|
6
|
+
siteId: string;
|
|
7
|
+
publicKey?: string;
|
|
8
|
+
sessionToken?: string;
|
|
9
|
+
sessionId?: string;
|
|
10
|
+
siteKeyId?: string;
|
|
11
|
+
apiBase?: string;
|
|
12
|
+
visitorId?: string;
|
|
13
|
+
workerUrl?: string;
|
|
14
|
+
allowedDomains?: string[];
|
|
15
|
+
domainScopeMode?: 'host_only' | 'registrable_domain';
|
|
16
|
+
externalNavigationPolicy?: 'open_new_tab_notice' | 'block' | 'allow';
|
|
17
|
+
cloudSandboxEnabled?: boolean;
|
|
18
|
+
sessionScope?: 'shared_site' | 'tab';
|
|
19
|
+
openOnInit?: boolean;
|
|
20
|
+
mode?: 'safe' | 'full';
|
|
21
|
+
allowActions?: boolean;
|
|
22
|
+
deepLink?: {
|
|
23
|
+
enabled?: boolean;
|
|
24
|
+
promptParam?: string;
|
|
25
|
+
shortcutParam?: string;
|
|
26
|
+
consume?: boolean;
|
|
27
|
+
};
|
|
28
|
+
pageConfig?: RoverPageCaptureConfig | null;
|
|
29
|
+
navigation?: {
|
|
30
|
+
crossHostPolicy?: 'open_new_tab' | 'same_tab';
|
|
31
|
+
};
|
|
32
|
+
tabPolicy?: {
|
|
33
|
+
observerByDefault?: boolean;
|
|
34
|
+
actionLeaseMs?: number;
|
|
35
|
+
};
|
|
36
|
+
taskRouting?: {
|
|
37
|
+
mode?: 'auto' | 'act' | 'planner';
|
|
38
|
+
actHeuristicThreshold?: number;
|
|
39
|
+
plannerOnActError?: boolean;
|
|
40
|
+
};
|
|
41
|
+
taskContext?: {
|
|
42
|
+
resetMode?: 'auto' | 'ask' | 'off';
|
|
43
|
+
inactivityMs?: number;
|
|
44
|
+
suggestReset?: boolean;
|
|
45
|
+
semanticSimilarityThreshold?: number;
|
|
46
|
+
};
|
|
47
|
+
checkpointing?: {
|
|
48
|
+
enabled?: boolean;
|
|
49
|
+
autoVisitorId?: boolean;
|
|
50
|
+
flushIntervalMs?: number;
|
|
51
|
+
pullIntervalMs?: number;
|
|
52
|
+
minFlushIntervalMs?: number;
|
|
53
|
+
ttlHours?: number;
|
|
54
|
+
};
|
|
55
|
+
apiMode?: boolean;
|
|
56
|
+
apiToolsConfig?: {
|
|
57
|
+
mode?: 'allowlist' | 'profile' | 'none';
|
|
58
|
+
enableAdditionalTools?: string[];
|
|
59
|
+
userDefined?: string[];
|
|
60
|
+
};
|
|
61
|
+
telemetry?: {
|
|
62
|
+
enabled?: boolean;
|
|
63
|
+
sampleRate?: number;
|
|
64
|
+
flushIntervalMs?: number;
|
|
65
|
+
maxBatchSize?: number;
|
|
66
|
+
includePayloads?: boolean;
|
|
67
|
+
};
|
|
68
|
+
ui?: {
|
|
69
|
+
agent?: {
|
|
70
|
+
name?: string;
|
|
71
|
+
};
|
|
72
|
+
mascot?: {
|
|
73
|
+
disabled?: boolean;
|
|
74
|
+
imageUrl?: string;
|
|
75
|
+
mp4Url?: string;
|
|
76
|
+
webmUrl?: string;
|
|
77
|
+
soundEnabled?: boolean;
|
|
78
|
+
};
|
|
79
|
+
shortcuts?: RoverShortcut[];
|
|
80
|
+
greeting?: {
|
|
81
|
+
text?: string;
|
|
82
|
+
delay?: number;
|
|
83
|
+
duration?: number;
|
|
84
|
+
disabled?: boolean;
|
|
85
|
+
};
|
|
86
|
+
voice?: RoverVoiceConfig | JsonRecord | null;
|
|
87
|
+
experience?: JsonRecord | null;
|
|
88
|
+
muted?: boolean;
|
|
89
|
+
thoughtStyle?: 'concise_cards' | 'minimal';
|
|
90
|
+
panel?: {
|
|
91
|
+
resizable?: boolean;
|
|
92
|
+
};
|
|
93
|
+
showTaskControls?: boolean;
|
|
94
|
+
};
|
|
95
|
+
tools?: {
|
|
96
|
+
web?: {
|
|
97
|
+
enableExternalWebContext?: boolean;
|
|
98
|
+
allowDomains?: string[];
|
|
99
|
+
denyDomains?: string[];
|
|
100
|
+
scrapeMode?: 'off' | 'on_demand';
|
|
101
|
+
};
|
|
102
|
+
};
|
|
103
|
+
agentDiscovery?: RoverAgentDiscoveryRuntimeConfig;
|
|
104
|
+
siteMode?: 'agent' | 'analytics_only' | string;
|
|
105
|
+
};
|
|
106
|
+
export type RoverOwnerInstallRoverBookConfig = {
|
|
107
|
+
enabled?: boolean;
|
|
108
|
+
scriptUrl?: string;
|
|
109
|
+
config?: JsonRecord | null;
|
|
110
|
+
attachPollIntervalMs?: number;
|
|
111
|
+
attachMaxAttempts?: number;
|
|
112
|
+
};
|
|
113
|
+
export type RoverOwnerInstallBundleInput = {
|
|
114
|
+
bootConfig: RoverOwnerInstallBootConfig;
|
|
115
|
+
discovery?: RoverAgentDiscoveryConfig | null;
|
|
116
|
+
embedScriptUrl?: string;
|
|
117
|
+
roverBook?: RoverOwnerInstallRoverBookConfig | null;
|
|
118
|
+
emitLlmsTxt?: boolean;
|
|
119
|
+
llmsTxt?: string;
|
|
120
|
+
};
|
|
121
|
+
export type RoverOwnerInstallBundleMetadata = {
|
|
122
|
+
discoveryEnabled: boolean;
|
|
123
|
+
llmsPublished: boolean;
|
|
124
|
+
embedScriptUrl: string;
|
|
125
|
+
roverBookEnabled: boolean;
|
|
126
|
+
roverBookScriptUrl?: string;
|
|
127
|
+
publishedAgentCardUrl?: string;
|
|
128
|
+
publishedRoverSiteUrl?: string;
|
|
129
|
+
publishedLlmsUrl?: string;
|
|
130
|
+
serviceDescLinkTag?: string;
|
|
131
|
+
serviceDocLinkTag?: string;
|
|
132
|
+
markerJson?: string;
|
|
133
|
+
markerScript?: string;
|
|
134
|
+
inlineAgentCardScript?: string;
|
|
135
|
+
roverSiteJson?: string;
|
|
136
|
+
inlineRoverSiteScript?: string;
|
|
137
|
+
pageManifestJson?: string;
|
|
138
|
+
pageManifestScript?: string;
|
|
139
|
+
};
|
|
140
|
+
export type RoverOwnerInstallBundle = {
|
|
141
|
+
bodyInstallHtml: string;
|
|
142
|
+
headDiscoveryHtml: string;
|
|
143
|
+
agentCard?: RoverAgentCard;
|
|
144
|
+
agentCardJson?: string;
|
|
145
|
+
roverSite?: RoverSiteProfile;
|
|
146
|
+
roverSiteJson?: string;
|
|
147
|
+
serviceDescLinkHeader?: string;
|
|
148
|
+
llmsTxt?: string;
|
|
149
|
+
metadata: RoverOwnerInstallBundleMetadata;
|
|
150
|
+
};
|
|
151
|
+
export declare function createRoverOwnerInstallBundle(input: RoverOwnerInstallBundleInput): RoverOwnerInstallBundle;
|
|
152
|
+
export {};
|
|
@@ -0,0 +1,357 @@
|
|
|
1
|
+
import { DEFAULT_AGENT_CARD_PATH, DEFAULT_ROVER_SITE_PATH, createRoverAgentCard, createRoverAgentCardJson, createRoverSiteProfile, createRoverSiteProfileJson, createRoverServiceDescLinkHeader, } from './agentDiscovery.js';
|
|
2
|
+
const DEFAULT_EMBED_SCRIPT_URL = 'https://rover.rtrvr.ai/embed.js';
|
|
3
|
+
const DEFAULT_ROVERBOOK_SCRIPT_URL = 'https://rover.rtrvr.ai/roverbook.js';
|
|
4
|
+
function text(value) {
|
|
5
|
+
return String(value || '').trim();
|
|
6
|
+
}
|
|
7
|
+
function escapeHtmlAttr(value) {
|
|
8
|
+
return String(value || '')
|
|
9
|
+
.replace(/&/g, '&')
|
|
10
|
+
.replace(/"/g, '"')
|
|
11
|
+
.replace(/</g, '<')
|
|
12
|
+
.replace(/>/g, '>');
|
|
13
|
+
}
|
|
14
|
+
function escapeScriptJson(value) {
|
|
15
|
+
return String(value || '')
|
|
16
|
+
.replace(/</g, '\\u003c')
|
|
17
|
+
.replace(/>/g, '\\u003e')
|
|
18
|
+
.replace(/&/g, '\\u0026');
|
|
19
|
+
}
|
|
20
|
+
function replaceInlineDiscoveryScript(html, marker, script) {
|
|
21
|
+
if (!script)
|
|
22
|
+
return html;
|
|
23
|
+
const pattern = new RegExp(`<script[^>]+data-rover-agent-discovery="${marker}"[^>]*>[\\s\\S]*?<\\/script>`);
|
|
24
|
+
if (pattern.test(html)) {
|
|
25
|
+
return html.replace(pattern, script);
|
|
26
|
+
}
|
|
27
|
+
return [html, script].filter(Boolean).join('\n');
|
|
28
|
+
}
|
|
29
|
+
function decorateBundleWithExperience(bundle, bootConfig) {
|
|
30
|
+
const experience = isObject(bootConfig.ui?.experience) ? bootConfig.ui?.experience : null;
|
|
31
|
+
if (!experience)
|
|
32
|
+
return bundle;
|
|
33
|
+
const presence = isObject(experience.presence) ? experience.presence : {};
|
|
34
|
+
const inputs = isObject(experience.inputs) ? experience.inputs : {};
|
|
35
|
+
const shell = isObject(experience.shell) ? experience.shell : {};
|
|
36
|
+
const stream = isObject(experience.stream) ? experience.stream : {};
|
|
37
|
+
const ctaText = text(presence.ctaText) || `Do it with ${text(bootConfig.ui?.agent?.name) || 'Rover'}`;
|
|
38
|
+
const assistantName = text(presence.assistantName) || text(bootConfig.ui?.agent?.name) || 'Rover';
|
|
39
|
+
const agentCard = bundle.agentCard ? JSON.parse(JSON.stringify(bundle.agentCard)) : undefined;
|
|
40
|
+
if (agentCard?.extensions?.rover) {
|
|
41
|
+
agentCard.extensions.rover.discoverySurface = {
|
|
42
|
+
...(agentCard.extensions.rover.discoverySurface || {}),
|
|
43
|
+
mode: 'beacon',
|
|
44
|
+
hostSurface: 'floating-corner',
|
|
45
|
+
actionReveal: 'click',
|
|
46
|
+
beaconLabel: ctaText,
|
|
47
|
+
};
|
|
48
|
+
agentCard.extensions.rover.presence = {
|
|
49
|
+
assistantName,
|
|
50
|
+
ctaText,
|
|
51
|
+
draggable: presence.draggable !== false,
|
|
52
|
+
};
|
|
53
|
+
agentCard.extensions.rover.experience = experience;
|
|
54
|
+
agentCard.extensions.rover.inputs = {
|
|
55
|
+
filesEnabled: inputs.files !== false,
|
|
56
|
+
acceptedMimeGroups: Array.isArray(inputs.acceptedMimeGroups) ? inputs.acceptedMimeGroups : ['images', 'pdfs', 'office', 'text'],
|
|
57
|
+
allowMultipleFiles: inputs.allowMultipleFiles !== false,
|
|
58
|
+
};
|
|
59
|
+
}
|
|
60
|
+
const roverSite = bundle.roverSite ? JSON.parse(JSON.stringify(bundle.roverSite)) : undefined;
|
|
61
|
+
if (roverSite) {
|
|
62
|
+
roverSite.display = {
|
|
63
|
+
...(roverSite.display || {}),
|
|
64
|
+
mode: 'beacon',
|
|
65
|
+
hostSurface: 'floating-corner',
|
|
66
|
+
actionReveal: 'click',
|
|
67
|
+
beaconLabel: ctaText,
|
|
68
|
+
presence: 'draggable_pill',
|
|
69
|
+
openMode: text(shell.openMode) || 'center_stage',
|
|
70
|
+
mobileMode: text(shell.mobileMode) || 'fullscreen_sheet',
|
|
71
|
+
streamMode: text(stream.layout) || 'single_column',
|
|
72
|
+
focusView: 'focus_stream',
|
|
73
|
+
};
|
|
74
|
+
roverSite.experience = experience;
|
|
75
|
+
roverSite.inputs = {
|
|
76
|
+
...(roverSite.inputs || {}),
|
|
77
|
+
filesEnabled: inputs.files !== false,
|
|
78
|
+
acceptedMimeGroups: Array.isArray(inputs.acceptedMimeGroups) ? inputs.acceptedMimeGroups : ['images', 'pdfs', 'office', 'text'],
|
|
79
|
+
allowMultipleFiles: inputs.allowMultipleFiles !== false,
|
|
80
|
+
};
|
|
81
|
+
}
|
|
82
|
+
const agentCardJson = agentCard ? JSON.stringify(agentCard, null, 2) : bundle.agentCardJson;
|
|
83
|
+
const roverSiteJson = roverSite ? JSON.stringify(roverSite, null, 2) : bundle.roverSiteJson;
|
|
84
|
+
const inlineAgentCardScript = agentCardJson
|
|
85
|
+
? `<script type="application/agent-card+json" data-rover-agent-discovery="agent-card">${escapeScriptJson(agentCardJson)}</script>`
|
|
86
|
+
: bundle.metadata.inlineAgentCardScript;
|
|
87
|
+
const inlineRoverSiteScript = roverSiteJson
|
|
88
|
+
? `<script type="application/rover-site+json" data-rover-agent-discovery="rover-site">${escapeScriptJson(roverSiteJson)}</script>`
|
|
89
|
+
: bundle.metadata.inlineRoverSiteScript;
|
|
90
|
+
return {
|
|
91
|
+
...bundle,
|
|
92
|
+
agentCard,
|
|
93
|
+
agentCardJson,
|
|
94
|
+
roverSite,
|
|
95
|
+
roverSiteJson,
|
|
96
|
+
bodyInstallHtml: replaceInlineDiscoveryScript(replaceInlineDiscoveryScript(bundle.bodyInstallHtml, 'agent-card', inlineAgentCardScript), 'rover-site', inlineRoverSiteScript),
|
|
97
|
+
metadata: {
|
|
98
|
+
...bundle.metadata,
|
|
99
|
+
roverSiteJson,
|
|
100
|
+
inlineAgentCardScript,
|
|
101
|
+
inlineRoverSiteScript,
|
|
102
|
+
},
|
|
103
|
+
};
|
|
104
|
+
}
|
|
105
|
+
function indentJson(value) {
|
|
106
|
+
return JSON.stringify(value, null, 2)
|
|
107
|
+
.split('\n')
|
|
108
|
+
.map(line => ` ${line}`)
|
|
109
|
+
.join('\n');
|
|
110
|
+
}
|
|
111
|
+
function isObject(value) {
|
|
112
|
+
return !!value && typeof value === 'object' && !Array.isArray(value);
|
|
113
|
+
}
|
|
114
|
+
function hasObjectEntries(value) {
|
|
115
|
+
return isObject(value) && Object.keys(value).length > 0;
|
|
116
|
+
}
|
|
117
|
+
function normalizeAttachPollIntervalMs(value) {
|
|
118
|
+
const parsed = Number(value);
|
|
119
|
+
if (!Number.isFinite(parsed) || parsed < 10)
|
|
120
|
+
return 50;
|
|
121
|
+
return Math.round(parsed);
|
|
122
|
+
}
|
|
123
|
+
function normalizeAttachMaxAttempts(value) {
|
|
124
|
+
const parsed = Number(value);
|
|
125
|
+
if (!Number.isFinite(parsed) || parsed < 1)
|
|
126
|
+
return 300;
|
|
127
|
+
return Math.round(parsed);
|
|
128
|
+
}
|
|
129
|
+
function discoveryEnabled(config) {
|
|
130
|
+
return !!config && config.enabled !== false && config.aiAccess?.enabled !== false;
|
|
131
|
+
}
|
|
132
|
+
function llmsEnabled(input, config) {
|
|
133
|
+
if (!discoveryEnabled(config))
|
|
134
|
+
return false;
|
|
135
|
+
return input.emitLlmsTxt === true || !!text(config.llmsUrl);
|
|
136
|
+
}
|
|
137
|
+
function buildOwnerMarker(card, publishedAgentCardUrl) {
|
|
138
|
+
return {
|
|
139
|
+
task: card.extensions?.rover.taskEndpoint,
|
|
140
|
+
card: publishedAgentCardUrl,
|
|
141
|
+
roverSite: card.extensions?.rover.roverSiteUrl,
|
|
142
|
+
site: card.extensions?.rover.siteUrl,
|
|
143
|
+
workflow: card.extensions?.rover.workflowEndpoint,
|
|
144
|
+
page: card.extensions?.rover.currentPage?.pageId,
|
|
145
|
+
preferExecution: card.extensions?.rover.preferredExecution,
|
|
146
|
+
display: card.extensions?.rover.discoverySurface
|
|
147
|
+
? {
|
|
148
|
+
mode: card.extensions.rover.discoverySurface.mode,
|
|
149
|
+
hostSurface: card.extensions.rover.discoverySurface.hostSurface,
|
|
150
|
+
actionReveal: card.extensions.rover.discoverySurface.actionReveal,
|
|
151
|
+
beaconLabel: card.extensions.rover.discoverySurface.beaconLabel,
|
|
152
|
+
}
|
|
153
|
+
: undefined,
|
|
154
|
+
skills: card.skills.slice(0, 24).map(skill => ({
|
|
155
|
+
id: skill.id,
|
|
156
|
+
name: skill.name,
|
|
157
|
+
})),
|
|
158
|
+
capabilities: (card.extensions?.rover.capabilitiesGraph || []).slice(0, 24).map(capability => ({
|
|
159
|
+
capabilityId: capability.capabilityId,
|
|
160
|
+
label: capability.label,
|
|
161
|
+
})),
|
|
162
|
+
};
|
|
163
|
+
}
|
|
164
|
+
function buildDefaultLlmsTxt(card, options) {
|
|
165
|
+
const lines = [
|
|
166
|
+
`# ${card.name}`,
|
|
167
|
+
'',
|
|
168
|
+
card.description,
|
|
169
|
+
'',
|
|
170
|
+
'Prefer Rover shortcuts, explicit site tools, and public task flows over raw DOM automation when they match the requested outcome.',
|
|
171
|
+
`Primary task endpoint: ${text(card.extensions?.rover.taskEndpoint || card.url)}`,
|
|
172
|
+
`Workflow endpoint: ${text(card.extensions?.rover.workflowEndpoint)}`,
|
|
173
|
+
`Capability card: ${options.agentCardUrl}`,
|
|
174
|
+
];
|
|
175
|
+
const skills = card.skills
|
|
176
|
+
.map(skill => ({
|
|
177
|
+
id: text(skill.id),
|
|
178
|
+
name: text(skill.name),
|
|
179
|
+
description: text(skill.description),
|
|
180
|
+
interface: text(skill.preferredInterface || skill.rover?.source || 'task'),
|
|
181
|
+
}))
|
|
182
|
+
.filter(skill => skill.id && skill.name);
|
|
183
|
+
if (skills.length > 0) {
|
|
184
|
+
lines.push('', 'Published skills:');
|
|
185
|
+
for (const skill of skills) {
|
|
186
|
+
const description = skill.description ? ` - ${skill.description}` : '';
|
|
187
|
+
lines.push(`- ${skill.id}: ${skill.name} [${skill.interface}]${description}`);
|
|
188
|
+
}
|
|
189
|
+
}
|
|
190
|
+
const shortcuts = (card.extensions?.rover.shortcuts || [])
|
|
191
|
+
.map(shortcut => `${text(shortcut.id)}: ${text(shortcut.label)}`)
|
|
192
|
+
.filter(Boolean);
|
|
193
|
+
if (shortcuts.length > 0) {
|
|
194
|
+
lines.push('', 'Shortcut IDs:');
|
|
195
|
+
for (const shortcut of shortcuts) {
|
|
196
|
+
lines.push(`- ${shortcut}`);
|
|
197
|
+
}
|
|
198
|
+
}
|
|
199
|
+
return lines.join('\n');
|
|
200
|
+
}
|
|
201
|
+
function buildQueueStubLines() {
|
|
202
|
+
return [
|
|
203
|
+
'(function(){ var r = window.rover = window.rover || function(){ (r.q = r.q || []).push(arguments); }; r.l = +new Date(); })();',
|
|
204
|
+
];
|
|
205
|
+
}
|
|
206
|
+
function materializeCloudSandboxBootConfig(bootConfig) {
|
|
207
|
+
if (bootConfig.cloudSandboxEnabled !== true) {
|
|
208
|
+
return bootConfig;
|
|
209
|
+
}
|
|
210
|
+
return {
|
|
211
|
+
...bootConfig,
|
|
212
|
+
tools: {
|
|
213
|
+
...(bootConfig.tools || {}),
|
|
214
|
+
web: {
|
|
215
|
+
...(bootConfig.tools?.web || {}),
|
|
216
|
+
enableExternalWebContext: true,
|
|
217
|
+
scrapeMode: 'on_demand',
|
|
218
|
+
},
|
|
219
|
+
},
|
|
220
|
+
};
|
|
221
|
+
}
|
|
222
|
+
function buildBootScript(bootConfig) {
|
|
223
|
+
const normalizedBootConfig = materializeCloudSandboxBootConfig(bootConfig);
|
|
224
|
+
const lines = [
|
|
225
|
+
'<script>',
|
|
226
|
+
...buildQueueStubLines().map(line => ` ${line}`),
|
|
227
|
+
` rover('boot', ${indentJson(normalizedBootConfig)});`,
|
|
228
|
+
'</script>',
|
|
229
|
+
];
|
|
230
|
+
return lines.join('\n');
|
|
231
|
+
}
|
|
232
|
+
function buildRoverBookAttachScript(config, options) {
|
|
233
|
+
const pollIntervalMs = normalizeAttachPollIntervalMs(options?.pollIntervalMs);
|
|
234
|
+
const maxAttempts = normalizeAttachMaxAttempts(options?.maxAttempts);
|
|
235
|
+
return [
|
|
236
|
+
'<script>',
|
|
237
|
+
' (function(){',
|
|
238
|
+
` var roverBookConfig = ${indentJson(config)};`,
|
|
239
|
+
' function attachRoverBook(){',
|
|
240
|
+
' if (window.__ROVERBOOK_INSTANCE__) return true;',
|
|
241
|
+
' var roverApi = window.rover;',
|
|
242
|
+
' var roverBook = window.RoverBook;',
|
|
243
|
+
" if (!roverApi || typeof roverApi.on !== 'function' || typeof roverApi.requestSigned !== 'function') return false;",
|
|
244
|
+
" if (!roverBook || typeof roverBook.enableRoverBook !== 'function') return false;",
|
|
245
|
+
' window.__ROVERBOOK_INSTANCE__ = roverBook.enableRoverBook(roverApi, roverBookConfig);',
|
|
246
|
+
' return true;',
|
|
247
|
+
' }',
|
|
248
|
+
' if (attachRoverBook()) return;',
|
|
249
|
+
' var attempts = 0;',
|
|
250
|
+
' var timer = setInterval(function(){',
|
|
251
|
+
' attempts += 1;',
|
|
252
|
+
` if (attachRoverBook() || attempts >= ${maxAttempts}) clearInterval(timer);`,
|
|
253
|
+
` }, ${pollIntervalMs});`,
|
|
254
|
+
' })();',
|
|
255
|
+
'</script>',
|
|
256
|
+
].join('\n');
|
|
257
|
+
}
|
|
258
|
+
export function createRoverOwnerInstallBundle(input) {
|
|
259
|
+
const bootConfig = materializeCloudSandboxBootConfig(input.bootConfig);
|
|
260
|
+
const discoveryConfig = discoveryEnabled(input.discovery) ? input.discovery : null;
|
|
261
|
+
const publishedAgentCardUrl = discoveryConfig ? text(discoveryConfig.agentCardUrl) || DEFAULT_AGENT_CARD_PATH : '';
|
|
262
|
+
const publishedRoverSiteUrl = discoveryConfig ? text(discoveryConfig.roverSiteUrl) || DEFAULT_ROVER_SITE_PATH : '';
|
|
263
|
+
const publishLlmsTxt = llmsEnabled(input, discoveryConfig);
|
|
264
|
+
const publishedLlmsUrl = discoveryConfig ? text(discoveryConfig.llmsUrl) : '';
|
|
265
|
+
const embedScriptUrl = text(input.embedScriptUrl) || DEFAULT_EMBED_SCRIPT_URL;
|
|
266
|
+
const roverBookEnabled = input.roverBook?.enabled !== false && hasObjectEntries(input.roverBook?.config);
|
|
267
|
+
const roverBookScriptUrl = roverBookEnabled
|
|
268
|
+
? (text(input.roverBook?.scriptUrl) || DEFAULT_ROVERBOOK_SCRIPT_URL)
|
|
269
|
+
: '';
|
|
270
|
+
const agentCard = discoveryConfig ? createRoverAgentCard(discoveryConfig) : undefined;
|
|
271
|
+
const agentCardJson = discoveryConfig ? createRoverAgentCardJson(discoveryConfig) : undefined;
|
|
272
|
+
const roverSite = discoveryConfig ? createRoverSiteProfile(discoveryConfig) : undefined;
|
|
273
|
+
const roverSiteJson = discoveryConfig ? createRoverSiteProfileJson(discoveryConfig) : undefined;
|
|
274
|
+
const pageManifestJson = discoveryConfig
|
|
275
|
+
? JSON.stringify(agentCard?.extensions?.rover.currentPage || null, null, 2)
|
|
276
|
+
: undefined;
|
|
277
|
+
const marker = agentCard && publishedAgentCardUrl
|
|
278
|
+
? buildOwnerMarker(agentCard, publishedAgentCardUrl)
|
|
279
|
+
: undefined;
|
|
280
|
+
const markerJson = marker ? escapeScriptJson(JSON.stringify(marker)) : undefined;
|
|
281
|
+
const escapedAgentCardJson = agentCardJson ? escapeScriptJson(agentCardJson) : undefined;
|
|
282
|
+
const escapedRoverSiteJson = roverSiteJson ? escapeScriptJson(roverSiteJson) : undefined;
|
|
283
|
+
const escapedPageManifestJson = pageManifestJson ? escapeScriptJson(pageManifestJson) : undefined;
|
|
284
|
+
const serviceDescLinkTag = discoveryConfig && publishedAgentCardUrl
|
|
285
|
+
? `<link rel="service-desc" href="${escapeHtmlAttr(publishedAgentCardUrl)}" type="application/json" />`
|
|
286
|
+
: undefined;
|
|
287
|
+
const serviceDocLinkTag = discoveryConfig && publishedLlmsUrl
|
|
288
|
+
? `<link rel="service-doc" href="${escapeHtmlAttr(publishedLlmsUrl)}" type="text/markdown" />`
|
|
289
|
+
: undefined;
|
|
290
|
+
const bodyLines = [];
|
|
291
|
+
if (markerJson) {
|
|
292
|
+
bodyLines.push(`<script type="application/agent+json" data-rover-agent-discovery="marker">${markerJson}</script>`);
|
|
293
|
+
}
|
|
294
|
+
if (escapedRoverSiteJson) {
|
|
295
|
+
bodyLines.push(`<script type="application/rover-site+json" data-rover-agent-discovery="rover-site">${escapedRoverSiteJson}</script>`);
|
|
296
|
+
}
|
|
297
|
+
if (escapedPageManifestJson) {
|
|
298
|
+
bodyLines.push(`<script type="application/rover-page+json" data-rover-agent-discovery="page">${escapedPageManifestJson}</script>`);
|
|
299
|
+
}
|
|
300
|
+
if (escapedAgentCardJson) {
|
|
301
|
+
bodyLines.push(`<script type="application/agent-card+json" data-rover-agent-discovery="agent-card">${escapedAgentCardJson}</script>`);
|
|
302
|
+
}
|
|
303
|
+
bodyLines.push(buildBootScript(bootConfig));
|
|
304
|
+
bodyLines.push(`<script src="${escapeHtmlAttr(embedScriptUrl)}" async></script>`);
|
|
305
|
+
if (roverBookEnabled && roverBookScriptUrl) {
|
|
306
|
+
bodyLines.push(`<script src="${escapeHtmlAttr(roverBookScriptUrl)}" async></script>`);
|
|
307
|
+
bodyLines.push(buildRoverBookAttachScript(input.roverBook?.config || {}, {
|
|
308
|
+
pollIntervalMs: input.roverBook?.attachPollIntervalMs,
|
|
309
|
+
maxAttempts: input.roverBook?.attachMaxAttempts,
|
|
310
|
+
}));
|
|
311
|
+
}
|
|
312
|
+
const llmsTxt = publishLlmsTxt && agentCard
|
|
313
|
+
? (text(input.llmsTxt) ? input.llmsTxt : buildDefaultLlmsTxt(agentCard, { agentCardUrl: publishedAgentCardUrl || DEFAULT_AGENT_CARD_PATH }))
|
|
314
|
+
: undefined;
|
|
315
|
+
return decorateBundleWithExperience({
|
|
316
|
+
bodyInstallHtml: bodyLines.join('\n'),
|
|
317
|
+
headDiscoveryHtml: [serviceDescLinkTag, serviceDocLinkTag].filter(Boolean).join('\n'),
|
|
318
|
+
agentCard,
|
|
319
|
+
agentCardJson,
|
|
320
|
+
roverSite,
|
|
321
|
+
roverSiteJson,
|
|
322
|
+
serviceDescLinkHeader: discoveryConfig
|
|
323
|
+
? createRoverServiceDescLinkHeader({
|
|
324
|
+
agentCardUrl: publishedAgentCardUrl || DEFAULT_AGENT_CARD_PATH,
|
|
325
|
+
...(publishedLlmsUrl ? { llmsUrl: publishedLlmsUrl } : {}),
|
|
326
|
+
})
|
|
327
|
+
: undefined,
|
|
328
|
+
llmsTxt,
|
|
329
|
+
metadata: {
|
|
330
|
+
discoveryEnabled: !!discoveryConfig,
|
|
331
|
+
llmsPublished: !!serviceDocLinkTag,
|
|
332
|
+
embedScriptUrl,
|
|
333
|
+
roverBookEnabled,
|
|
334
|
+
roverBookScriptUrl: roverBookScriptUrl || undefined,
|
|
335
|
+
publishedAgentCardUrl: publishedAgentCardUrl || undefined,
|
|
336
|
+
publishedRoverSiteUrl: publishedRoverSiteUrl || undefined,
|
|
337
|
+
publishedLlmsUrl: publishedLlmsUrl || undefined,
|
|
338
|
+
serviceDescLinkTag,
|
|
339
|
+
serviceDocLinkTag,
|
|
340
|
+
markerJson,
|
|
341
|
+
markerScript: markerJson
|
|
342
|
+
? `<script type="application/agent+json" data-rover-agent-discovery="marker">${markerJson}</script>`
|
|
343
|
+
: undefined,
|
|
344
|
+
inlineAgentCardScript: escapedAgentCardJson
|
|
345
|
+
? `<script type="application/agent-card+json" data-rover-agent-discovery="agent-card">${escapedAgentCardJson}</script>`
|
|
346
|
+
: undefined,
|
|
347
|
+
roverSiteJson,
|
|
348
|
+
inlineRoverSiteScript: escapedRoverSiteJson
|
|
349
|
+
? `<script type="application/rover-site+json" data-rover-agent-discovery="rover-site">${escapedRoverSiteJson}</script>`
|
|
350
|
+
: undefined,
|
|
351
|
+
pageManifestJson,
|
|
352
|
+
pageManifestScript: escapedPageManifestJson
|
|
353
|
+
? `<script type="application/rover-page+json" data-rover-agent-discovery="page">${escapedPageManifestJson}</script>`
|
|
354
|
+
: undefined,
|
|
355
|
+
},
|
|
356
|
+
}, input.bootConfig);
|
|
357
|
+
}
|
|
@@ -2,6 +2,14 @@ export type RoverPreviewAttachLaunch = {
|
|
|
2
2
|
requestId: string;
|
|
3
3
|
attachToken: string;
|
|
4
4
|
};
|
|
5
|
+
export type RoverPreviewBootstrapVoiceConfig = {
|
|
6
|
+
enabled?: boolean;
|
|
7
|
+
language?: string;
|
|
8
|
+
autoStopMs?: number;
|
|
9
|
+
};
|
|
10
|
+
export type RoverPreviewBootstrapUiConfig = {
|
|
11
|
+
voice?: RoverPreviewBootstrapVoiceConfig;
|
|
12
|
+
};
|
|
5
13
|
export type RoverPreviewBootstrapConfig = {
|
|
6
14
|
scriptUrl?: string;
|
|
7
15
|
siteId: string;
|
|
@@ -18,6 +26,7 @@ export type RoverPreviewBootstrapConfig = {
|
|
|
18
26
|
openOnInit?: boolean;
|
|
19
27
|
mode?: 'safe' | 'full';
|
|
20
28
|
allowActions?: boolean;
|
|
29
|
+
ui?: RoverPreviewBootstrapUiConfig;
|
|
21
30
|
attachLaunch?: RoverPreviewAttachLaunch;
|
|
22
31
|
};
|
|
23
32
|
export type RoverScriptAttributeSource = Pick<HTMLScriptElement, 'getAttribute'>;
|