@rtrvr-ai/rover 3.0.1 → 4.0.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/README.md +110 -12
- package/dist/agentDiscovery.d.ts +304 -0
- package/dist/agentDiscovery.js +1040 -0
- package/dist/embed.js +3707 -1565
- package/dist/index.d.ts +15 -2
- package/dist/ownerInstall.d.ts +150 -0
- package/dist/ownerInstall.js +340 -0
- package/dist/previewBootstrap.d.ts +9 -0
- package/dist/previewBootstrap.js +72 -2
- package/dist/rover.js +3707 -1565
- 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;
|
|
@@ -163,6 +167,7 @@ export type RoverInit = {
|
|
|
163
167
|
disabled?: boolean;
|
|
164
168
|
mp4Url?: string;
|
|
165
169
|
webmUrl?: string;
|
|
170
|
+
soundEnabled?: boolean;
|
|
166
171
|
};
|
|
167
172
|
shortcuts?: RoverShortcut[];
|
|
168
173
|
muted?: boolean;
|
|
@@ -171,6 +176,7 @@ export type RoverInit = {
|
|
|
171
176
|
resizable?: boolean;
|
|
172
177
|
};
|
|
173
178
|
showTaskControls?: boolean;
|
|
179
|
+
experience?: RoverServerExperienceConfig;
|
|
174
180
|
greeting?: {
|
|
175
181
|
text?: string;
|
|
176
182
|
delay?: number;
|
|
@@ -195,10 +201,13 @@ export type RoverInit = {
|
|
|
195
201
|
};
|
|
196
202
|
export type ClientToolDefinition = {
|
|
197
203
|
name: string;
|
|
204
|
+
title?: string;
|
|
198
205
|
description?: string;
|
|
199
206
|
parameters?: Record<string, any>;
|
|
200
207
|
required?: string[];
|
|
201
208
|
schema?: any;
|
|
209
|
+
outputSchema?: any;
|
|
210
|
+
annotations?: Record<string, any>;
|
|
202
211
|
llmCallable?: boolean;
|
|
203
212
|
};
|
|
204
213
|
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 +249,7 @@ export type RoverInstance = {
|
|
|
240
249
|
reason?: string;
|
|
241
250
|
}) => void;
|
|
242
251
|
getState: () => any;
|
|
252
|
+
getAgentCard: () => RoverAgentCard | null;
|
|
243
253
|
requestSigned: (input: string | URL, init?: RequestInit) => Promise<Response>;
|
|
244
254
|
attachLaunch: (params: RoverPreviewAttachLaunch) => Promise<RoverLaunchAttachResponse | null>;
|
|
245
255
|
registerPromptContextProvider: (provider: RoverPromptContextProvider) => () => void;
|
|
@@ -254,6 +264,7 @@ type TelemetryEventName = RoverEventName | RoverVoiceTelemetryEventName;
|
|
|
254
264
|
declare function normalizePromptContextEntry(input: string | RoverPromptContextEntry): FollowupChatEntry | null;
|
|
255
265
|
declare function buildPublicRunStartedPayload(msg: any): Record<string, unknown>;
|
|
256
266
|
declare function buildPublicRunLifecyclePayload(msg: any, completionState: ReturnType<typeof normalizeRunCompletionState>): Record<string, unknown>;
|
|
267
|
+
export declare function getAgentCard(): RoverAgentCard | null;
|
|
257
268
|
declare function normalizeRunCompletionState(msg: any): {
|
|
258
269
|
taskComplete: boolean;
|
|
259
270
|
needsUserInput: boolean;
|
|
@@ -290,6 +301,7 @@ export declare function endTask(options?: {
|
|
|
290
301
|
export declare function getState(): any;
|
|
291
302
|
export declare function registerTool(nameOrDef: string | ClientToolDefinition, handler: (args: any) => any | Promise<any>): void;
|
|
292
303
|
export declare const __roverInternalsForTests: {
|
|
304
|
+
normalizePendingRunResumeReason: typeof normalizePendingRunResumeReason;
|
|
293
305
|
sanitizeWorkerState: typeof sanitizeWorkerState;
|
|
294
306
|
cloneRuntimeStateForCheckpoint: typeof cloneRuntimeStateForCheckpoint;
|
|
295
307
|
getPersistGovernorConfig: () => {
|
|
@@ -301,5 +313,6 @@ export declare const __roverInternalsForTests: {
|
|
|
301
313
|
buildPublicRunStartedPayload: typeof buildPublicRunStartedPayload;
|
|
302
314
|
buildPublicRunLifecyclePayload: typeof buildPublicRunLifecyclePayload;
|
|
303
315
|
};
|
|
304
|
-
export { createRoverBookmarklet, createRoverConsoleSnippet, createRoverScriptTagSnippet, readRoverScriptDataAttributes, };
|
|
316
|
+
export { createRoverAgentCard, createRoverAgentCardJson, createRoverAgentDiscoveryTags, createRoverBookmarklet, createRoverConsoleSnippet, createRoverOwnerInstallBundle, createRoverSiteProfile, createRoverSiteProfileJson, createRoverServiceDescLinkHeader, createRoverScriptTagSnippet, createRoverWellKnownAgentCard, createRoverWellKnownSiteProfile, readRoverScriptDataAttributes, };
|
|
317
|
+
export type { RoverOwnerInstallBootConfig, RoverOwnerInstallBundle, RoverOwnerInstallBundleInput, RoverOwnerInstallRoverBookConfig, };
|
|
305
318
|
export declare function installGlobal(): void;
|
|
@@ -0,0 +1,150 @@
|
|
|
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
|
+
sessionScope?: 'shared_site' | 'tab';
|
|
18
|
+
openOnInit?: boolean;
|
|
19
|
+
mode?: 'safe' | 'full';
|
|
20
|
+
allowActions?: boolean;
|
|
21
|
+
deepLink?: {
|
|
22
|
+
enabled?: boolean;
|
|
23
|
+
promptParam?: string;
|
|
24
|
+
shortcutParam?: string;
|
|
25
|
+
consume?: boolean;
|
|
26
|
+
};
|
|
27
|
+
pageConfig?: RoverPageCaptureConfig | null;
|
|
28
|
+
navigation?: {
|
|
29
|
+
crossHostPolicy?: 'open_new_tab' | 'same_tab';
|
|
30
|
+
};
|
|
31
|
+
tabPolicy?: {
|
|
32
|
+
observerByDefault?: boolean;
|
|
33
|
+
actionLeaseMs?: number;
|
|
34
|
+
};
|
|
35
|
+
taskRouting?: {
|
|
36
|
+
mode?: 'auto' | 'act' | 'planner';
|
|
37
|
+
actHeuristicThreshold?: number;
|
|
38
|
+
plannerOnActError?: boolean;
|
|
39
|
+
};
|
|
40
|
+
taskContext?: {
|
|
41
|
+
resetMode?: 'auto' | 'ask' | 'off';
|
|
42
|
+
inactivityMs?: number;
|
|
43
|
+
suggestReset?: boolean;
|
|
44
|
+
semanticSimilarityThreshold?: number;
|
|
45
|
+
};
|
|
46
|
+
checkpointing?: {
|
|
47
|
+
enabled?: boolean;
|
|
48
|
+
autoVisitorId?: boolean;
|
|
49
|
+
flushIntervalMs?: number;
|
|
50
|
+
pullIntervalMs?: number;
|
|
51
|
+
minFlushIntervalMs?: number;
|
|
52
|
+
ttlHours?: number;
|
|
53
|
+
};
|
|
54
|
+
apiMode?: boolean;
|
|
55
|
+
apiToolsConfig?: {
|
|
56
|
+
mode?: 'allowlist' | 'profile' | 'none';
|
|
57
|
+
enableAdditionalTools?: string[];
|
|
58
|
+
userDefined?: string[];
|
|
59
|
+
};
|
|
60
|
+
telemetry?: {
|
|
61
|
+
enabled?: boolean;
|
|
62
|
+
sampleRate?: number;
|
|
63
|
+
flushIntervalMs?: number;
|
|
64
|
+
maxBatchSize?: number;
|
|
65
|
+
includePayloads?: boolean;
|
|
66
|
+
};
|
|
67
|
+
ui?: {
|
|
68
|
+
agent?: {
|
|
69
|
+
name?: string;
|
|
70
|
+
};
|
|
71
|
+
mascot?: {
|
|
72
|
+
disabled?: boolean;
|
|
73
|
+
mp4Url?: string;
|
|
74
|
+
webmUrl?: string;
|
|
75
|
+
soundEnabled?: boolean;
|
|
76
|
+
};
|
|
77
|
+
shortcuts?: RoverShortcut[];
|
|
78
|
+
greeting?: {
|
|
79
|
+
text?: string;
|
|
80
|
+
delay?: number;
|
|
81
|
+
duration?: number;
|
|
82
|
+
disabled?: boolean;
|
|
83
|
+
};
|
|
84
|
+
voice?: RoverVoiceConfig | JsonRecord | null;
|
|
85
|
+
experience?: JsonRecord | null;
|
|
86
|
+
muted?: boolean;
|
|
87
|
+
thoughtStyle?: 'concise_cards' | 'minimal';
|
|
88
|
+
panel?: {
|
|
89
|
+
resizable?: boolean;
|
|
90
|
+
};
|
|
91
|
+
showTaskControls?: boolean;
|
|
92
|
+
};
|
|
93
|
+
tools?: {
|
|
94
|
+
web?: {
|
|
95
|
+
enableExternalWebContext?: boolean;
|
|
96
|
+
allowDomains?: string[];
|
|
97
|
+
denyDomains?: string[];
|
|
98
|
+
scrapeMode?: 'off' | 'on_demand';
|
|
99
|
+
};
|
|
100
|
+
};
|
|
101
|
+
agentDiscovery?: RoverAgentDiscoveryRuntimeConfig;
|
|
102
|
+
siteMode?: 'agent' | 'analytics_only' | string;
|
|
103
|
+
};
|
|
104
|
+
export type RoverOwnerInstallRoverBookConfig = {
|
|
105
|
+
enabled?: boolean;
|
|
106
|
+
scriptUrl?: string;
|
|
107
|
+
config?: JsonRecord | null;
|
|
108
|
+
attachPollIntervalMs?: number;
|
|
109
|
+
attachMaxAttempts?: number;
|
|
110
|
+
};
|
|
111
|
+
export type RoverOwnerInstallBundleInput = {
|
|
112
|
+
bootConfig: RoverOwnerInstallBootConfig;
|
|
113
|
+
discovery?: RoverAgentDiscoveryConfig | null;
|
|
114
|
+
embedScriptUrl?: string;
|
|
115
|
+
roverBook?: RoverOwnerInstallRoverBookConfig | null;
|
|
116
|
+
emitLlmsTxt?: boolean;
|
|
117
|
+
llmsTxt?: string;
|
|
118
|
+
};
|
|
119
|
+
export type RoverOwnerInstallBundleMetadata = {
|
|
120
|
+
discoveryEnabled: boolean;
|
|
121
|
+
llmsPublished: boolean;
|
|
122
|
+
embedScriptUrl: string;
|
|
123
|
+
roverBookEnabled: boolean;
|
|
124
|
+
roverBookScriptUrl?: string;
|
|
125
|
+
publishedAgentCardUrl?: string;
|
|
126
|
+
publishedRoverSiteUrl?: string;
|
|
127
|
+
publishedLlmsUrl?: string;
|
|
128
|
+
serviceDescLinkTag?: string;
|
|
129
|
+
serviceDocLinkTag?: string;
|
|
130
|
+
markerJson?: string;
|
|
131
|
+
markerScript?: string;
|
|
132
|
+
inlineAgentCardScript?: string;
|
|
133
|
+
roverSiteJson?: string;
|
|
134
|
+
inlineRoverSiteScript?: string;
|
|
135
|
+
pageManifestJson?: string;
|
|
136
|
+
pageManifestScript?: string;
|
|
137
|
+
};
|
|
138
|
+
export type RoverOwnerInstallBundle = {
|
|
139
|
+
bodyInstallHtml: string;
|
|
140
|
+
headDiscoveryHtml: string;
|
|
141
|
+
agentCard?: RoverAgentCard;
|
|
142
|
+
agentCardJson?: string;
|
|
143
|
+
roverSite?: RoverSiteProfile;
|
|
144
|
+
roverSiteJson?: string;
|
|
145
|
+
serviceDescLinkHeader?: string;
|
|
146
|
+
llmsTxt?: string;
|
|
147
|
+
metadata: RoverOwnerInstallBundleMetadata;
|
|
148
|
+
};
|
|
149
|
+
export declare function createRoverOwnerInstallBundle(input: RoverOwnerInstallBundleInput): RoverOwnerInstallBundle;
|
|
150
|
+
export {};
|
|
@@ -0,0 +1,340 @@
|
|
|
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 buildBootScript(bootConfig) {
|
|
207
|
+
const lines = [
|
|
208
|
+
'<script>',
|
|
209
|
+
...buildQueueStubLines().map(line => ` ${line}`),
|
|
210
|
+
` rover('boot', ${indentJson(bootConfig)});`,
|
|
211
|
+
'</script>',
|
|
212
|
+
];
|
|
213
|
+
return lines.join('\n');
|
|
214
|
+
}
|
|
215
|
+
function buildRoverBookAttachScript(config, options) {
|
|
216
|
+
const pollIntervalMs = normalizeAttachPollIntervalMs(options?.pollIntervalMs);
|
|
217
|
+
const maxAttempts = normalizeAttachMaxAttempts(options?.maxAttempts);
|
|
218
|
+
return [
|
|
219
|
+
'<script>',
|
|
220
|
+
' (function(){',
|
|
221
|
+
` var roverBookConfig = ${indentJson(config)};`,
|
|
222
|
+
' function attachRoverBook(){',
|
|
223
|
+
' if (window.__ROVERBOOK_INSTANCE__) return true;',
|
|
224
|
+
' var roverApi = window.rover;',
|
|
225
|
+
' var roverBook = window.RoverBook;',
|
|
226
|
+
" if (!roverApi || typeof roverApi.on !== 'function' || typeof roverApi.requestSigned !== 'function') return false;",
|
|
227
|
+
" if (!roverBook || typeof roverBook.enableRoverBook !== 'function') return false;",
|
|
228
|
+
' window.__ROVERBOOK_INSTANCE__ = roverBook.enableRoverBook(roverApi, roverBookConfig);',
|
|
229
|
+
' return true;',
|
|
230
|
+
' }',
|
|
231
|
+
' if (attachRoverBook()) return;',
|
|
232
|
+
' var attempts = 0;',
|
|
233
|
+
' var timer = setInterval(function(){',
|
|
234
|
+
' attempts += 1;',
|
|
235
|
+
` if (attachRoverBook() || attempts >= ${maxAttempts}) clearInterval(timer);`,
|
|
236
|
+
` }, ${pollIntervalMs});`,
|
|
237
|
+
' })();',
|
|
238
|
+
'</script>',
|
|
239
|
+
].join('\n');
|
|
240
|
+
}
|
|
241
|
+
export function createRoverOwnerInstallBundle(input) {
|
|
242
|
+
const bootConfig = input.bootConfig;
|
|
243
|
+
const discoveryConfig = discoveryEnabled(input.discovery) ? input.discovery : null;
|
|
244
|
+
const publishedAgentCardUrl = discoveryConfig ? text(discoveryConfig.agentCardUrl) || DEFAULT_AGENT_CARD_PATH : '';
|
|
245
|
+
const publishedRoverSiteUrl = discoveryConfig ? text(discoveryConfig.roverSiteUrl) || DEFAULT_ROVER_SITE_PATH : '';
|
|
246
|
+
const publishLlmsTxt = llmsEnabled(input, discoveryConfig);
|
|
247
|
+
const publishedLlmsUrl = discoveryConfig ? text(discoveryConfig.llmsUrl) : '';
|
|
248
|
+
const embedScriptUrl = text(input.embedScriptUrl) || DEFAULT_EMBED_SCRIPT_URL;
|
|
249
|
+
const roverBookEnabled = input.roverBook?.enabled !== false && hasObjectEntries(input.roverBook?.config);
|
|
250
|
+
const roverBookScriptUrl = roverBookEnabled
|
|
251
|
+
? (text(input.roverBook?.scriptUrl) || DEFAULT_ROVERBOOK_SCRIPT_URL)
|
|
252
|
+
: '';
|
|
253
|
+
const agentCard = discoveryConfig ? createRoverAgentCard(discoveryConfig) : undefined;
|
|
254
|
+
const agentCardJson = discoveryConfig ? createRoverAgentCardJson(discoveryConfig) : undefined;
|
|
255
|
+
const roverSite = discoveryConfig ? createRoverSiteProfile(discoveryConfig) : undefined;
|
|
256
|
+
const roverSiteJson = discoveryConfig ? createRoverSiteProfileJson(discoveryConfig) : undefined;
|
|
257
|
+
const pageManifestJson = discoveryConfig
|
|
258
|
+
? JSON.stringify(agentCard?.extensions?.rover.currentPage || null, null, 2)
|
|
259
|
+
: undefined;
|
|
260
|
+
const marker = agentCard && publishedAgentCardUrl
|
|
261
|
+
? buildOwnerMarker(agentCard, publishedAgentCardUrl)
|
|
262
|
+
: undefined;
|
|
263
|
+
const markerJson = marker ? escapeScriptJson(JSON.stringify(marker)) : undefined;
|
|
264
|
+
const escapedAgentCardJson = agentCardJson ? escapeScriptJson(agentCardJson) : undefined;
|
|
265
|
+
const escapedRoverSiteJson = roverSiteJson ? escapeScriptJson(roverSiteJson) : undefined;
|
|
266
|
+
const escapedPageManifestJson = pageManifestJson ? escapeScriptJson(pageManifestJson) : undefined;
|
|
267
|
+
const serviceDescLinkTag = discoveryConfig && publishedAgentCardUrl
|
|
268
|
+
? `<link rel="service-desc" href="${escapeHtmlAttr(publishedAgentCardUrl)}" type="application/json" />`
|
|
269
|
+
: undefined;
|
|
270
|
+
const serviceDocLinkTag = discoveryConfig && publishedLlmsUrl
|
|
271
|
+
? `<link rel="service-doc" href="${escapeHtmlAttr(publishedLlmsUrl)}" type="text/markdown" />`
|
|
272
|
+
: undefined;
|
|
273
|
+
const bodyLines = [];
|
|
274
|
+
if (markerJson) {
|
|
275
|
+
bodyLines.push(`<script type="application/agent+json" data-rover-agent-discovery="marker">${markerJson}</script>`);
|
|
276
|
+
}
|
|
277
|
+
if (escapedRoverSiteJson) {
|
|
278
|
+
bodyLines.push(`<script type="application/rover-site+json" data-rover-agent-discovery="rover-site">${escapedRoverSiteJson}</script>`);
|
|
279
|
+
}
|
|
280
|
+
if (escapedPageManifestJson) {
|
|
281
|
+
bodyLines.push(`<script type="application/rover-page+json" data-rover-agent-discovery="page">${escapedPageManifestJson}</script>`);
|
|
282
|
+
}
|
|
283
|
+
if (escapedAgentCardJson) {
|
|
284
|
+
bodyLines.push(`<script type="application/agent-card+json" data-rover-agent-discovery="agent-card">${escapedAgentCardJson}</script>`);
|
|
285
|
+
}
|
|
286
|
+
bodyLines.push(buildBootScript(bootConfig));
|
|
287
|
+
bodyLines.push(`<script src="${escapeHtmlAttr(embedScriptUrl)}" async></script>`);
|
|
288
|
+
if (roverBookEnabled && roverBookScriptUrl) {
|
|
289
|
+
bodyLines.push(`<script src="${escapeHtmlAttr(roverBookScriptUrl)}" async></script>`);
|
|
290
|
+
bodyLines.push(buildRoverBookAttachScript(input.roverBook?.config || {}, {
|
|
291
|
+
pollIntervalMs: input.roverBook?.attachPollIntervalMs,
|
|
292
|
+
maxAttempts: input.roverBook?.attachMaxAttempts,
|
|
293
|
+
}));
|
|
294
|
+
}
|
|
295
|
+
const llmsTxt = publishLlmsTxt && agentCard
|
|
296
|
+
? (text(input.llmsTxt) ? input.llmsTxt : buildDefaultLlmsTxt(agentCard, { agentCardUrl: publishedAgentCardUrl || DEFAULT_AGENT_CARD_PATH }))
|
|
297
|
+
: undefined;
|
|
298
|
+
return decorateBundleWithExperience({
|
|
299
|
+
bodyInstallHtml: bodyLines.join('\n'),
|
|
300
|
+
headDiscoveryHtml: [serviceDescLinkTag, serviceDocLinkTag].filter(Boolean).join('\n'),
|
|
301
|
+
agentCard,
|
|
302
|
+
agentCardJson,
|
|
303
|
+
roverSite,
|
|
304
|
+
roverSiteJson,
|
|
305
|
+
serviceDescLinkHeader: discoveryConfig
|
|
306
|
+
? createRoverServiceDescLinkHeader({
|
|
307
|
+
agentCardUrl: publishedAgentCardUrl || DEFAULT_AGENT_CARD_PATH,
|
|
308
|
+
...(publishedLlmsUrl ? { llmsUrl: publishedLlmsUrl } : {}),
|
|
309
|
+
})
|
|
310
|
+
: undefined,
|
|
311
|
+
llmsTxt,
|
|
312
|
+
metadata: {
|
|
313
|
+
discoveryEnabled: !!discoveryConfig,
|
|
314
|
+
llmsPublished: !!serviceDocLinkTag,
|
|
315
|
+
embedScriptUrl,
|
|
316
|
+
roverBookEnabled,
|
|
317
|
+
roverBookScriptUrl: roverBookScriptUrl || undefined,
|
|
318
|
+
publishedAgentCardUrl: publishedAgentCardUrl || undefined,
|
|
319
|
+
publishedRoverSiteUrl: publishedRoverSiteUrl || undefined,
|
|
320
|
+
publishedLlmsUrl: publishedLlmsUrl || undefined,
|
|
321
|
+
serviceDescLinkTag,
|
|
322
|
+
serviceDocLinkTag,
|
|
323
|
+
markerJson,
|
|
324
|
+
markerScript: markerJson
|
|
325
|
+
? `<script type="application/agent+json" data-rover-agent-discovery="marker">${markerJson}</script>`
|
|
326
|
+
: undefined,
|
|
327
|
+
inlineAgentCardScript: escapedAgentCardJson
|
|
328
|
+
? `<script type="application/agent-card+json" data-rover-agent-discovery="agent-card">${escapedAgentCardJson}</script>`
|
|
329
|
+
: undefined,
|
|
330
|
+
roverSiteJson,
|
|
331
|
+
inlineRoverSiteScript: escapedRoverSiteJson
|
|
332
|
+
? `<script type="application/rover-site+json" data-rover-agent-discovery="rover-site">${escapedRoverSiteJson}</script>`
|
|
333
|
+
: undefined,
|
|
334
|
+
pageManifestJson,
|
|
335
|
+
pageManifestScript: escapedPageManifestJson
|
|
336
|
+
? `<script type="application/rover-page+json" data-rover-agent-discovery="page">${escapedPageManifestJson}</script>`
|
|
337
|
+
: undefined,
|
|
338
|
+
},
|
|
339
|
+
}, input.bootConfig);
|
|
340
|
+
}
|
|
@@ -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'>;
|